From de3469e088c8b10d41a9a5515512c12587768c6a Mon Sep 17 00:00:00 2001 From: Dan Nicholson Date: Sat, 5 Jun 2010 12:32:36 -0700 Subject: glib: Bundle snapshot of glib-2.0 Add a snapshot of the current stable version of glib, glib-2.32.0. Since we only need the glib library, a lot of files are removed. See the README and update-glib.sh files in glib-patches for details. --- glib/.gitignore | 43 + glib/AUTHORS | 40 + glib/COPYING | 482 + glib/Makefile.am | 135 + glib/Makefile.decl | 97 + glib/NEWS | 6191 +++++++ glib/README.in | 288 + glib/acglib.m4 | 131 + glib/acinclude.m4 | 452 + glib/configure.ac | 3571 ++++ glib/glib-gettextize.in | 188 + glib/glib.doap | 47 + glib/glib/.gitignore | 12 + glib/glib/Makefile.am | 526 + glib/glib/abicheck.sh | 13 + glib/glib/deprecated/gallocator.c | 104 + glib/glib/deprecated/gallocator.h | 90 + glib/glib/deprecated/gcache.c | 345 + glib/glib/deprecated/gcache.h | 73 + glib/glib/deprecated/gcompletion.c | 492 + glib/glib/deprecated/gcompletion.h | 85 + glib/glib/deprecated/gmain.h | 138 + glib/glib/deprecated/grel.c | 677 + glib/glib/deprecated/grel.h | 107 + glib/glib/deprecated/gthread-deprecated.c | 1592 ++ glib/glib/deprecated/gthread.h | 285 + glib/glib/docs.c | 2334 +++ glib/glib/galloca.h | 110 + glib/glib/garray.c | 1777 ++ glib/glib/garray.h | 187 + glib/glib/gasyncqueue.c | 802 + glib/glib/gasyncqueue.h | 91 + glib/glib/gasyncqueueprivate.h | 31 + glib/glib/gatomic.c | 871 + glib/glib/gatomic.h | 216 + glib/glib/gbacktrace.c | 374 + glib/glib/gbacktrace.h | 64 + glib/glib/gbase64.c | 445 + glib/glib/gbase64.h | 57 + glib/glib/gbitlock.c | 536 + glib/glib/gbitlock.h | 72 + glib/glib/gbookmarkfile.c | 3713 ++++ glib/glib/gbookmarkfile.h | 215 + glib/glib/gbsearcharray.h | 303 + glib/glib/gbytes.c | 482 + glib/glib/gbytes.h | 74 + glib/glib/gcharset.c | 592 + glib/glib/gcharset.h | 40 + glib/glib/gchecksum.c | 1461 ++ glib/glib/gchecksum.h | 86 + glib/glib/gconstructor.h | 91 + glib/glib/gconvert.c | 2250 +++ glib/glib/gconvert.h | 164 + glib/glib/gdataset.c | 1362 ++ glib/glib/gdataset.h | 122 + glib/glib/gdatasetprivate.h | 44 + glib/glib/gdate.c | 2551 +++ glib/glib/gdate.h | 264 + glib/glib/gdatetime.c | 2754 +++ glib/glib/gdatetime.h | 217 + glib/glib/gdir.c | 320 + glib/glib/gdir.h | 54 + glib/glib/gen-iswide-table.py | 58 + glib/glib/gen-script-table.pl | 119 + glib/glib/gen-unicode-tables.pl | 1339 ++ glib/glib/genviron.c | 697 + glib/glib/genviron.h | 65 + glib/glib/gerror.c | 727 + glib/glib/gerror.h | 107 + glib/glib/gfileutils.c | 2654 +++ glib/glib/gfileutils.h | 176 + glib/glib/ggettext.c | 614 + glib/glib/ggettext.h | 59 + glib/glib/ghash.c | 1903 ++ glib/glib/ghash.h | 146 + glib/glib/ghmac.c | 400 + glib/glib/ghmac.h | 71 + glib/glib/ghook.c | 1054 ++ glib/glib/ghook.h | 181 + glib/glib/ghostutils.c | 800 + glib/glib/ghostutils.h | 40 + glib/glib/gi18n-lib.h | 38 + glib/glib/gi18n.h | 34 + glib/glib/giochannel.c | 2587 +++ glib/glib/giochannel.h | 374 + glib/glib/giounix.c | 658 + glib/glib/giowin32.c | 2241 +++ glib/glib/gkeyfile.c | 4383 +++++ glib/glib/gkeyfile.h | 268 + glib/glib/glib-init.c | 269 + glib/glib/glib-init.h | 40 + glib/glib/glib-mirroring-tab/Makefile | 11 + glib/glib/glib-mirroring-tab/gen-mirroring-tab.c | 232 + glib/glib/glib-mirroring-tab/packtab.c | 424 + glib/glib/glib-mirroring-tab/packtab.h | 50 + glib/glib/glib-object.h | 42 + glib/glib/glib-private.c | 46 + glib/glib/glib-private.h | 47 + glib/glib/glib-unix.c | 280 + glib/glib/glib-unix.h | 84 + glib/glib/glib.h | 112 + glib/glib/glib.py | 250 + glib/glib/glib.rc.in | 30 + glib/glib/glib.stp.in | 84 + glib/glib/glib.symbols | 1665 ++ glib/glib/glib_trace.h | 43 + glib/glib/glibintl.h | 42 + glib/glib/glist.c | 1133 ++ glib/glib/glist.h | 117 + glib/glib/gmacros.h | 343 + glib/glib/gmain-internal.h | 35 + glib/glib/gmain.c | 4891 +++++ glib/glib/gmain.h | 491 + glib/glib/gmappedfile.c | 402 + glib/glib/gmappedfile.h | 52 + glib/glib/gmarkup.c | 2824 +++ glib/glib/gmarkup.h | 238 + glib/glib/gmem.c | 881 + glib/glib/gmem.h | 264 + glib/glib/gmessages.c | 1431 ++ glib/glib/gmessages.h | 404 + glib/glib/gmirroringtable.h | 901 + glib/glib/gnode.c | 1251 ++ glib/glib/gnode.h | 298 + glib/glib/gnulib/Makefile.am | 22 + glib/glib/gnulib/README | 44 + glib/glib/gnulib/asnprintf.c | 40 + glib/glib/gnulib/g-gnulib.h | 49 + glib/glib/gnulib/printf-args.c | 133 + glib/glib/gnulib/printf-args.h | 142 + glib/glib/gnulib/printf-parse.c | 498 + glib/glib/gnulib/printf-parse.h | 74 + glib/glib/gnulib/printf.c | 154 + glib/glib/gnulib/printf.h | 57 + glib/glib/gnulib/vasnprintf.c | 1081 ++ glib/glib/gnulib/vasnprintf.h | 61 + glib/glib/goption.c | 2466 +++ glib/glib/goption.h | 370 + glib/glib/gpattern.c | 442 + glib/glib/gpattern.h | 49 + glib/glib/gpoll.c | 432 + glib/glib/gpoll.h | 120 + glib/glib/gprimes.c | 98 + glib/glib/gprimes.h | 51 + glib/glib/gprintf.c | 340 + glib/glib/gprintf.h | 52 + glib/glib/gprintfint.h | 59 + glib/glib/gqsort.c | 306 + glib/glib/gqsort.h | 46 + glib/glib/gquark.h | 52 + glib/glib/gqueue.c | 1072 ++ glib/glib/gqueue.h | 152 + glib/glib/grand.c | 695 + glib/glib/grand.h | 85 + glib/glib/gregex.c | 2971 +++ glib/glib/gregex.h | 475 + glib/glib/gscanner.c | 2260 +++ glib/glib/gscanner.h | 284 + glib/glib/gscripttable.h | 3120 ++++ glib/glib/gsequence.c | 2007 ++ glib/glib/gsequence.h | 136 + glib/glib/gshell.c | 685 + glib/glib/gshell.h | 55 + glib/glib/gslice.c | 1718 ++ glib/glib/gslice.h | 86 + glib/glib/gslist.c | 1042 ++ glib/glib/gslist.h | 111 + glib/glib/gspawn-win32-helper.c | 333 + glib/glib/gspawn-win32.c | 1493 ++ glib/glib/gspawn.c | 1728 ++ glib/glib/gspawn.h | 239 + glib/glib/gstdio.c | 832 + glib/glib/gstdio.h | 149 + glib/glib/gstrfuncs.c | 2805 +++ glib/glib/gstrfuncs.h | 247 + glib/glib/gstring.c | 1234 ++ glib/glib/gstring.h | 155 + glib/glib/gstringchunk.c | 327 + glib/glib/gstringchunk.h | 53 + glib/glib/gtester-report | 492 + glib/glib/gtester.c | 729 + glib/glib/gtestutils.c | 2573 +++ glib/glib/gtestutils.h | 301 + glib/glib/gthread-posix.c | 1180 ++ glib/glib/gthread-win32.c | 1032 ++ glib/glib/gthread.c | 1014 + glib/glib/gthread.h | 231 + glib/glib/gthreadpool.c | 1016 + glib/glib/gthreadpool.h | 80 + glib/glib/gthreadprivate.h | 68 + glib/glib/gtimer.c | 555 + glib/glib/gtimer.h | 65 + glib/glib/gtimezone.c | 817 + glib/glib/gtimezone.h | 81 + glib/glib/gtrashstack.c | 94 + glib/glib/gtrashstack.h | 103 + glib/glib/gtree.c | 1413 ++ glib/glib/gtree.h | 90 + glib/glib/gtypes.h | 484 + glib/glib/gunibreak.c | 61 + glib/glib/gunibreak.h | 20548 +++++++++++++++++++++ glib/glib/gunichartables.h | 15148 +++++++++++++++ glib/glib/gunicode.h | 751 + glib/glib/gunicodeprivate.h | 35 + glib/glib/gunicollate.c | 683 + glib/glib/gunicomp.h | 922 + glib/glib/gunidecomp.c | 751 + glib/glib/gunidecomp.h | 13321 +++++++++++++ glib/glib/guniprop.c | 1510 ++ glib/glib/gurifuncs.c | 252 + glib/glib/gurifuncs.h | 81 + glib/glib/gutf8.c | 1747 ++ glib/glib/gutils.c | 2393 +++ glib/glib/gutils.h | 373 + glib/glib/gvariant-core.c | 1075 ++ glib/glib/gvariant-core.h | 46 + glib/glib/gvariant-internal.h | 49 + glib/glib/gvariant-parser.c | 2550 +++ glib/glib/gvariant-serialiser.c | 1689 ++ glib/glib/gvariant-serialiser.h | 66 + glib/glib/gvariant.c | 5192 ++++++ glib/glib/gvariant.h | 282 + glib/glib/gvarianttype.c | 1523 ++ glib/glib/gvarianttype.h | 352 + glib/glib/gvarianttypeinfo.c | 869 + glib/glib/gvarianttypeinfo.h | 151 + glib/glib/gversion.c | 157 + glib/glib/gversion.h | 78 + glib/glib/gversionmacros.h | 212 + glib/glib/gwakeup.c | 260 + glib/glib/gwakeup.h | 37 + glib/glib/gwin32.c | 577 + glib/glib/gwin32.h | 118 + glib/glib/libcharset/.gitignore | 3 + glib/glib/libcharset/Makefile.am | 64 + glib/glib/libcharset/README | 46 + glib/glib/libcharset/codeset.m4 | 21 + glib/glib/libcharset/config.charset | 640 + glib/glib/libcharset/glibc21.m4 | 30 + glib/glib/libcharset/libcharset-glib.patch | 77 + glib/glib/libcharset/libcharset.h | 46 + glib/glib/libcharset/localcharset.c | 465 + glib/glib/libcharset/localcharset.h | 43 + glib/glib/libcharset/make-patch.sh | 28 + glib/glib/libcharset/ref-add.sin | 31 + glib/glib/libcharset/ref-del.sin | 26 + glib/glib/libcharset/update.sh | 33 + glib/glib/libglib-gdb.py.in | 10 + glib/glib/win_iconv.c | 1965 ++ glib/m4macros/.gitignore | 6 + glib/m4macros/Makefile.am | 8 + glib/m4macros/glib-2.0.m4 | 214 + glib/m4macros/glib-gettext.m4 | 436 + glib/m4macros/gsettings.m4 | 83 + glib/mkinstalldirs | 162 + 255 files changed, 207331 insertions(+) create mode 100644 glib/.gitignore create mode 100644 glib/AUTHORS create mode 100644 glib/COPYING create mode 100644 glib/Makefile.am create mode 100644 glib/Makefile.decl create mode 100644 glib/NEWS create mode 100644 glib/README.in create mode 100644 glib/acglib.m4 create mode 100644 glib/acinclude.m4 create mode 100644 glib/configure.ac create mode 100644 glib/glib-gettextize.in create mode 100644 glib/glib.doap create mode 100644 glib/glib/.gitignore create mode 100644 glib/glib/Makefile.am create mode 100755 glib/glib/abicheck.sh create mode 100644 glib/glib/deprecated/gallocator.c create mode 100644 glib/glib/deprecated/gallocator.h create mode 100644 glib/glib/deprecated/gcache.c create mode 100644 glib/glib/deprecated/gcache.h create mode 100644 glib/glib/deprecated/gcompletion.c create mode 100644 glib/glib/deprecated/gcompletion.h create mode 100644 glib/glib/deprecated/gmain.h create mode 100644 glib/glib/deprecated/grel.c create mode 100644 glib/glib/deprecated/grel.h create mode 100644 glib/glib/deprecated/gthread-deprecated.c create mode 100644 glib/glib/deprecated/gthread.h create mode 100644 glib/glib/docs.c create mode 100644 glib/glib/galloca.h create mode 100644 glib/glib/garray.c create mode 100644 glib/glib/garray.h create mode 100644 glib/glib/gasyncqueue.c create mode 100644 glib/glib/gasyncqueue.h create mode 100644 glib/glib/gasyncqueueprivate.h create mode 100644 glib/glib/gatomic.c create mode 100644 glib/glib/gatomic.h create mode 100644 glib/glib/gbacktrace.c create mode 100644 glib/glib/gbacktrace.h create mode 100644 glib/glib/gbase64.c create mode 100644 glib/glib/gbase64.h create mode 100644 glib/glib/gbitlock.c create mode 100644 glib/glib/gbitlock.h create mode 100644 glib/glib/gbookmarkfile.c create mode 100644 glib/glib/gbookmarkfile.h create mode 100644 glib/glib/gbsearcharray.h create mode 100644 glib/glib/gbytes.c create mode 100644 glib/glib/gbytes.h create mode 100644 glib/glib/gcharset.c create mode 100644 glib/glib/gcharset.h create mode 100644 glib/glib/gchecksum.c create mode 100644 glib/glib/gchecksum.h create mode 100644 glib/glib/gconstructor.h create mode 100644 glib/glib/gconvert.c create mode 100644 glib/glib/gconvert.h create mode 100644 glib/glib/gdataset.c create mode 100644 glib/glib/gdataset.h create mode 100644 glib/glib/gdatasetprivate.h create mode 100644 glib/glib/gdate.c create mode 100644 glib/glib/gdate.h create mode 100644 glib/glib/gdatetime.c create mode 100644 glib/glib/gdatetime.h create mode 100644 glib/glib/gdir.c create mode 100644 glib/glib/gdir.h create mode 100755 glib/glib/gen-iswide-table.py create mode 100755 glib/glib/gen-script-table.pl create mode 100755 glib/glib/gen-unicode-tables.pl create mode 100644 glib/glib/genviron.c create mode 100644 glib/glib/genviron.h create mode 100644 glib/glib/gerror.c create mode 100644 glib/glib/gerror.h create mode 100644 glib/glib/gfileutils.c create mode 100644 glib/glib/gfileutils.h create mode 100644 glib/glib/ggettext.c create mode 100644 glib/glib/ggettext.h create mode 100644 glib/glib/ghash.c create mode 100644 glib/glib/ghash.h create mode 100644 glib/glib/ghmac.c create mode 100644 glib/glib/ghmac.h create mode 100644 glib/glib/ghook.c create mode 100644 glib/glib/ghook.h create mode 100644 glib/glib/ghostutils.c create mode 100644 glib/glib/ghostutils.h create mode 100644 glib/glib/gi18n-lib.h create mode 100644 glib/glib/gi18n.h create mode 100644 glib/glib/giochannel.c create mode 100644 glib/glib/giochannel.h create mode 100644 glib/glib/giounix.c create mode 100644 glib/glib/giowin32.c create mode 100644 glib/glib/gkeyfile.c create mode 100644 glib/glib/gkeyfile.h create mode 100644 glib/glib/glib-init.c create mode 100644 glib/glib/glib-init.h create mode 100644 glib/glib/glib-mirroring-tab/Makefile create mode 100644 glib/glib/glib-mirroring-tab/gen-mirroring-tab.c create mode 100644 glib/glib/glib-mirroring-tab/packtab.c create mode 100644 glib/glib/glib-mirroring-tab/packtab.h create mode 100644 glib/glib/glib-object.h create mode 100644 glib/glib/glib-private.c create mode 100644 glib/glib/glib-private.h create mode 100644 glib/glib/glib-unix.c create mode 100644 glib/glib/glib-unix.h create mode 100644 glib/glib/glib.h create mode 100644 glib/glib/glib.py create mode 100644 glib/glib/glib.rc.in create mode 100644 glib/glib/glib.stp.in create mode 100644 glib/glib/glib.symbols create mode 100644 glib/glib/glib_trace.h create mode 100644 glib/glib/glibintl.h create mode 100644 glib/glib/glist.c create mode 100644 glib/glib/glist.h create mode 100644 glib/glib/gmacros.h create mode 100644 glib/glib/gmain-internal.h create mode 100644 glib/glib/gmain.c create mode 100644 glib/glib/gmain.h create mode 100644 glib/glib/gmappedfile.c create mode 100644 glib/glib/gmappedfile.h create mode 100644 glib/glib/gmarkup.c create mode 100644 glib/glib/gmarkup.h create mode 100644 glib/glib/gmem.c create mode 100644 glib/glib/gmem.h create mode 100644 glib/glib/gmessages.c create mode 100644 glib/glib/gmessages.h create mode 100644 glib/glib/gmirroringtable.h create mode 100644 glib/glib/gnode.c create mode 100644 glib/glib/gnode.h create mode 100644 glib/glib/gnulib/Makefile.am create mode 100644 glib/glib/gnulib/README create mode 100644 glib/glib/gnulib/asnprintf.c create mode 100644 glib/glib/gnulib/g-gnulib.h create mode 100644 glib/glib/gnulib/printf-args.c create mode 100644 glib/glib/gnulib/printf-args.h create mode 100644 glib/glib/gnulib/printf-parse.c create mode 100644 glib/glib/gnulib/printf-parse.h create mode 100644 glib/glib/gnulib/printf.c create mode 100644 glib/glib/gnulib/printf.h create mode 100644 glib/glib/gnulib/vasnprintf.c create mode 100644 glib/glib/gnulib/vasnprintf.h create mode 100644 glib/glib/goption.c create mode 100644 glib/glib/goption.h create mode 100644 glib/glib/gpattern.c create mode 100644 glib/glib/gpattern.h create mode 100644 glib/glib/gpoll.c create mode 100644 glib/glib/gpoll.h create mode 100644 glib/glib/gprimes.c create mode 100644 glib/glib/gprimes.h create mode 100644 glib/glib/gprintf.c create mode 100644 glib/glib/gprintf.h create mode 100644 glib/glib/gprintfint.h create mode 100644 glib/glib/gqsort.c create mode 100644 glib/glib/gqsort.h create mode 100644 glib/glib/gquark.h create mode 100644 glib/glib/gqueue.c create mode 100644 glib/glib/gqueue.h create mode 100644 glib/glib/grand.c create mode 100644 glib/glib/grand.h create mode 100644 glib/glib/gregex.c create mode 100644 glib/glib/gregex.h create mode 100644 glib/glib/gscanner.c create mode 100644 glib/glib/gscanner.h create mode 100644 glib/glib/gscripttable.h create mode 100644 glib/glib/gsequence.c create mode 100644 glib/glib/gsequence.h create mode 100644 glib/glib/gshell.c create mode 100644 glib/glib/gshell.h create mode 100644 glib/glib/gslice.c create mode 100644 glib/glib/gslice.h create mode 100644 glib/glib/gslist.c create mode 100644 glib/glib/gslist.h create mode 100644 glib/glib/gspawn-win32-helper.c create mode 100644 glib/glib/gspawn-win32.c create mode 100644 glib/glib/gspawn.c create mode 100644 glib/glib/gspawn.h create mode 100644 glib/glib/gstdio.c create mode 100644 glib/glib/gstdio.h create mode 100644 glib/glib/gstrfuncs.c create mode 100644 glib/glib/gstrfuncs.h create mode 100644 glib/glib/gstring.c create mode 100644 glib/glib/gstring.h create mode 100644 glib/glib/gstringchunk.c create mode 100644 glib/glib/gstringchunk.h create mode 100755 glib/glib/gtester-report create mode 100644 glib/glib/gtester.c create mode 100644 glib/glib/gtestutils.c create mode 100644 glib/glib/gtestutils.h create mode 100644 glib/glib/gthread-posix.c create mode 100644 glib/glib/gthread-win32.c create mode 100644 glib/glib/gthread.c create mode 100644 glib/glib/gthread.h create mode 100644 glib/glib/gthreadpool.c create mode 100644 glib/glib/gthreadpool.h create mode 100644 glib/glib/gthreadprivate.h create mode 100644 glib/glib/gtimer.c create mode 100644 glib/glib/gtimer.h create mode 100644 glib/glib/gtimezone.c create mode 100644 glib/glib/gtimezone.h create mode 100644 glib/glib/gtrashstack.c create mode 100644 glib/glib/gtrashstack.h create mode 100644 glib/glib/gtree.c create mode 100644 glib/glib/gtree.h create mode 100644 glib/glib/gtypes.h create mode 100644 glib/glib/gunibreak.c create mode 100644 glib/glib/gunibreak.h create mode 100644 glib/glib/gunichartables.h create mode 100644 glib/glib/gunicode.h create mode 100644 glib/glib/gunicodeprivate.h create mode 100644 glib/glib/gunicollate.c create mode 100644 glib/glib/gunicomp.h create mode 100644 glib/glib/gunidecomp.c create mode 100644 glib/glib/gunidecomp.h create mode 100644 glib/glib/guniprop.c create mode 100644 glib/glib/gurifuncs.c create mode 100644 glib/glib/gurifuncs.h create mode 100644 glib/glib/gutf8.c create mode 100644 glib/glib/gutils.c create mode 100644 glib/glib/gutils.h create mode 100644 glib/glib/gvariant-core.c create mode 100644 glib/glib/gvariant-core.h create mode 100644 glib/glib/gvariant-internal.h create mode 100644 glib/glib/gvariant-parser.c create mode 100644 glib/glib/gvariant-serialiser.c create mode 100644 glib/glib/gvariant-serialiser.h create mode 100644 glib/glib/gvariant.c create mode 100644 glib/glib/gvariant.h create mode 100644 glib/glib/gvarianttype.c create mode 100644 glib/glib/gvarianttype.h create mode 100644 glib/glib/gvarianttypeinfo.c create mode 100644 glib/glib/gvarianttypeinfo.h create mode 100644 glib/glib/gversion.c create mode 100644 glib/glib/gversion.h create mode 100644 glib/glib/gversionmacros.h create mode 100644 glib/glib/gwakeup.c create mode 100644 glib/glib/gwakeup.h create mode 100644 glib/glib/gwin32.c create mode 100644 glib/glib/gwin32.h create mode 100644 glib/glib/libcharset/.gitignore create mode 100644 glib/glib/libcharset/Makefile.am create mode 100644 glib/glib/libcharset/README create mode 100644 glib/glib/libcharset/codeset.m4 create mode 100755 glib/glib/libcharset/config.charset create mode 100644 glib/glib/libcharset/glibc21.m4 create mode 100644 glib/glib/libcharset/libcharset-glib.patch create mode 100644 glib/glib/libcharset/libcharset.h create mode 100644 glib/glib/libcharset/localcharset.c create mode 100644 glib/glib/libcharset/localcharset.h create mode 100755 glib/glib/libcharset/make-patch.sh create mode 100644 glib/glib/libcharset/ref-add.sin create mode 100644 glib/glib/libcharset/ref-del.sin create mode 100755 glib/glib/libcharset/update.sh create mode 100644 glib/glib/libglib-gdb.py.in create mode 100644 glib/glib/win_iconv.c create mode 100644 glib/m4macros/.gitignore create mode 100644 glib/m4macros/Makefile.am create mode 100644 glib/m4macros/glib-2.0.m4 create mode 100644 glib/m4macros/glib-gettext.m4 create mode 100644 glib/m4macros/gsettings.m4 create mode 100755 glib/mkinstalldirs diff --git a/glib/.gitignore b/glib/.gitignore new file mode 100644 index 0000000..a19c655 --- /dev/null +++ b/glib/.gitignore @@ -0,0 +1,43 @@ +# for all subdirectories +Makefile.in +Makefile +TAGS +.libs +.deps +*.o +*.lo +*.la +*.pc +.*.swp +.sw? +*.rc +*.gcno +*.gcda +*.gcov +*.sourcefiles +*.stp +*.exe + +# autofoo stuff here +compile +config.* +configure +depcomp +aclocal.m4 +autom4te.cache +stamp-* +libtool +ltmain.sh +mingw32-config.cache +missing +install-sh +glib-gettextize +glib-zip +gtk-doc.make +py-compile + +INSTALL +README +ChangeLog +/glib-lcov.info +/glib-lcov/ diff --git a/glib/AUTHORS b/glib/AUTHORS new file mode 100644 index 0000000..17814ca --- /dev/null +++ b/glib/AUTHORS @@ -0,0 +1,40 @@ +Below are just a few of the people who have contributed +to GLib. Please don't mail these people about problems you +have with GTK+; see the README file for information about +filing bugs and submitting patches. + +GLib-2.0 Team +------------- +Hans Breuer +Matthias Clasen +Tor Lillqvist +Tim Janik +Havoc Pennington +Ron Steinke +Owen Taylor +Sebastian Wilhelmi + +GLib-1.2 Team +------------- +Shawn T. Amundson +Jeff Garzik +Raja R Harinath +Tim Janik +Elliot Lee +Tor Lillqvist +Paolo Molaro +Havoc Pennington +Manish Singh +Owen Taylor +Sebastian Wilhelmi + +The random number generator "Mersenne Twister", which is used by GLib, +was developed and originally coded by: +Makoto Matsumoto +Takuji Nishimura + +Original Authors +---------------- +Peter Mattis +Spencer Kimball +Josh MacDonald diff --git a/glib/COPYING b/glib/COPYING new file mode 100644 index 0000000..bf50f20 --- /dev/null +++ b/glib/COPYING @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307 USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/glib/Makefile.am b/glib/Makefile.am new file mode 100644 index 0000000..f5c510d --- /dev/null +++ b/glib/Makefile.am @@ -0,0 +1,135 @@ +## Process this file with automake to produce Makefile.in +include $(top_srcdir)/Makefile.decl + +# http://people.gnome.org/~walters/docs/build-api.txt +.buildapi-allow-builddir: + +ACLOCAL_AMFLAGS = -I m4macros ${ACLOCAL_FLAGS} + +SUBDIRS = . m4macros glib gmodule gthread gobject gio tests po docs +DIST_SUBDIRS = $(SUBDIRS) build + +bin_SCRIPTS = glib-gettextize + +AM_CPPFLAGS = \ + -DG_LOG_DOMAIN=g_log_domain_glib \ + @GLIB_DEBUG_FLAGS@ \ + -DG_DISABLE_DEPRECATED \ + -DGLIB_COMPILATION + +EXTRA_DIST += \ + ChangeLog.pre-2-20 \ + ChangeLog.pre-2-18 \ + ChangeLog.pre-2-16 \ + ChangeLog.pre-2-14 \ + ChangeLog.pre-2-12 \ + ChangeLog.pre-2-10 \ + ChangeLog.pre-2-8 \ + ChangeLog.pre-2-6 \ + ChangeLog.pre-2-4 \ + ChangeLog.pre-2-2 \ + ChangeLog.pre-2-0 \ + ChangeLog.pre-1-2 \ + glib-zip.in \ + NEWS.pre-1-3 \ + acglib.m4 \ + sanity_check \ + README.commits \ + README.in \ + INSTALL.in \ + README.win32 \ + HACKING \ + autogen.sh \ + Makefile.decl \ + mkinstalldirs \ + makefile.msc \ + msvc_recommended_pragmas.h \ + config.h.win32.in \ + po/po2tbl.sed.in \ + glib-2.0.pc.in \ + gobject-2.0.pc.in \ + gmodule-2.0.pc.in \ + gmodule-export-2.0.pc.in \ + gmodule-no-export-2.0.pc.in \ + gthread-2.0.pc.in \ + gio-2.0.pc.in \ + gio-unix-2.0.pc.in \ + gio-windows-2.0.pc.in + + +# These may be in the builddir too +BUILT_EXTRA_DIST = \ + README \ + INSTALL \ + ChangeLog \ + config.h.win32 \ + gtk-doc.make + +CONFIGURE_DEPENDENCIES = acglib.m4 + +ChangeLog: + $(AM_V_GEN) if test -d "$(srcdir)/.git"; then \ + (GIT_DIR=$(top_srcdir)/.git ./missing --run git log GLIB_2_20_0^^.. --stat) | fmt --split-only > $@.tmp \ + && mv -f $@.tmp $@ \ + || ($(RM) $@.tmp; \ + echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \ + (test -f $@ || echo git-log is required to generate this file >> $@)); \ + else \ + test -f $@ || \ + (echo A git checkout and git-log is required to generate ChangeLog >&2 && \ + echo A git checkout and git-log is required to generate this file >> $@); \ + fi + +pkgconfigdir = $(libdir)/pkgconfig +pkgconfig_DATA = glib-2.0.pc gobject-2.0.pc gmodule-2.0.pc gmodule-export-2.0.pc gmodule-no-export-2.0.pc gthread-2.0.pc gio-2.0.pc + +if OS_UNIX +pkgconfig_DATA += gio-unix-2.0.pc +endif + +if OS_WIN32 +pkgconfig_DATA += gio-windows-2.0.pc +endif + +$(pkgconfig_DATA): config.status + +# install mkinstalldirs for glib-gettextize's benefit +gettextdir = $(datadir)/glib-2.0/gettext +gettext_SCRIPTS = mkinstalldirs + +# build documentation when doing distcheck +DISTCHECK_CONFIGURE_FLAGS = --enable-debug --enable-gtk-doc --enable-man --disable-maintainer-mode + +DISTCLEANFILES = config.lt + +distclean-local: lcov-clean + if test $(srcdir) = .; then :; else \ + rm -f $(BUILT_EXTRA_DIST); \ + fi + +.PHONY: files release sanity snapshot ChangeLog + +files: + @files=`ls $(DISTFILES) 2> /dev/null `; for p in $$files; do \ + echo $$p; \ + done + +release: + rm -rf .deps */.deps + cd docs && make glib.html + $(MAKE) distcheck + +sanity: + ./sanity_check $(VERSION) + +snapshot: + $(MAKE) dist distdir=$(PACKAGE)-snap`date +"%Y%m%d"` + +snapcheck: + $(MAKE) distcheck distdir=$(PACKAGE)-snap`date +"%Y%m%d"` + +dist-hook: $(BUILT_EXTRA_DIST) + files='$(BUILT_EXTRA_DIST)'; \ + for f in $$files; do \ + if test -f $$f; then d=.; else d=$(srcdir); fi; \ + rm -f $(distdir)/$$f && cp $$d/$$f $(distdir) || exit 1; done diff --git a/glib/Makefile.decl b/glib/Makefile.decl new file mode 100644 index 0000000..50cf169 --- /dev/null +++ b/glib/Makefile.decl @@ -0,0 +1,97 @@ +# GLIB - Library of useful C routines + +#GTESTER = gtester # for non-GLIB packages +GTESTER = $(top_builddir)/glib/gtester # for the GLIB package +GTESTER_REPORT = $(top_builddir)/glib/gtester-report # for the GLIB package + +# initialize variables for unconditional += appending +EXTRA_DIST = +TEST_PROGS = + +### testing rules + +# test: run all tests in cwd and subdirs +test: test-nonrecursive +if OS_UNIX + @ for subdir in $(SUBDIRS) . ; do \ + test "$$subdir" = "." -o "$$subdir" = "po" || \ + ( cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $? ; \ + done + +# test-nonrecursive: run tests only in cwd +test-nonrecursive: ${TEST_PROGS} + @test -z "${TEST_PROGS}" || G_DEBUG=gc-friendly MALLOC_CHECK_=2 MALLOC_PERTURB_=$$(($${RANDOM:-256} % 256)) ${GTESTER} --verbose ${TEST_PROGS} +else +test-nonrecursive: +endif + +# test-report: run tests in subdirs and generate report +# perf-report: run tests in subdirs with -m perf and generate report +# full-report: like test-report: with -m perf and -m slow +test-report perf-report full-report: ${TEST_PROGS} + @test -z "${TEST_PROGS}" || { \ + case $@ in \ + test-report) test_options="-k";; \ + perf-report) test_options="-k -m=perf";; \ + full-report) test_options="-k -m=perf -m=slow";; \ + esac ; \ + if test -z "$$GTESTER_LOGDIR" ; then \ + ${GTESTER} --verbose $$test_options -o test-report.xml ${TEST_PROGS} ; \ + elif test -n "${TEST_PROGS}" ; then \ + ${GTESTER} --verbose $$test_options -o `mktemp "$$GTESTER_LOGDIR/log-XXXXXX"` ${TEST_PROGS} ; \ + fi ; \ + } + @ ignore_logdir=true ; \ + if test -z "$$GTESTER_LOGDIR" ; then \ + GTESTER_LOGDIR=`mktemp -d "\`pwd\`/.testlogs-XXXXXX"`; export GTESTER_LOGDIR ; \ + ignore_logdir=false ; \ + fi ; \ + if test -d "$(top_srcdir)/.git" ; then \ + REVISION=`git describe` ; \ + else \ + REVISION=$(VERSION) ; \ + fi ; \ + for subdir in $(SUBDIRS) . ; do \ + test "$$subdir" = "." -o "$$subdir" = "po" || \ + ( cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $@ ) || exit $? ; \ + done ; \ + $$ignore_logdir || { \ + echo '' > $@.xml ; \ + echo '' >> $@.xml ; \ + echo '' >> $@.xml ; \ + echo ' $(PACKAGE)' >> $@.xml ; \ + echo ' $(VERSION)' >> $@.xml ; \ + echo " $$REVISION" >> $@.xml ; \ + echo '' >> $@.xml ; \ + for lf in `ls -L "$$GTESTER_LOGDIR"/.` ; do \ + sed '1,1s/^?]*?>//' <"$$GTESTER_LOGDIR"/"$$lf" >> $@.xml ; \ + done ; \ + echo >> $@.xml ; \ + echo '' >> $@.xml ; \ + rm -rf "$$GTESTER_LOGDIR"/ ; \ + ${GTESTER_REPORT} --version 2>/dev/null 1>&2 ; test "$$?" != 0 || ${GTESTER_REPORT} $@.xml >$@.html ; \ + } +.PHONY: test test-report perf-report full-report test-nonrecursive + +.PHONY: lcov genlcov lcov-clean +# use recursive makes in order to ignore errors during check +lcov: + -$(MAKE) $(AM_MAKEFLAGS) -k check + $(MAKE) $(AM_MAKEFLAGS) genlcov + +# we have to massage the lcov.info file slightly to hide the effect of libtool +# placing the objects files in the .libs/ directory separate from the *.c +# we also have to delete tests/.libs/libmoduletestplugin_*.gcda +genlcov: + rm -f $(top_builddir)/tests/.libs/libmoduletestplugin_*.gcda + $(LTP) --directory $(top_builddir) --capture --output-file glib-lcov.info --test-name GLIB_PERF --no-checksum --compat-libtool + LANG=C $(LTP_GENHTML) --prefix $(top_builddir) --output-directory glib-lcov --title "GLib Code Coverage" --legend --show-details glib-lcov.info + @echo "file://$(abs_top_builddir)/glib-lcov/index.html" + +lcov-clean: + -$(LTP) --directory $(top_builddir) -z + -rm -rf glib-lcov.info glib-lcov + -find -name '*.gcda' -print | xargs rm + +# run tests in cwd as part of make check +check-local: test-nonrecursive diff --git a/glib/NEWS b/glib/NEWS new file mode 100644 index 0000000..0a2e06e --- /dev/null +++ b/glib/NEWS @@ -0,0 +1,6191 @@ +Overview of changes from GLib 2.31.22 to 2.32.0 +=============================================== + +* Bugs fixed: + 671988 Quickly registering / unregistering objects on bus... + 672095 glib needs stable sort function + 672406 glib/tests/include.c fails to build on FreeBSD + +* Updated translations: + Telugu + + +Overview of changes from GLib 2.31.20 to 2.31.22 +================================================ + +* Bugs fixed: + 531901 Use __builtin_bswap* for GUINT*_SWAP_LE_BE if building... + 653167 Out of tree build is broken on windows + 668973 Test /gvariant/parser fails on Solaris 10 + 669797 gvfs now lists its fuse mounts + 670846 deadlock: GStreamer-WARNING **: wrong STREAM_LOCK count 0 + 671664 gio-querymodules: unlink instead of writing empty cache + 671676 Glib can't be cross-compiled any more after merge of... + 671918 gnome-shell is inaccessible unless started while an AT... + 671942 GSocketMsgFlags: annotate as a flags + 671997 Unix signal handling assumes that volatile 1-byte writes... + 672013 GSimpleAsyncResult: support reliable cancellation + 672026 default log output should include pid and/or prgname + 672095 glib needs stable sort function + 672201 G_SPAWN_SEARCH_PATH should continue on ENODEV and ETIMEDOUT + 672239 request NO_REPLY from g_dbus_connection_call() with no as... + 672249 gdbusproxy leaks asyncresult in an error case instead of... + +* Translation updates: + Assamese + British English + Catalan + Catalan (Valencian) + Danish + Esperanto + Finnish + French + German + Hungarian + Korean + Lithuanian + Norwegian bokmÃ¥l + Polish + Portuguese + Russian + Traditional Chinese + + +Overview of changes from GLib 2.31.18 to 2.31.20 +================================================ + +* Update to Unicode 6.1 + +* Update PCRE to 8.30 + +* Deprecations are now versioned, and new API is + marked with the version it was introduced. + Use these with GLIB_VERSION_{MIN,MAX}_REQUIRED + +* The performance of signal emissions has been + improved for simple cases + +* Bugs fixed: + 529806 Cannot build in 64-bit Mac OS X due to libiconv + 580873 Documentation of register type functions incomplete + 592666 Document how to unset an attribute + 597785 g_type_class_add_private code snippet is a bad example + 621368 glib-2.24.1: FAIL: run-assert-msg-test.sh when updating... + 622149 --disable-regex breaks glib2 build + 639873 GBinding: Crash when binding two properties on the same... + 640202 For GLIB v. 2.23.6 and above: impossibility to build mu... + 668295 Need a way to classify GVolume instances + 669670 gasyncqueue: don't use deprecated g_cond_timed_wait() + 670542 Add version information for deprecations + 670557 gvaluetransform: Fix an infinite loop with GFlagsValue... + 670721 global variable for signal ID should be hidden + 670751 IceWM build fails due to the G_DEPRECATED_FOR macro + 670909 g_dbus_connection_call leaks when it receives an error... + 670922 Include path to gdbus-codegen in the pkgconfig file + 670969 GSequence lookup may fail if there was no sort prior to... + 671025 Constants and identifiers starting with a number are no... + 671270 make distclean failures + 671281 glib-compile-resources.xml is missing from the dist tar... + +* Translation updates: + Basque + Belarusian + Brazilian Portuguese + Bulgarian + Galician + Hebrew + Lithuanian + Persian + Punjabi + Serbian + Simplified Chinese + Slovenian + Telugu + Traditional Chinese + Uyghur + Vietnamese + + +Overview of changes from GLib 2.31.16 to 2.31.18 +================================================ + +* GDBusProxy has now a flag, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + which can be set to make GDBus automatically reload + changed properties even if the propertychanged signal + does not contain the new values. + +* GApplication puts non-unique applications on the bus + +* GApplication now has g_application_quit() + +* g_async_queue_timed_pop has been deprecated in favor of + the new g_async_queue_timeout_pop, which uses relative + delays in microseconds instead of a GTimeVal. + +* a huge number of API documentation fixes + +* Bugs fixed: + 647986 put non-unique apps on D-Bus + 658484 vpn connection vs NetworkSecretDialog + 664237 GDateTime falls back to UTC if TZ is set + 669329 gthread-win32: update for g_get_monotonic_time() changes + 669330 glocalfile: fix error code when opening a directory on win32 + 669372 glib/tests memory leaks. + 669412 mem leak in g_environ_unsetenv + 669538 Fix compilation of glib-compile-resources.c on Windows + 669544 gdbus-codegen example introspection XML is not complete + 669595 glib-mkenums: fix handling of forward enum declarations + 669670 gasyncqueue: don't use deprecated g_cond_timed_wait() + 669671 gobject: use #pragmas to avoid deprecated function warnings + 669689 Retrieve cwd and environ in local GApplicationCommandLine + 669810 socket/win32: flush pending read before signaling HUP + 669865 g_regex_fetch() + 670085 memory leak in g_output_stream_write_async + 670138 gbytes.h is missing the G_BEGIN/END_DECL guards + 670485 Simplify session API (shared bug with gtk+) + +* Updated translations: + Belarusian + Danish + Galician + Serbian + Telugu + Hebrew + + +Overview of changes from GLib 2.31.14 to 2.31.16 +================================================ + +* GResource: + - The resource compiler can now convert pngs into + pixel data that can be used without parsing at runtime + (requires gdk-pixbuf-pixdata to be present) + +* Bugs fixed: + 669123 resource compiler: failing to-pixdata should... + 669173 resource: fix xml preprocess entity handling + 669224 Cross-compilation broken by data-to-c + 669253 gsettings set buggy on array values + 669334 fix memory leak in bookmark file parser + +* Translation updates: + Norwegian bokmÃ¥l + Spanish + + +Overview of changes from GLib 2.31.12 to 2.31.14 +================================================ + +* GResource: + - GLib now includes a commandline utility, gresource, + to explore resources in ELF files + - The resource compiler can now optionally strip + ignorable whitespace from XML resources + - The resource compiler can now generate build dependencies + - The resource compiler will now autoselect output formats + +* GApplication: + - The menu markup parser API has been dropped, the + menu XML support lives in GTK+ now + +* GValueArray has been deprecated + +* Bugs fixed: + 626258 N-ary Trees - 'nodes' can be inserted before and after... + 634232 Core Dump / Aborted using g_key_file_to_data + 639099 schema compiler chokes on valid schema + 667228 Deprecate GValueArray + 667243 Add an element clear function to GArray + 667929 glib-compile-resources: xml resources doesn't need to... + 668250 g_date_time_format() produces a non-UTF8 string + 668468 'IP_ADD_SOURCE_MEMBERSHIP' undeclared + 668532 resources: add dependency generator to the resource compiler + 668539 resources: compiler should autoselect output format... + 668561 gresource-tool not internationalized + 668572 glib_cv_g_atomic_lock_free config.cache setting not honored... + 668650 GRealArray->clear_func should be initialized + 668756 GKeyFile: allow loading from empty strings + 668857 fix couple of typos in comments + 669024 goption: implement platform_get_argv0() for OpenBSD + +* Updated translations: + Galician + Norwegian bokmÃ¥l + Spanish + Traditional Chinese + +Overview of changes from GLib 2.31.10 to 2.31.12 +================================================ + +* GApplication: + - Drop support for exporting menus - this functionality + will be provided in GtkApplication + - Add a way to create actions that change settings + +* Bugs fixed: + 629503 Add async versions of g_unix_connection_{receive,send}_credentials + 656301 glib-compile-schemas should not create an empty file + 668071 mingw-gcc build fails on gio/gsocket.[c|h] + 668118 the big appmenu switcheroo + 668158 base64 encode and line termination + 668163 GDBusConnection: note that exit-on-close is sometimes TRUE + 668269 gsignal: add g_signal_handlers_disconnect_by_data + 668279 create GAction from GSettings + +* Translation updates: + Norwegian bokmÃ¥l + + +Overview of changes from GLib 2.31.8 to 2.31.10 +=============================================== + +* GResource: + - A new facility to allow linking data files into binaries + and make them available as resources + - Resources are compiled using glib-compile-resources + - GIO supports resource:/// uris to access resources + +* Bugs fixed: + 619126 Missing dependency libs + 658315 g_key_file_get_keys() should set length to 0... + 660371 is it ever valid to have 0 as a GError domain? + 666700 Add some missing (allow-none) annotations + 667375 GAsyncInitable subclassing (and async subclassing... + 667447 Missing many introspection annotations + 667790 Protect call to pthread_condattr_setclock with define + 667938 wrong gtypes generated for empty flags enums + +* Translation updates: + Hebrew + Spanish + + +Overview of changes from GLib 2.31.6 to 2.31.8 +============================================== + +* GObject: + - The type checks for overriding properties have been loosened. + In particular, it is now possible to add the CONSTRUCT flag + to an overridden property + - GWeakRef is a new API for weak references; unlike g_object_weak_ref + and g_object_add_weak_pointer, it is thread-safe. + +* GHashTable has grown new convenience api for use as a set: + g_hash_table_add, g_hash_table_contains + +* GSocketConnection has gained API for managing connection status + +* GSettings: a native OS X backend has been added, under the + name 'nexstep' + +* Bugs fixed + 455640 Something fishy with GRegex and unicode + 548954 weak references are not threadsafe + 625751 Add G_FILE_ATTRIBUTE_FILESYSTEM_USED + 658871 gbacktrace: g_get_prgname () isn't called for a NULL argu... + 664069 gvariant: Never break out of g_variant_iter_loop + 664830 g_strescape doesn't natively handle \v (vertical tab) + 665211 GDBusConnection singleton access can race with disposal + 665805 Add GSocketClient::action, for tracking socket client status + 666116 some tests provoke undefined behaviour, which is undesira... + 666422 Unreachable code in gio gnetworkmonitornetlink.c + 666551 Crash in g_thread_xp_SleepConditionVariableSRW + 666595 menu parser disallows id='' on submenu and section + 666615 loosen property override flag restrictions + 666616 gobject: fix property override type checks + 666803 g_utf8_validate() fails to validate strings with known size + 666804 g_ateaxit deprecation warning in devhelp points in wrong ... + 666951 g_mkdtemp: Since version incorrect in docs + 666978 Fails to compile glib applications with ISO C90 compiler + 667098 ginetaddressmask leaks its address property + 667225 GSocket: add missing type checks to public methods + 667226 GSocket: fix an error return value + 667279 Sometimes crashes when launching commandline-crea... + 667285 Wrong keyname listed in documentation for g_deskt... + 667331 Use g_queue_free_full() convenience function + 667420 GHashTable GDB pretty printing is broken + +* Updated translations + Belarusian + Bulgarian + Hebrew + Norwegian bokmÃ¥l + Norwegian Nynorsk + Spanish + Vietnamese + + +Overview of changes from GLib 2.31.4 to 2.31.6 +============================================== + +* GApplication no longer has APIs for setting menus. Those have been + moved to GtkApplication. + +* the GActionGroup import/export functionality has been decoupled from + GApplication by the introduction of a new interface for the purpose of + handling platform data: GRemoteActionGroup. This allows Gtk to + properly deal with platform data (and gdk threads) on window actions. + +* lots of documentation improvements + +* bug fixes and a huge number of memory leak fixes + +* the test suite now passes on ARM and some of the GDBus testcase hangs + we've been seeing have been resolved (although others could remain) + +* g_bytes_get_data() API changed: now includes 'size' out parameter + +* new g_queue_free_full() API similar to g_[s]list_free_full() + +* desktop files: use standard "Keywords" now, not "X-GNOME-Keywords" + +* gsettings commandline tool now has --schemadir option for schemas not + installed in the usual place (ie: as part of plugins) + +* Bugs fixed: + 643736 GApplication doesn't emit dbus signals on action updates + 657433 g_queue_free_full() missing + 664699 glib: documentation fixes + 665737 acquire/release gdk threads lock on incoming dbus + 665879 GBytes: add a size argument to g_bytes_get_data + 666113 various leaks in GLib, GIO are visible in the regression tests + 666115 various tests leak memory, obscuring real leaks in the library + 666145 Doc could be more explicite that g_thread_init calls can be droped + 666173 Configure warning - linux/netlink.h usability... no + 666296 Race condition in g_thread_xp_get_srwlock + 666415 Settings tools should allow specifying a schema directory + +* Translations updated: + French + Spanish + +Overview of changes from GLib 2.31.2 to 2.31.4 +============================================== + +* EXPERIMENTAL: Menu support has been added to GApplication. Menus + are exported on the bus, alongside the actions that are already there. + There have also been many related improvements to action group + functionality. + + These new APIs are subject to changes in the coming releases. In + particular, it seems somewhat likely that the APIs for registering + menubars may change in order to accommodate windows with different + types of menubars. + +* GDBusConnection previously directly dispatched destroy notifies when + unregistering objects if the current main context was the same context + the object was exported on. It now unconditionally dispatches these + through an idle on the context. + +* Clean up Requires in pc files. Linking against GIO no + longer drags in gmodule. This may require dependency + fixes here and there. + +* Introduce GBytes, a data type for immutable, fixed-size + byte sequences. This makes the pre-existing GBuffer + API available outside GLib + +* GDBusInterfaceSkeleton can now be exported on multiple + connections + +* Bugs fixed: + 600161 Do not use static GTypeInfo and GInterfaceInfo + 640077 GFileMonitor: Always send CHANGES_DONE_HINT after a move... + 641720 Misleading definition for local_command_line() in GApplic... + 648516 Little comment error and 2 useless lines of code + 651997 Dummy backend for gapplication + 652560 Test for g_ascii_strtod is failing + 662208 failure to initialize a GInitable should be considered... + 662718 GDBusInterfaceSkeleton should be able to export on multi... + 663291 GBytes: Immutable, refcounted sequence of bytes + 664406 Need context for a proper translation + 664455 Build fixes for GLib GIT master (2.31.x) + 664558 GDBusWorker.frozen has a value > 1 in a gboolean + 664559 sys/wait.h not available on windows + 664617 gdbus segfault error 4 in libgio-2.0.so.0.3102.0 + 664635 GMemory{Out,In}putStream _async functions break sub-class... + 664809 Add command line option to gtester to allow skipping tests + 665067 cryptic assertion failure if nonsensical flag combinations... + 665184 Check ref. count before reffing/unreffing + 665298 Add 'Requires.private: libpcre' to glib-2.0.pc + 665391 update documentation around mainloops + 665607 ./configure is there for fiddling with cross-compile enviro... + 665634 g_dbus_node_info_new_for_xml() errors on unknown attributes... + 665685 Add a #define for the max length of a Unicode decomposition + 665733 GDBusConnection holds lock while calling destroynotify + +* Translation updates: + Norwegian bokmÃ¥l + Spanish + + +Overview of changes from GLib 2.31.0 to 2.31.2 +============================================== + +* Monotonic time is now properly supported on Windows + +* glib-mkenums: fix @ENUMPREFIX@ with /*< underscore_name=... >*/ + +* EXPERIMENTAL: introduce new GSettingsSchema and GSettingsSchemaSource + APIs for the convenience of plugin system authors and those who wish + to introspect the contents of schemas. This API may change. + +* Improve the performance of GObject property notifies. + +* GDBus: + - fix a race when unowning a name immediately after owning it + - thread safety improvements on GDBusConnection + - fixes for exit-on-close functionality + +* Deprecations: + - add G_SIGNAL_DEPRECATED + - don't use G_DISABLE_DEPRECATED masking for functions anymore + +* docs + - tmpl/ is finally dead for glib + +* GIO: + - GInetAddressMask: new type for internet address range matching + - various GIO file and stream fixes + - improvements to attribute and fileinfo handling + +Overview of changes from GLib 2.29/2.30 to 2.31.0 +================================================= + +This release contains a huge number of changes (500 commits worth). The +list below attempts to summarise, but not every change is listed. + +* Major changes to threading and synchronisation + - threading is now always enabled in GLib + - support for custom thread implementations (including our own internal + support for errorcheck mutexes) has been removed + - a whole lot of dead code (to deal with the non-threaded case) has + been ripped out. This includes the racy path of GMainContext that + caused deadlocks with respect to child process exits in + single-threaded programs (such as gtester). + - libgthread is now an empty shell and g_thread_init() is no longer + required (and has been deprecated) + - GMutex and GCond can now be statically allocated without explicit + initialisation. Dynamic allocation for these types is deprecated. + - new types GRecMutex and GRWLock can also be statically allocated + without explicit initialisation. + - GPrivate can now be statically allocated and has an improved API. + Dynamic allocation of GPrivate is deprecated. + - GStaticMutex, GStaticRecMutex, GStaticRwLock, GStaticPrivate are + deprecated. + - GCond now uses monotonic time internally and a new API takes + monotonic time for timed waits, deprecating the wallclock API + - removal of the insane macro indirection used in the previous + implementation of threading and synchronisation APIs + - use SRWLock and CONDITION_VARIABLE APIs when available on Windows + (Vista and later) and emulate them on XP + - leaks of G(Static)Private-allocated data on some cases of thread exit + have been fixed + - simplified new thread creation API with the old API deprecated. The + concept of joinability has disappeared (all threads are joinable) as + have priority levels, 'bound'ness (ie: kernel vs. userspace threads) + and ability to manipulate the stack size. + - GThread is now a refcounted type + - other implementation details changed + +* Move headers for some deprecated functionality to a separate + deprecated/ directory. + +* New support for attribute-based deprecations to issue compiler + warnings instead of breaking the build and/or giving warnings about + implicit declarations (and possibly miscompiling). + +* GCache has been deprecated (after its last use was removed from our + platform over a year ago). + +* It is no longer possible to include individual headers (like + "ghash.h") -- you must #include . + +* The misguided experiment of allowing the program to stumble along with + missing GSettings schemas is now over -- the abort is back. + +* Clarify that fork() is not valid while using GMainContext. This is + because the internal resources of the GMainContext end up being shared + by both processes. We had an assert here but it was breaking existing + (valid) use cases as well, so it has been removed for now. + +* GApplication + - add ::shutdown signal as logical dual to ::startup + - don't use a GMainLoop: iterate the GMainContext directly (improves + quit logic) + +* Several portability fixes for Windows, OpenBSD, Solaris + +* Add new GValue API to specifically deal in signed chars (in case the + platform defines 'char' as unsigned) + +* some new API to mitigate the problems associated with calling setenv() + in a multi-threaded program + +* Use CLOCK_MONOTONIC unconditionally if the libc has support at compile + time (ie: stop checking for kernel support at runtime). + +* pkg-config files: + - drop -uninstalled variants + - remove gobject dependency on gthread + +* New macro G_ATOMIC_LOCK_FREE is defined if the atomic operations are + implemented without use of a mutex. Cleaned up atomic-related + compilation issues with mingw compilers on win32 systems. + +* SOCKS proxy and resolver improvements + +* Fix the spelling of G_IO_FLAG_IS_WRITABLE (was WRITEABLE) and + introduce a macro for backwards compatibility. + +* GDBus: + - many code generation updates and improvements + - some race condition fixes, including testcase hangs + +* GVariant: + - new g_variant_new_from_fixed_array() API + - substantial docs improvements/clarifications + +* GKeyFile is now refcounted and boxed + +* mount monitoring is now based on /proc/mounts (where available) + instead of mtab + +* new macros G_SOURCE_CONTINUE and G_SOURCE_REMOVE for returning from + GSourceFunc (so you don't have to remember what TRUE and FALSE mean) + +* use xlocale functions where available to avoid too much heavy lifting + in functions like g_ascii_strtod() + +* GMappedFile can now be created from an fd + +* error message strings grammar/i18n fixes + +* many docs updates + +* Partial list of bugs closed: + 70598 Unify GStaticMutex and GMutex. + 320888 optimization for g_main_context_wakeup + 398418 GChildWatch race condition? + 527214 g_timer_elapsed() returns random values + 580505 add a way to set/get name for a thread + 583511 race condition means g_main_loop_quit() does not work + 590808 GKeyFile should have a refcount and a boxed type in GObject + 592715 Document that g_str_hash() and g_int_hash() are not NULL safe + 631413 Add macros for GSourceFunc return values + 632049 not immediately clear what g_variant_get_fixed_array expects + 640212 "Error stating file" is not a friendly message + 640293 Use xlocale functions to implement g_ascii_strtod() + 640975 Check that error exists before trying to set it + 643934 GApplication lacking a logical dual for the ::startup signal + 651268 assertion failed in GDBus worker thread + 653987 g_key_file_get_integer cannot interpret trailing spaces + 654412 Documentation for g_variant_get_child_value unclear + 654563 info capplet: Failed to calculate disk space + 655366 missing GSettings schemas lead to obscure crashes + 656621 g_spawn_*() calls executables in current directory + 656679 [gi] Add two annotations to gio + 657992 Add glib__private__() API to share between glib,gio + 658188 _set_as_last_used_for_type generates a broken mimeapps.list + 658206 gsocks5proxy.c has invalid gettext use + 658207 glib-compile-schemas says "can not" + 658558 simpleaction: Fix documentation of :enabled + 658683 clean up charset/language threading issues + 658692 add introspection annotations to g_time_val_from_iso8601() + 658715 Duplicite strings + 658769 Invalid reuse of GError in GThreadedResolver + 658806 sign error in string hash implementation + 658976 gdbus-codegen's C namespace option needs to support Ugly_Case + 659070 gdbus-codegen generated code segfaults when property changes + 659082 gdbus-codegen: Single letter namespaces get dropped from names + 659212 GMappedFile should fail on non-regular files + 659324 _SPLICE_CLOSE_TARGET doesn't mark the output stream as closed + 659423 Use adaptive mutexes when available + 659427 Move deprecated code to a separate directory + 659646 gdbus-codegen produce code that warnings at build + 659690 Possible build warning in code generated by gdbus-codegen + 659699 property name collision when generating code for "Connection" + 659754 Add API to GMappedFile that allows to pass FD + 659838 incorrect types in introspection for g_object_bind_property + 659866 pthread_rwlock_t requires defined __USE_UNIX98 + 659870 gvalue: Fix signedness of g_value_get_char() + 659889 glib-2.29.92/gio-2.0.pc.in has a wrong line. + 659916 GObject size of 64K is not actively enforced + 659920 Missing setter for read/write property 'closed' of GIOStream + 659923 Add g_variant_new_fixed_array() function + 660013 Remove old g_atomic configure cruft + 660096 glib/rwlock tests failure (tests asserted) + 660130 Possible loss of user data when updating mimeapps.list + 660147 tracker causes g_critical in "gsettings list-recursively" + 660413 Make G_ASSERT_STATIC work with clang + 660498 Generated test code fails when the codegen changes + 660511 Use /proc/mounts for monitoring mounts, not /etc/mtab + 660536 Expose options for /etc/fstab entries + 660635 Deprecate g_thread_foreach + 660637 Pending dbus method calls not canceled on connection loss + 660739 kill off g_{mutex,cond}_{new,free}() + 660740 make GThread more standard + 660741 g_cond_timedwait is a disaster + 660743 macro wrappers for g_once_init_enter/leave + 660744 finish killing g_thread_init() + 660745 GPrivate leaks on Windows + 660791 [gio] Improve doc for g_file_make_directory_with_parents() + 660843 asyncqueue-test is broken + 660849 Remove cruft from g_strerror and g_strsignal + 660886 GDBusProxy: don't drop/complain about unknown props/signals + 660887 g_slice_set_config() is broken + 660994 Add g_main_context_ref_thread_default() + 661255 gio: enable test_peer regression test for OpenBSD + 661257 giomodules.c uses ":" instead of G_SEARCHPATH_SEPARATOR_S + 661318 tests use pthread without appropriate compiler/linker flags + 661421 Applications fail to initialize on GNU Hurd - commit + 661438 Implement G_GNUC_DEPRECATED/G_GNUC_DEPRECATED_FOR on Visual C++ + 661711 Sorting keys for GDrive, GVolume and GMount instances + 661763 desktop-app-info: Add support for X-GNOME-Keywords + 661896 /gdbus/connection/life-cycle is racy + 661914 Gstreamer/Totem locks up + 662100 regression: g_dbus_connection_close() triggers exit-on-close logic + +* Translations updates: + Belarusian + Brazilian Portuguese + British English + Bulgarian + Catalan + Catalan (Valencian) + Czech + Danish + Esperanto + French + Gujarati + Hebrew + Hungarian + Italian + Japanese + Lithuanian + Norwegian bokmÃ¥l + Oriya + Polish + Russian + Serbian + Simplified Chinese + Slovak + Slovenian + Spanish + Tamil + Vietnamese + +Overview of changes from GLib 2.29.18 to 2.29.90 +================================================ + +* API/ABI changes: + - unix signal watches now match the API of all of the other sources + - revert the addition of g_date_time_source_new () from last release + +* networking and other fixes for Solaris + - we no longer support symbolic port names (ie: from /etc/services) + - check if -lsocket is needed + - fix g_socket_details_from_fd() + - avoid getmntinfo + - fix some harmless warnings + +* GDateTime improvements: + - generally improved standards compliance (with C99) + - support C99-specified format strings: %g, %G, %V, %c, %C, %w + - consult the locale for the preferred 12-hour time format (%r) + - drop support for non-standard %N and broken %W + - better support for formatting non-POSIX (eg: Arabic) numerals + - locale-related test case fixups, and fix some leaks + +* GTlsInteraction: add interaction method invocation guarantees + +* gdbus-codegen: post-process all interfaces when parsing >1 file + +* make GMainLoop, GMainContext and GSource boxed types + +* fix a race condition in the first use of g_get_monotonic_time() + +* lots gtk-doc cleanups + +* better intltool compatibility when generating pot file + +* avoid GCC-specific compiler options when not using GCC + +* Translation updates: + Belarusian + Brazilian Portuguese + Canadian English + Galician + Indonesian + Korean + Lithuanian + Norwegian bokmÃ¥l + Portuguese + Spanish + Swedish + +Overview of changes from GLib 2.29.16 to 2.29.18 +================================================ + +* GDateTime is now respecting LC_TIME when formatting + +* GTimeZoneMonitor has been removed again + +* A new API for wallclock functionality has been added: + g_date_time_source_new(). This API is still experimental + and may be changed or removed before 2.30. + +* Bugs fixed: + 628904 Add credential support for FreeBSD and fix a socket issue + 650763 gdbus-codegen is broken with python 2.7 + 655129 GDateTime could provide api for implementing wall clocks + 656341 gtlsconsoleinteraction.c uses getpass() which isn't avail... + 656387 GCancellable can be used concurrently + 656443 Make GTlsInteraction ask_password cancellable + 656675 void functions should not return in glib 2.29.16 + 656772 g_variant_compare for uint64 incorrect + 656914 Load GIO_EXTRA_MODULES first, and ignore duplicates + 657083 The header langinfo.h is not available on all systems + 657084 gfileutils: fix docs/annotations for temp file methods + 657138 Some files missing in POTFILES.in + 657206 GInputStream leaked in g_file_icon_load_async() + 657243 g_cancellable_set_error_if_cancelled() documentation + 657274 Use detected PYTHON variable as shebang for gdbus-codegen + 657336 Speling fixes for glib found with codespell + 657452 plural forms needed + 657454 Translation comment needed + 657540 Print out file:// URL to coverage HTML report after building + 657593 g_test_trap_fork calls close(-1) + 646082 Addresses from GSocket should be normalized before returning + 657517 fix gio/tests/gdbus-peer on bsd + +* Translation updates: + Brazilian Portuguese + Galician + Norwegian bokmÃ¥l + Punjabi + Russian + Serbian + Spanish + Swedish + Traditional Chinese + Uighur + + +Overview of changes from GLib 2.29.14 to 2.29.16 +================================================ + +* GTlsDatabase: an abstract class that provides support + or certificate and key lookup. An implementation will + be provided in glib-networking + +* GHmac: Support or HMAC digests + +* Misc new API: + - g_ptr_array_add_full: creates a GPtrArray with + a preallocated size and a destroy function + - g_desktop_app_info_get_show_in: checks if a GDesktopAppInfo + should be shown in a given desktop environment + - g_mkdtemp, g_mkdtemp_full, g_dir_make_tmp: create + temporary directories + +* Unify thread wakeup implementations of GMainContext + and GCancellable, and use eventfd for it when available + +* Show mounts in $XDG_USER_DIR in addition to /media and $HOME + +* Bugs fixed: + 636572 GTlsCertificateDB + 644601 Some tests need a running dbus session + 652284 deal with small key lengths + 652827 glib-2.29.8 no longer builds with mingw.org's toolchain + 653063 PEM parser fails parsing private key when put first + 654078 Fail to static linking with Glib library + 654450 New functions: g_ptr_array_new_full() + 654793 Add G_VALUE_INIT + 655044 GDesktopAppInfo: Add g_desktop_app_info_get_show_in() + 655148 gdbusconnection is broken when compiling with mingw + 655241 glocalfile.c no longer compiles with MinGW GCC + 655598 g_cancellable_get_fd: silently return -1 for NULL cancellable + 655664 gdbus should not abort if no dbus session is available + 655769 Use ZLIB_CFLAGS when compiling gio + 656031 Improve GVariant annotations + 656048 glib-codegen requires Python >= 2.5 + 656151 configure test logic inverted, doesn't match comments + 656152 GCC only syntax used, yet other compilers allowed by configure. + 656162 allow use of lcov 1.9 for coverage + 656282 GDBusProxy: uninitialized local variables can be freed + 656283 Failing tls connection cause assertion + 118563 Add g_mkdtemp in the spirit of g_mkstemp + 636405 Add g_return_if_fail() to g_settings_bind_with_mapping() + 656039 race condition between GDBusProxy signals and public API + 656492 g_io_channel_new_file failure (open(2) behavior wrt POSIX) + +* Translation updates: + Bulgarian + Esperanto + French + Galician + German + Hebrew + Indonesian + Italian + Norwegian bokmÃ¥l + Russian + Spanish + Swedish + + +Overview of changes from GLib 2.29.12 to 2.29.14 +================================================ + +* Unicode improvements + - add g_unicode_script_{to,from}_iso15924 + - add G_UNICODE_SPACING_MARK define + - more normalisation improvements + - stop using deprecated g_unicode_canonical_decomposition() + +* GParamSpec: + - mark the 'name' field as 'const' and add a comment to the header to + help avoid future problems caused by bad hacks + +* Merge some (modified) patches from Debian: + - 03_blacklist-directories.patch + - add some blacklisted mount directories + - 60_wait-longer-for-threads-to-die.patch + - sleep longer in a test case, if needed to avoid failing + +* Units policy change: prefer use of SI units + - deprecate g_format_size_for_display, add g_format_size(_full) + +* GSettings: don't call g_error() when the schema is missing + +* GVariant support for arrays of object paths: + - new g_variant_{new,get,dup}_objv API + - support for g_variant_{new,get} '^ao' and '^a&o' similar to '^as' + +* GDBus: + - use new improved array-of-objects support and pass 'ao' as char** + instead of GVariant* + - improve handling of 'h' type (Unix file descriptor index) + +* GIO: + - fix compilation without USE_STATFS and USE_STATVFS + +* Documentation fixes + +* Bugs fixed: + 622921 Migrate from dbus-glib to glib's GDBus + 648271 Add g_unicode_script_to_iso15924() + 654948 Stop using deprecated g_unicode_canonical_decomposition() + 654988 g_atomic_int_add should document behaviour change + 655025 #define G_UNICODE_SPACING_MARK G_UNICODE_COMBINING_MARK + 655076 normalization misses some Full_Composition_Exclusion=True. + +* Translations updated: + Spanish + +Overview of changes from GLib 2.29.10 to 2.29.12 +================================================ + +* Add new API to do Unicode (de-)composition in atomic steps, + for use in Harfbuzz. + +* Bugs fixed: + 615895 (indirectly) support non-NULL-terminated regexes in GRegex + 617949 glib trunk fails to compile on Solaris w/ Studio 12... + 620423 Document the possibility to unset attributes + 627974 Floating reference headaches + 644687 Not finding cross-links in current doc set + 649246 g_output_stream_splice() cannot be used on 32-bit machines... + 653841 a helper script to build glib from git master on win32 + 653935 g_slist_free_full/g_list_free_full iterates twice in the list + 654017 tests: fix glib_translations_work() in gsettings unit test + 654085 Don't needlessly use "echo -e" when creating .def files + 654195 Add g_unichar_compose() and g_unichar_decompose() + 654232 GCancellable eventfd problems + 654394 suspicious use of floating references in GDBusInterfaceSkeleton + 654536 GSettings: lift key name length restriction to 64 + 654627 GParamSpec: intern property names + 654651 Better g_unicode_canonical_decomposition() + 654917 Make g_cclosure_marshal_generic the default signal handler + +* Translation updates: + Belarusian + Finnish + Korean + Latvian + Lithuanian + Norwegian bokmÃ¥l + Turkish + + +Overview of changes from GLib 2.29.8 to 2.29.10 +=============================================== + +* New features: + - g_desktop_app_info_get_nodisplay: a function that is required + to port gnome-menus to GDesktopAppInfo + - g_hash_Table_iter_replace: new function to replace a value + while iterating over a hash table + - g_utf8_substring: convenience API to extract substrings from + UTF-8 strings + - g_action_group_add_entries: convenience API for creating lots + of actions quickly + - Use eventfd instead of pipes for waking up main contexts and + for cancellation when available + - GMatchInfo is now a refcounted boxed type + +* API changes in GAction: + - the 'set_state' entry in the GActionInterface vtable has been + renamed to 'change_state + - g_action_set_state has been renamed to g_action_change_state + - the 'state' property has been changed to read-only + - GSimpleAction can no longer be subclassed + +* Bug fixes + 647796 g_variant_new_variant is not marked as constructor + 652072 gmain: make use of signalfd() + 652168 Crosscompiling Fails if build<=2.24 and host >2.24 + 652750 make dist fails + 652758 GDataInputStream: Clarify g_data_input_stream_read_line docs... + 652822 Add a g_hash_table_iter_replace + 652897 tiny docs clarification for g_utf8_to_ucs4_fast + 653140 gmain: use Linux eventfd() for main context wake up + 653429 drop AM_MAINTAINER_MODE or enable it by default + 653484 GAsyncCallbacks should default to allow-none + Add missing fundamental types to the generic marshaller + +* Translation updates + Belarusian + Galician + Russian + +Overview of changes from GLib 2.29.6 to 2.29.8 +============================================== + +* Bug fixes + 646608 export_symbols variable for gio dynamic library is wrong + 646635 Fix introspection of GLib + 647930 Documentation: GDataInputStream _read_upto() version + 651745 Switch to _ prefixing rather than G_GNUC_INTERNAL + 651920 Improve qsort_r detection + 651959 gbitlock: "asm goto" is not available in gcc < 4.5 + 651998 gdbus-codegen: Use relative Python imports + 652000 Fix for gatomic.c on Windows/MSVC + 652002 Proposal to clean up gvaluetransform.c for MSVC + 652025 g_dbus_connection_register_object: error is not set... + 652081 Typos in a GBinding warning message + 652197 Improper handling of double values in GDBusMessage + Fix a deadlock in gobject finalization + +* Translation updates: + Czech + Galician + German + Hebrew + Norwegian bokmÃ¥l + Spanish + Uighur + + +Overview of changes from GLib 2.29.4 to 2.29.6 +============================================== + +* Atomic operations have been rewritten from scratch to make use + of gcc builtins where possible. As a side-effect of this, calls + to g_atomic_ API with explicit casts may now be problematic; if + that happens to you, try first to remove the casts. Another + side-effect of the rewrite is that g_atomic_int_exchange_and_add + has been deprecated in favor of g_atomic_int_add. + +* A full set of atomic operations on pointers has been added, + including bit locks in pointer-size locations. + +* Access to quarks is now lockless + +* GObject data scalability has been greatly improved + +* g_data_time_format now supports alternative digits and padding + +* Introspection improvements: + - Add a boxed type for GVariantBuilder + - Annotation fixes in GDBus, GVariant, g_base64_ + +* Bugs fixed: + 502560 g_rand_double_range returns 'inf' + 612729 g_mkdir_with_parents can fail if the directory already exists + 617491 g_once() implementation is inefficient + 619418 Add a performance test for UTF-8 decoding functions + 619435 Make g_utf8_to_ucs4_fast() yet faster + 626549 G_STATIC_ASSERT_EXPR + 631231 bitlock: Fix detection and usage of futexes with Bionic + 632294 g_queue_remove() should return a boolean + 640518 GMainLoop has quadratic complexity when all pollfd's... + 642026 Race condition in g_static_private_free + 646635 Fix introspection of GLib + 648678 g_date_time_format(): support %O flags for localized numbers + 649480 Use MSG_CMSG_CLOEXEC in recvmsg in gio/gsocket.c + 649506 GTestFunc et al lacking Since tag + 649657 Don't return gboolean for functions that throw + 649775 glib-gio-gdbuscodegen-Makefile.patch + 649915 gsettings accepts unquoted strings longer than two characters + 649973 gthread: build unix tests only on unix + 649988 gdbus-codegen: Drop dependency on argparse + 650078 forkbomb building glib/tests/protocol + 650211 Optimization in key file parsing + 650236 Application over DBus implements action state incorrectly + 650345 g_key_file_has_key_full: New function to fix g_key_file_has_key... + 650458 reduce overhead in g_object_set/get_data + 650459 hash table consistency while calling destroy notify funcs + 650688 enforce rules about hash table modification + 650823 expand the set of atomic ops + 650874 codegen chokes on docs + 650882 use stdout instead of stderr for informational messages + 650884 fix compilation with gcc2 + 650885 implement glib credentials on OpenBSD (hackish) + 650935 G_GNUC_MAY_ALIAS and atomic ops + 651009 minor documentation fix + 651034 Regarding g_cond_wait after g_thread_pool_push in gthreadedresolver + 651133 race condition in GDBusConnection's emit_signal_instance_in_idle_cb + 651141 hashtable infinite loop + 651219 fix path to true(1) on OpenBSD + 651223 Fix some compile warnings on OpenBSD + 651327 Minor fixes for the gsocket API + 651467 Add pointer sized bitlocks + 651650 gdbus: Avoid busy wait loop + 651725 gmain: Cleanups and a new test case + 651745 Switch to _ prefixing rather than G_GNUC_INTERNAL + +* Updated translations: + Catalan (Valencian) + Esperanto + Hebrew + Hungarian + Russian + Spanish + + +Overview of changes from GLib 2.29.2 to 2.29.4 +============================================== + +* GDBus: + - Includes several new types to support modeling D-Bus + objects and interfaces more fully, and also introduces + an 'object manager' pattern: + GDBusInterface, GDBusObject, GDBusObjectManager + These interfaces have client-side implementations: + GDBusProxy, GDBusObjectProxy, GDBusObjectManagerClient + And server-side implementations: + GDBusInterfaceSkeleton, GDBusObjectSkeleton, GDBusObjectManagerServer + - The new gdbus-codegen utility uses these new classes + to generate C code and documentation from D-Bus interface + descriptions in XML + +* GTest: + - There is now a g_test_fail() function to mark + tests as failed + +* GDesktopAppInfo + - Now has a binding-friendly filename property + - Other new API to more fully expose desktop file contents: + g_desktop_app_info_get_categories(), + g_desktop_app_info_get_generic_name() + +* GHashTable: + - Several optimizations to reduce space consumption of + large hash tables, in particular tables that are used + to store sets. + +* Unix-specific APIs: + GLib now installs a separate header, glib-unix.h, that is + meant to collect Unix-specific APIs. For now, it contains + g_unix_open_pipe(), g_unix_set_fd_non_blocking() for dealing + with pipes and fds, as well as APIs to create mainloop + sources which can trigger callbacks on certain Unix + signals (SIGTERM, SIGHUP, SIGINT). + +* Bugs fixed: + 631379 GDBus nonce-tcp test failing + 632631 GLib-CRITICAL **: g_variant_new_string: assertion `g_utf8_validate (string, -1, NULL)' failed + 635694 gdbus aborting due to unauthorized socket in DBUS_SESSION_BUS_ADDRESS + 637561 Crash when using G_DBUS_SERVER_FLAGS_RUN_IN_THREAD + 642935 g_date_time_format() prints wrong value for %z and timezone -0800 + 643134 g_dbus_message_copy + 644941 glib-unix: New Unix-specific API + 646013 g_hash_table_remove_all_nodes optimization + 646309 glib cannot be cross-compilled for mingw32 + 646435 GTimeZone doesn't seem to be thread-safe + 646957 GIO chained calls don't work with a thread default context + 647594 README link to mailing list is broken + 647602 Cannot connect to remote message bus via TCP + 647746 The GSocketService documentation is incomplete. + 647826 API: gtester: Add g_test_fail() + 647903 GDesktopAppInfo: Add g_desktop_app_info_get_categories() + 648416 g_app_info_create_from_commandline ignores SUPPORTS_STARTUP_NOTIFICATION + 648423 Support G_DEBUG=trap-warnings + 648425 GDesktopAppInfo: Add "filename" property for bindings + 648966 Update g_unichar_iswide and g_unichar_iswide_cjk + +* Updated translations + Norwegian bokmÃ¥l + Spanish + Turkish + Uighur + + +Overview of Changes from GLib 2.28.0 to 2.29.2 +============================================== + +* GApplication + - The documentation has been enhanced and clarified + - An opt-out for uniqueness has been added: G_APPLICATION_NON_UNIQUE + - GApplication now syncs settings before g_application_run() returns + +* GDBus + - Interface lookups are now happening in constant time + - Signature checking and handling of various unexpected + situations has been improved + +* GVariant + - The format accepted by the GVariant parser has beend documented + - GVariant accepts G_VARIANT_TYPE_VARDICT for a{sv} + +* GDateTime: + - The return value of g_datetime_compare() has been fixed to + match strcmp() semantics + - In order to handle problems with changing timezones, a GTimeZoneMonitor + has been added to GIO, and g_time_zone_refresh_local() can be + called to update the cached information about the local timezone + +* GOption now uses /proc/self/cmdline to set the program name instead + and only falls back to "" if that is unavailable + +* GSettings: + - The schema compiler now warns about references to non-existing schemas + +* Commandline utilities are now fully translated + +* Signals can now indicate that collecting their arguments must + always happen, even in the absence of connected signal handlers, + using the G_SIGNAL_MUST_COLLECT flag. + +* Bugs fixed: + 635099 Memory leak in gdbus introspection when parsing xml + 640489 $ and ^ do not match lines if G_REGEX_MULTILINE|G_R... + 642042 Overriding GDBus org.freedesktop.DBus.Properties im... + 642052 g_timeout_add(_seconds) cannot handle large intervals + 642490 notify_desktop_launch() "g_variant_new_bytestring:... + 613269 g_type_get_qdata() doesn't work as I expected on subtypes + 624943 G_VALUE_NOCOPY_CONTENTS is undocumented + 637738 object_interface_check_properties never actually executes + 638185 GIOCondition should be annotated as "flags" + 639478 GDBusServer's g_dbus_server_new_sync() function should just... + 641755 Add g_settings_get/set_uint() helpers + 641768 dconf gsettings backend silently drops writes if it can't... + 642797 g_app_info_get_default_for_type() broken for subtypes + 642825 Unnecessary assertion failure in g_option_context_parse() + 642944 NULL key lookup using g_hash_table_lookup_extended() + 643074 Incorrect documentation for g_socket_receive() and g_socket... + 643197 g_application_id_is_valid docs imply no valid ids + 643468 GApplication docs: Warn that handling "command-line" means... + 643478 GApplication::local_command_line vfunc documentation seems wrong + 643624 Can g_variant_unref() on an already free'd variant + 643649 g_application_run() should say that argc/argv can be NULL + 643780 shouldn't need to create an action group to use actions... + 643795 g_timeout_add_seconds fires with intervals 1 second longer... + 644309 Program name is not set when using GtkApplication + 644428 Crash in failure section of g_markup_collect_attributes() + 644465 undefined reference to `_usleep' + 644552 g_timeout_add_seconds(1, ...) may have a latency of up to 2... + 644607 Correct internal definition of C_() + 645789 annotations for g_file_*_contents + 646039 g_settings_list_children() returns child that cannot be opened + 646310 Accept range with only min or max + 646420 g_dbus_method_invocation_get_parameters() docs should say... + 646843 occasional abort on autologin + 646985 add G_APPLICATION_NON_UNIQUE flag + 647579 gsettings: Implement reset-recursively + 647600 gsettings description has typo + +* Translation updates + Afrikaans + Bulgarian + Bengali India + British English + Bulgarian + Catalan + Czech + Danish + French + Galician + German + Greek + Gujarati + Hebrew + Hungarian + Italian + Japanese + Korean + Lithuanian + Polish + Portuguese + Romanian + Serbian + Simplified Chinese + Spanish + Swedish + Traditional Chinese + Uighur + Vietnamese + + +Overview of Changes from GLib 2.27.93 to 2.28.0 +=============================================== + +* Bugs fixed: +641363 GInitable documentation isn't clear about that finalize... +641395 Add more data about the origin application to the "Lau... +641411 gdesktopappinfo signals lost if it's the session bus... +641477 glib-mkenums uses unportable #! line +641572 Add @EXEEXT@ to pkgconfig binary name +641688 glib installs GSettings.html and gsettings.html + +* Translation updates: + Galician + Italian + Korean + Punjabi + + +Overview of Changes from GLib 2.27.92 to 2.27.93 +================================================ + +* Bugs fixed: + 637013 gio/gdbusmessage.c fails to compile on Solaris + 640192 Error creating a Gio.Settings object through py... + 640261 Minimum version for external pcre needs to be.. + 640262 GActionGroup contains redundant TYPE macros + 640436 Make load_user_special_dirs() resistant to non... + 640695 g_key_file_load_from_file() mishandles a CR-LF... + 640724 can't compile gio due to format string issues + 640725 can't compile tests due to format string issue + 640807 improve GVariant behaviour with invalid pointers + 640823 wrong documentation for g_source_add_child_source + +* Translation updates: + Bulgarian + Galician + Hebrew + Norwegian bokmÃ¥l + Spanish + Traditional Chinese + + +Overview of Changes from GLib 2.27.91 to 2.27.92 +================================================ + +* Update to Unicode 6.0 + +* Update PCRE to 8.12 + +* Bugs fixed: + 637696 g_unix_connection_send_fd() doesn't work + 638872 null settings backend bug + 640042 GtkApplication's warning about not connecting... + +* Translation updates: + Arabic + Basque + Estonian + Greek + +Overview of Changes from GLib 2.27.90 to 2.27.91 +================================================ + +* Bugs fixed: + 638838 gdesktopappinfo: Don't crash if we don't have a desktop filename + 638894 Splitting on \s* gives no result + 639064 Update gschema.dtd + 639084 Copy/paste error in GSettings::writable-changed signal + 639177 SIGSEGV for GApplications with G_APPLICATION_IS_SERVICE + +* Translation updates: + Estonian + Galician + Indonesian + + +Overview of Changes from GLib 2.27.5 to 2.27.90 +=============================================== + +* Test reports created by gtester-report can now + include revision information + +* The g_desktop_app_info_launch_* family of functions + now emit a DBus signal when an application is launched. + Additionally, there is a new variant + g_desktop_app_info_launch_uris_as_manager(), which + gives more control over the launched process. + +* The memory and null GSettings backends are now available + as public API + +* g_get_locale_variants() is a new function that returns a + list of variants of a locale identifier + +* Bugs fixed: + 587898 I/O timeouts for GSocket + 606960 gio: Add extension point for informing parties... + 631980 Handle an optional node in the report... + 634569 Document that g_variant_builder_add_value consumes... + 635998 Make _g_compute_locale_variants public + 636806 Add g_{memory,null}_settings_backend_get_default + 637262 Need a binary DER version of ::accepted-cas + 637544 Skip fsync() on btrfs + 637720 void functions should not return a value. + 637738 object_interface_check_properties never actually... + 637759 GIOChannel: fix a crash in g_io_channel_read_chars() + 637852 Updates to glib.vsprops file for MSVC 2008 builds... + 637858 Updates to test/testglib.c... + 638349 parameter name of g_variant_new_* may conflict... + +* Translation updates: + Hebrew + Norwegian bokmÃ¥l + Simplified Chinese + Spanish + Swedish + Uyghur + Vietnamese + + +Overview of Changes from GLib 2.27.4 to 2.27.5 +============================================== + +* Network support: + - Add g_tls_certificate_verify() to verify a certificate + - Add GTlsConnection:use-system-certdb + - Other TLS api additions + +* GIO: + - Add g_io_stream_splice_async()/_finish() to splice two iostreams + - Add g_emblemed_icon_clear_emblems() and make GEmblemedIcon derivable + - Remove GPeriodic; it did not receive the necessary review and + integration work to declare it stable + +* GSequence: + - New methods g_sequence_lookup() and g_sequence_lookup_iter() + +* Bugs fixed: + 617254 Missing g_sequence_lookup + 632544 g_dbus_connection_send_message can not send a locked message... + 633350 g_hostname_to_ascii() ignores non-ascii dots + 634583 Better error reporting for g_variant_parse() + 635007 gsetting enum rule don't work for out-of-srcdir builds + 635626 GDBus message idle can execute while flushes are pending + 636100 Can't read GSettings:backend property + 636305 Typo on g_queue_remove_all() function description + 636311 appinfo: tweak application positioning for content-types + 636351 g_simple_async_result_is_valid lacks a version tag + 636387 gdb autoload files shadow the "dir" builtin + 636673 g_simple_async_report_error_in_idle should allow object... + 637147 Add a "delay-apply" property to GSettings + 637171 emblemedicon: add g_emblemed_icon_clear_emblems() + 637237 gapplication: plug a memory leak + +* Translation updates: + Estonian + Galician + Hebrew + Norwegian bokmÃ¥l + Simplified Chinese + Spanish + Traditional Chinese + Vietnamese + + +Overview of Changes from GLib 2.27.3 to 2.27.4 +============================================== + +* GIO + - Mounts are treated as hidden if they have a path element + that starts with a dot + - GAppInfo gained API to differentiate between recommended + and fallback mime handlers + - g_cancellable_create_source: creates a GSource that triggers + when the GCancellable is canceled + - GPollableInput/OutputStream: Interfaces for pollable streams + - TLS support has landed, with an extension point that is + implemented in glib-networking + +* GLib + - Mainloop sources can now have 'child sources' + - g_get_runtime_dir: New function to return the XDG_RUNTIME_DIR + +* Bugs fixed: + 530786 GFileMonitor "changed" signal underdocumented + 588189 TLS support for GSocket* + 630357 g_object_new_valist uses uninitialized memory + 630559 typo in public string in gsocks: 'The SOCKSv5 require... + 632445 Documentation refers to removed GNOME 2.0 porting guide + 634239 Child GSources + 634241 Add pollable input/output streams + 634504 allow passing a NULL emblem to g_emblemed_icon_new() + 634613 unsufficient g_get_user_runtime_dir() documentation + 635640 schema should inherit gettext-domain from schemalist + 635768 Protect g_file_monitor_set_rate_limit() against negative... + 635882 Fix the wrong-category schema test + 635187 Wrong type of GVariant received in an action... + +* Updated translations: + Galician + Italian + Norwegian bokmÃ¥l + Uyghur + + +Overview of Changes from GLib 2.27.2 to 2.27.3 +============================================== + +* The GTimeSpec type that was introduced in the 2.27.2 has been + dropped again in favour of APIs that return microseconds as + 64-bit integer. + Affected functions: + g_source_get_time + g_periodic_unblock + g_get_monotonic_time + g_get_real_time + The similar GTimeVal struct is still around, but its use is + discouraged. + +* GTimer is now using monotonic time unconditionally + +* There are some new functions to facilitate error reporting + in async GIO APIs: + g_simple_async_result_take_error + g_simple_async_result_new_take_error + g_simple_async_report_take_gerror_in_idle + +* There is new convenience API to us GVariant dictionaries: + g_variant_lookup + +* It is now possible to delay sending match rules to the + D-Bus daemon in GDBus: + G_DBUS_SIGNAL_FLAGS_NO_MATCH_RULE + +* Support has been added for XDG_RUNTIME_DIR: + g_get_user_runtime_dir + +* Various fixes for Win64/MSVC builds have been committed + +* Bugs fixed: + 620263 Add g_clear_object, g_clear_pointer, g_clear_boxed + 633075 update Project Files and sources for MSVC 2008/C89 + 633381 gsettings Makefile rules should handle empty list... + 633685 Use g_simple_async_result_{new_,}take_error + 633686 Add g_simple_async_report_take_gerror_in_idle + +* Translation updates: + Belarusian + Galician + Hebrew + Punjabi + Spanish + + +Overview of Changes from GLib 2.27.1 to 2.27.2 +============================================== + +* GApplication + - Export actions over DBus and support activating them from remote instances + - Support environment passing + +* GSettings + - The gsettings utility has a list-recursively command + - The gsettings utility has commandline completion for enum values + +* GLib is now linked against librt and uses monotonic time for + timeouts and GPeriod sources. GSource has a new g_source_get_time() + which returns monotonic time, and g_source_get_current_time() has + been deprecated + +* Bugs fixed: + 158725 free linked list with data + 626320 GVariant: Avoid locking in g_variant_get_child_value() if possible + 629247 add gsimpleasyncresult methods to take over a GError + 629274 GNetworkService does not do fallback when there is no SRV record + 631264 gsettings-tool choice/range support + 631482 g_date_time_from_instant: 1000000000000000000 + 632169 docs for manual use of gsettings-data-convert + 632571 Add equivalent to gconftool-2's -R option + 633115 GSettings m4 doesn't fail the build for broken schemas + 633206 Default g_application_local_command_line() doesn't set exit_status... + 633339 support more complex gapplication setups + 633356 Make timeout G_MAXINT mean "no timeout" + +* Translation updates: + Catalan (Valencian) + Indonesian + Japanese + + +Overview of Changes from GLib 2.27.0 to 2.27.1 +============================================== + +* GDateTime now has full week number support. + New API: g_date_time_get_week_numbering_year + +* The GSettings schema compiler will now skip over + broken .xml schema files instead of aborting altogether + +* GSettings now works properly on bigendian systems + +* GSettings has more complete support for ranges + New API: + g_settings_get_range + g_settings_range_check + The gsettings commandline tool supports ranges too. + +* GApplication has been rewritten; see the API docs for details + and examples. The action support is not complete yet. + +* The GLib mainloop has gained 'dispatch to context' functionality, + which can replace manually created idles in many cases. + New API: + g_main_context_invoke + g_main_context_invoke_full + +* The gio-desktop-app-info-lookup extension point has been + removed from GIO. GIO now uses x-scheme-handler mimetypes when + looking for default applications. + +* On win32, make g_get_user_data_dir() return the CSIDL_LOCAL_APPDATA + folder on Windows, and not CSIDL_PERSONAL. This matches what Qt does, + and has been widely requested. Also make g_get_user_config_dir() return + this and not the (roaming) CSIDL_APPDATA folder. + +* A periodic event clock has been added in GIO: GPeriodic. Note that this + API is still experimental and expected to undergo changes before it + will be incorporated into a stable GLib release. Use at your own risk. + +Bug fixes: + 613822 gobject signal connect/disconnect not thread safe + 618737 "dispatch to context" functionality + 620710 g_get_user_data_dir() uses CSIDL_PERSONAL and not CSIDL_APPDATA + 623400 acquire context before dispatching + 627126 gsettings schema files don't get installed on FreeBSD + 627171 g_socket_new_from_fd() doesn't set the right protocol + 628876 Wrong error description + 628937 gracefully handle broken schemas + 629274 GNetworkService doesn't fallback when there is no SRV record + 629289 g_error() used wrong, produces core dump + 629687 leaks class refcount in gsocketcontrolmessage + 629849 GLib-CRITICAL **: g_source_get_context: assertion `!SOURCE_... + 629945 GDBus deadlock in g_bus_get_sync() + 630000 g_date_time_difference + 630077 GDateTime week number support + 630185 Allow NULL strings in g_quark_try_string() + 630797 docs mention non-existent g_object_dispose() + 630968 gschema-compile problems on power g5 + 631263 GSettings needs range/choice APIs + 631264 gsettings-tool choice/range support + 631379 GDBus nonce-tcp test failing + 631410 Port gapplookupgconf.c to using x-scheme-handler/ + 632884 Possible deadlock in g_object_remove_toggle_ref() + +Transation updates: + Basque + Brazilian Portuguese + British English + Bulgarian + Czech + Dutch + Estonian + French + Galician + German + Greek + Hebrew + Hungarian + Japanese + Lithuanian + Polish + Portuguese + Romanian + Simplified Chinese + Slovenian + Spanish + + +Overview of Changes from GLib 2.25.15 to GLib 2.27.0 +==================================================== + +Build: + - massive restructuring to reduce #include abuse + - tweaks to silence some harmless compiler warnings + - rename gschema-compile.c to glib-compile-schemas.c + - Windows fixes + - fix building with zlib < 1.2.4 on win32 + +GDateTime: + - better msgctxt for translating month and weekday names + - API is changed quite a lot, implementation is improved + - GTimeZone is now exposed + +GObject: + - make ordering for overridden interface properties consistent + - ->priv structures are limited to 64k but this was not documented, + and exceeding this limit produced bad results. Add docs and enforce + the limit properly. + - add g_object_class_install_properties() to install multiple + properties in one go + - improve debugging output for GValue containing G_TYPE_STRV + +GIO: + - fix priority sorting of GIO extensions + - add GCredentials support on FreeBSD + - fix support for IPv6 addresses in URI parsing functions + - GSocketClient fixes for when g_socket_connect succeeds immediately + - clarify string encoding for GFile constructors in docs + - new functions g_data_input_stream_read_upto{,async,finish} + - tweak confusing documentation for g_output_stream_write() + +GDBus: + - GDBusMessage can now be locked and copied (like in libdbus) + - GDBusConnection filter function API has changed again + - GDBusServer: ::new-connection now declares if the connection was claimed + - add a partial workaround for GObject bug 627724. + - very many memory leaks fixed + +GVariant: + - check for size == 0 in g_variant_get_bytestring to avoid a crash + when attempting to get_bytestring() from an empty array + - improve gobject-introspection annotations + +GSettings: + - add GSettings Windows registry backend + - some internal tweaks to the backend API + - remove g_settings_list_items + - add g_settings_list_children and _list_keys to replace it + - add schema compiler restrictions for dealing with lists + - don't automatically emit value changed signals on writability + changes + +Other: + - constify the 'parser' vtable param to g_markup_parse_context_push() + - plug many memory leaks in test cases + +Bugs closed: + 50076 Time API to go with date API + 584284 g_data_input_stream_read_until_async different from sync version + 624546 Modification of GDBusMessage in filter function + 626919 Let g_object_class_install_property() return the installed GParamSpec* + 628029 GDateTime missing get_week_of_year method + 628253 Interface properties not listed in a consistent order + 628331 Plug lots of mem leaks in gio test suite + 628345 Plug a mem leak + 628436 Plug a mem leak + 628505 Fix building with zlib < 1.2.4 on win32 + 628839 [PATCH] datetime: Rename shadowing variables + 628904 [PATCH] Add credential support for FreeBSD and fix a socket issue + 628952 incorrect glib_major_version and other variables on cygwin. + 629192 g_strdup_value_contents(): dump GStrv more usefully + 629251 g_socket_client_async_connect_complete: assertion failed + 629259 Failed to connect to "::1" + 629328 g_markup_parse_context_push doesn't respect const structs + 629429 month "May" short and full form same with "GDateTime" msgctxt + 629689 GDBusConnection leaks its GCredentials + 629698 Segfault in g_variant_get_bytestring() + +Updated translations: + Arabic + Armenian + Basque + British English + Czech + Finnish + Galician + German + Hungarian + Indonesian + Japanese + Lithuanian + Norwegian bokmÃ¥l + Polish + Portuguese + Punjabi + Simplified Chinese + Slovenian + Spanish + Swedish + Swedish + Traditional Chinese + +Overview of Changes from GLib 2.25.14 to GLib 2.25.15 +===================================================== + + * GIO + - Memory leak fixes + - The GZip(De}Compressor can now process header information + - Support for network proxies has been added, with the GProxy + interface and the gio-proxy-resolver extension point. GIO + includes SOCKSv4 and SOCKSv5 implementations, and libproxy + is also going to provide an implementation of this extension + point. + - There are GAction and GActionGroup interfaces now, which will + be used in GApplication in the near future. + + * GObject + - There are now convenience macros for defining boxed and + pointer types + + * GDBus + - Memory leak fixes + - GDBusProxy for well-known names can now auto-restart + the service if the name owner disapperas + - Filter functions are now allowed to modify messages + + * GLib + - GDateTime is a replacement for GDate that supports time + and timezone information. + + * Bugs fixed: + 50076 Time API to go with date API + 449565 Add G_DEFINE_BOXED_TYPE() + 617691 Add GZIP header processing to GZlibCompressor/GZlibDecompressor + 622184 add g_memory_output_stream_steal_data + 624546 Modification of GDBusMessage in filter function + 627088 Build failure in gdbus-peer.c on FreeBSD + 627181 save a memdup + 627182 Plug a mem leak in the gdbus-connection test + 627187 Plug some gdbus mem leaks + 627188 gdbus-non-socket test occasionally fails + 627252 G_OPTION_FLAG_NO_ARG is only for callback options + 627392 gdbus commit 8a3a4596 breaks win32 compile + 627407 FTBFS on !linux UNIX platforms + 627604 String error: 'that' twice in a row + 627969 ABR in g_file_open_tmp + 628084 gdbus-peer fails with assertion + 628193 Miscellaneous string fixes + 628296 abort() in gsocketconnection.c + 628309 Plug a mem leak in GConverterOutputStream + 628317 GEmblemedIcon:equal implementation is buggy + 628323 Fix invalid reads + 628327 Plug a mem leak + 628328 Plug a mem leak + 628329 Don't leak the FD list + 628324 Invalid reads in gdbus-export test + + * Updated translations: + British English + Danish + Galician + Hebrew + Punjabi + Serbian + Spanish + Traditional Chinese + + +Overview of Changes from GLib 2.25.13 to GLib 2.25.14 +===================================================== + +* GDBus + - Make the closure variants of GDBus apis work + - Make error unregistration work + - Use async IO in the IO thread (626748) + +* GIO + - Make g_simple_async_result_is_valid work without source (626208) + - GSocketClient: add a timeout property + - Fix memory leaks in GSocketClient + - Handle async vs. sync correctly in GSocketConnection stream (616458) + - Declare stream base classes as abstract + - Clarify semantics of g_output_stream_write() (627071) + +* Other + - Improve test coverage for GDBus, GRegex, GAsyncResult + - Drop dead code in pcre, xdgmime + - Fix a race condition in gtester (578295) + - Avoid an extra allocation in GAsyncQueue (626704) + - Add test case for non-socket GIOStream (626841) + - More explicit GVariant docs (622770) + - Imroved docs for GAsyncInitable and GSimpleAsyncResult (602417) + +* Translation updates: + - Galician + - Norwegian bokmÃ¥l + - Punjabi + - Simplified Chinese + - Swedish + + +Overview of Changes from GLib 2.25.12 to GLib 2.25.13 +===================================================== + ++-------------------------------------------------------------------+ +| WARNING: There have been no breaks in API or ABI. Weird, eh? | ++-------------------------------------------------------------------+ + +The primary purpose of this release is to fix a serious problem with +glib 2.25.12: glibconfig.h (as generated on a Fedora amd64 system) was +being distributed in the tarball. It was being used to build some parts +of glib on other systems (eg: 32bit ones). This was causing some very +serious problems. + +There have been many other improvements, however: + + Build and testing: + - vastly improved test coverage + - old tests moved to the gtester framework + - gtester Makefile modified so that the tests only run once + - cleanup of how we handle includes while building glib + + GVariant: + - add a g_return_if_fail (utf8) to g_variant_new_string() + + GDBus: + - perform extra sanity checks when serialising messages + - add API to query and set the byteorder of a GDBusMessage + - improve debug output, add some extra options + - if exiting due to the bus disconnecting us, print an error message + explaining why + - sort property names correctly + - don't bother sending RemoveMatch when we will close the connection + anyway + - use effective uid/gid for credential passing + + GSettings: + - add G_SETTINGS_BIND_INVERT_BOOLEAN for inverting boolean bindings + without mapping functions + - mark all strings in the schema compiler for translation + + Binding: + - improve closure support for bindings + - copy GSettings INVERT_BOOLEAN flag + + Other: + - fix another complicated GCancellable deadlock possibility + +Bugs closed: + 599590 glib build doesn't look for correct pkg-config + 619026 avoid warning in gutils.h when using gcc with -Wconversion + 624739 Please fix POTFILES.in + 625472 Valgrind claims uninitialized bytes used + 625500 g_date_set_time_val documentation doesn't mention local time + 625628 GDBusProxy: wrong property name sorting + 625753 Incorrect flags used in g_dbus_connection_call_sync() + 625827 Expand documentation about error quark naming + 625988 builddir != srcdir issues + 626107 glibconfig.h is being disted + +Updated translations: + French + Galician + Hebrew + Norwegian bokmÃ¥l + Spanish + + +Overview of Changes from GLib 2.25.11 to GLib 2.25.12 +===================================================== + ++-------------------------------------------------------------------+ +| WARNING: There have been many API changes in GDBus -- sending | +| messages, subscribing to signals, closing connections and | +| registering subtrees are affected. The ABI for GSettingsBackend | +| has also been changed. For both reasons, a new dconf release is | +| required (and will be along soon). | ++-------------------------------------------------------------------+ + +Build: + - cleanup automake setup + - rename configure.in to configure.ac + - various docs fixups + - move glibconfig.h to glib/ + - disable dtrace support on Mac OS (which has incompatible 'dtrace') + +GSettings: + - add support for vendor override files (to change the default values + in a schema) + - change GSettingsBackend vtable + - add g_settings_reset() + - support binding to G_TYPE_STRV properties + +GDBus: + - many bug fixes, including a serialisation fix + - stop handling incoming connections as soon as stop() is called + - proper support for file descriptor passing + - new flags parameter for sending messages + - new flags parameter for subscribing to signals + - always reset the message serial when sending a message unless + G_DBUS_SEND_MESSAGE_FLAGS_PRESERVE_SERIAL is given + - constness fixes for introspection structures + - clean ups to subtree registration API + +Other: + - fix divide by zero bug in g_malloc_n functions + - GIO: don't blindly assume that SOCK_CLOEXEC is supported + - make GObject property notify freezes threadsafe + - GIO: clean up credentials passing + - GApplication: make default-quit not apply if register=FALSE + - GIO: add annotations for gobject-introspection + +Bugs closed: + 166020 use GAtomic for refcounting + 617483 Credentials passing + 622005 [GApplication] no way to modify the "default-quit" property + 623293 vendor override files + 623810 Message serialization bug + 623815 Don't check sender for GDBusProxy objects where name is not set + 624473 GDBusSubtreeIntrospectFunc return type + 624483 GDBusSubtreeEnumerateFunc clarification + 624484 GDBusSubtreeDispatchFunc clarification + 624754 gdbusaddress.c missing sys/wait.h + 624968 div by zero in g_malloc_n family + 624991 GSettings mapping for G_TYPE_STRV + 625383 Add missing GI annotations + +Updated Translations: + Armenian + Galician + German + Hebrew + Kazakh + Romanian + Simplified Chinese + Spanish + +Overview of Changes from GLib 2.25.10 to GLib 2.25.11 +===================================================== + ++-------------------------------------------------------------------+ +| WARNING: There have been minor API changes in GDBus and GVariant. | +| These API changes will not affect many users, but they do require | +| a new version of GTK+ to be installed. | ++-------------------------------------------------------------------+ + +Build: + - add a --disable-Bsymbolic configure flag to disable linking with + -Bsymbolic-functions + - this release sees the complete removal of the old 'g*alias' hacks + - honour the NOCONFIGURE environment variable from autogen.sh + - use proper feature test macros for isnan + - use pkg-config to check for zlib + - add ACLOCAL_AMFLAGS to Makefile.am + +GDBus: + - hide Class and instance structures for all GDBus types except + GDBusProxy. This breaks API by preventing subclassing, but probably + nobody was doing that. + - add new GDBusConnection call to support flushing all pending + outgoing messages + - change the register_object API to add a reference to the + GDBusInterfaceInfo object so the caller need not keep it alive + themselves + - don't rewrite the serial number when sending messages that already + have a serial number + - better error checking for DBUS_SESSION_BUS_ADDRESS environment + variable + - switch to g_parse_debug_string for G_DBUS_DEBUG and add a lot of new + flags + - add support for temporarily freezing a freshly created + GDBusConnection. Do this until after the ::new-connection signal + has finished running on GDBus services. + - never require non-closed connections (the user is incapable of doing + this due to the obvious race) + - remove weird/misleading redundant check on NameOwnerChanged signal + - emit GDBusProxy::g-properties-changed on NameOwnerChanged + +GVariant: + - the 'g_variant_{new,get}_byte_array' APIs have been removed + - g_variant_{new,get,dup}_bytestring has been added, with different + arguments and different behaviour + - g_variant_{new,get,dup}_bytestring_array has been added, doing + essentially the same thing as the 'strv' functions, but with byte + strings instead of utf8 strings + - G_VARIANT_TYPE_BYTESTRING ('ay'), BYTESTRING_ARRAY ('aay') and + STRING_ARRAY ('as') constants have been added + - the undocumented behaviour that g_variant_get_strv() deserialised + arrays of object paths or signature strings has been dropped + - additional varargs support for converting bytestrings or bytestring + arrays with ^ay ^aay ^&ay and ^a&ay + - improved gobject-introspection annotation + - fix a problem with GBuffer calling g_slice_free for the wrong type + - fix leaks in the type inferencing code of the parser + +GSettings: + - improved documentation + - updated schema XML DTD, now xincluded into the docs + - added support for schemas that extend other schemas (using the + 'extends=' attribute). Values of keys in the base schema can be + overridden using . + - added theoretical support for lists (using the 'list-of=' attribute) + - lots of new tests + - add support for flags (implemented similarly to enums) + - add support for generating .enums.xml files to gsettings.m4: + gsettings_ENUM_NAMESPACE = org.example.myapp + gsettings_ENUM_FILES = ../path/to/*.h + will generate org.example.myapp.enums.xml with mappings for all + enums and flags in the specified .h files. + - warn with g_message() if the 'memory' backend is used by default + (ie: because no other GSettings backends are installed) + - fix get_property() for GSettings::schema + - command line tool: fix a bug that prevented non-basic values from + being set due to a premature free + - command line tool: bash completion support + - chain up in _finalize + - add a new g_settings_get_mapped API to read settings that require + post-processing + - retry with the translated or schema default value if the + GSettingsBindGetMapping function fails + - schema compiler: never fail due to empty schema directories (but + warn) + - peek rather than ref/unref the GEnumClass in the mapping function + - schema compiler: compile *.enums.xml before *.gschemas.xml to ensure + that we have all the enums that the schemas may reference + - schema compiler: improve accuracy of line numbers in error reports + - fix crashes in the keyfile backend caused by invalid group names in + the keyfile + +Other: + - always intern GBinding prop names + - base64: remove asserts preventing conversion of empty strings + - document NULL special-cases for GValueArray + - GNode docs improvements + - improve detection of 'system internal' mounts + - fix leaks in the inotify GFileMonitor implementation + - annotate all custom GIO GSources to improve debugging (e.g. using + SystemTap) + +Tests: + - Turn on glibc malloc checking features for make check + - improvements for GSettings tests, plus new tests + - improved tests for GKeyfile + - new tests for GDir, GSList, GSList, GAppLaunchContext, + CharsetConverter, GIcon, ... + - move some tests to GTester (tree tests, uri tests) + - generally, really an awful lot of new tests + - don't try to allocate 2gigs of memory anymore for the array test + + 552363 g_value_array_{insert,prepend,append}'s special cases for NULL + 561248 Improve return value description from g_node_prev/next_sibling() + 570036 Add ACLOCAL_AMFLAGS to Makefile.am + 576833 g_sprintf add a reference to g_strdup_printf + 576854 g_strconcat() documentation should provide a hint about bad l10n + 582227 reference: add other URI functions to 'URI Functions' section + 599223 should provide g_spawn_* variants that take a GAppLaunchContext + 610784 array test failing + 613057 Leak in inotify GFileMonitor implementation + 620536 Annotate all custom GIO GSource using g_source_set_name + 620913 More control with G_DBUS_DEBUG + 622124 implement flags + 622127 GSettings extended key validation + 622128 retry with default value for failed mapping + 622294 More annotations for GVariant + 622565 glib-compile-schemas fails when no schemas + 622600 Fix missing prototype warning + 622813 gsettings mapping & enum buglet + 623142 Ensure ::new-connection runs before processing D-Bus messages + 623143 Never require non-closed connections + 623319 use g_parse_debug_string for dbus debug flags + 623401 process enums first + 623402 schema compiler reports wrong line numbers + 623407 g_keyfile_settings_backend_new crashes with the key "/" + 623473 zlib should be checked with pkg-config + 623537 GDBusProxy has weird checking on NameOwnerChanged + 623538 GDBusProxy::g-properties-changed emission for corner cases + 623692 directory with file at multiple MLS levels may display empty + 623720 gschema.dtd does not contain enum definitions + 623770 quoting of expand_macro in gdesktopappinfo.c + 623772 gdesktopappinfo.c, function child_setup + 623780 g_unix_is_mount_path_system_internal + 623954 g_settings_finalize + 623955 Dubious return values + +Updated translations: + Galician + Hebrew + Norwegian bokmÃ¥l + Spanish + +Overview of Changes from GLib 2.25.9 to GLib 2.25.10 +==================================================== + ++----------------------------------------------------------------+ +| WARNING: There have been API changes in GDBus. Users of these | +| APIs will need to be adapted. In particular, a new release of | +| dconf is required to go along with this one. There has also | +| been a change in the GSettings backend API used for keyfiles. | ++----------------------------------------------------------------+ + +* GDBus: + - add direction parameter to filter functions (API change) + - allow calling other interfaces with a GDBusProxy + - padding added to class struct fields (ABI change) + - fixes for closures-based functions + +* GVariant: + - new is_floating() call + - add g_value_take_variant() call (required for marshallers) + +* GSettings: + - support for binding GParamSpecEnum properties + - ifelse-style condition support for GLIB_GSETTINGS m4 macro + - remove gsettings-schema-convert tool (now in GConf) + - allow introspection of all installed schemas + - allow introspection of the keys in a schema + - rewrite keyfile backend (API change) + +* GNIO: + - don't implicitly close GSocket until it is destroyed + - windows fixups + +* Other: + - allow GChecksum to take (NULL, 0) for data/length + - GRelation and GCompletion are now deprecated + - introduce G_PARAM_DEPRECATED and G_ENABLE_DIAGNOSTIC + - add working directory to GApplication platform data + - lots of documentation cleanups + - PCRE updated to 8.02 + +* Build: + - the IA__g_* style symbol aliasing has been disabled and replaced with + the -Bsymbolic-functions linker flag on platforms that support it. + Please be on the watch for portability issues and report them to us. + - many test cases have been moved to the GTester framework + - lcov support has been added for tests + - many windows fixes + +* Bugs fixed: + 501057 lcov coverage suite and GLib integration + 551271 deprecate GRelation + 601686 Implement diagnostic mode + 603309 GSocketOutputStream broken on Windows (?) + 616718 GLIB_GSETTINGS macro can't be used conditionally + 616855 GSocketConnection: don't close the socket if it's still reffed + 618866 g_ptr_array_remove_index_fast memory leak + 619878 keyfile backend calls keys_changed with invalid argument + 619879 keyfile backend doesn't make use of expected_type + 621092 Add with_closures() variants for bindings + 621172 Cross compiling fails + 621838 Actually add cwd to platform data + 621945 Filter outgoing messages in GDBusConnection + 621947 add g_value_take_variant + 622038 GSettings: "It is a programmer error" documentation is unclear + 622154 [patch] update documentation for g_application_new + 622281 binding: Add SYNC_CREATE to the flags + 622480 Improve documentation for g_strcmp0() + 622554 g_error called if schema not installed + 622601 Return interned strings from g_settings_list_keys + +* Translation updates: + - Galician + +Overview of Changes from GLib 2.25.8 to GLib 2.25.9 +=================================================== + ++----------------------------------------------------------------+ +| WARNING: There have been API changes in GDBus, GSettings and | +| GApplication. Users of these APIs will need to be adapted. In | +| particular, a new release of GTK+ is required to go along with | +| this one. | ++----------------------------------------------------------------+ + +* GDBus + - Use Gio's default async implementation + - Fix proxy construction for objects with no properties + - Fix error handling in synchronous initialization + - Do not dispatch calls to unregistered objects + - Add _with_closures alternative functions + - Allow constructing GDBusProxy with well-known names + - Remove GType parameters from GDBusProxy constructors + - Nuke g_bus_watch_proxy API + - Add --xml to gdbus-tool to print raw introspected XML + +* GSettings + - schema file format change: store (default, options) in gvdb + - Add g_settings_sync() + - Add support for enums and ranges + - 'context' support has been replaced by direct use of + GSettingsBackend + +* GApplication + - Switch to using variants for timestamps + - Use GInitable + +* GObject + - Introduce g_object_notify_by_pspec + - Add GBinding + - The GVariant gtype G_TYPE_VARIANT was changed from boxed + to fundamental. We believe there were no existing users + of the boxed type, so this should not cause any applications + to break. + +* Test framework + - Add package and version to the test report XML + - Use optparse to parse gtester-report commandline + - Add subunit support to gtester-report + - Prevent division by zero if no tests + +* Bugs fixed: + 621782 Crash using gbinding + 619945 GConverterOutputStream triggers assertion and corrupts data + 621319 more leaked GVariants in GSettings + 621168 GKeyFile memory leak on Windows platform + 621002 Switch to using variants for timestamps, split out signals + 620953 tiny docs addition + 618904 Lies in gunixmounts documentation + 621702 Correctly initialize GError + 611778 minor cleanup of gtester-report + 621213 GDBusProxy and well-known names + 621034 Rewrite apps test to ensure children are killed + 620954 gapplication gvariant simplifications + 611869 add subunit out feature to gtester-report + 621119 GDBusProxy and objects with no properties + 620990 Use Gio's default async implementation again + 620952 g_application_register_with_data is an ugly API + 621252 GSettings leaks context + 618715 fork() in GSettings test cases is problematic 618715 + 621905 Assume a ref when doing async work + 621266 GSettings "context" clarification + +* Translation updates: + Chinese + + +Overview of Changes from GLib 2.25.7 to GLib 2.25.8 +=================================================== + +* Initial support for dtrace and systemtap profiling: + - mainloop sources can be named + - probes for memory allocation with g_malloc and gslice + - gquark name tracking + - type creation + - object life-cyle (creation, finalization, ref, unref) + - signal creation and emission + +* GVariant + - has been fixed to work with the FreeBSD malloc + - added introspection annotations + - new function: g_variant_builder_add_parsed + +* GSettings: + - g_settings_set/get_strv functions have lost their length parameter + - g_settings_set_strv accepts NULL + - added introspection annotiations + +* GPermission: an abstract interface for representing permissions, + with a minimal implementation named GSimplePermission + +* GApplication: a basic application support class, with a D-Bus based + implementation + +* Bugs fixed: + 619585 glib-compile-schemas asserts on FreeBSD + 620384 Annotate GVariant and GSettings _strv() functions + 606044 Add support for dtrace/systemtap static markers + 620350 add g_variant_builder_add_parsed() API + 620349 utf8ify GVariant printer + 620767 Typo in GSettings documentation: "INTLTOOL_NOMERGE_RULE" + 620312 Fix g_settings_[gs]et_strv() API + 620519 GPermission + 620582 GPermission needs a simple implementation + 620496 GSettings schema compiler should reject invalid paths + 620173 missing single header inclusion guards + 620265 g_assertion_message_error should take const GError * + +* Translation updates: + Esperanto + Galician + Hebrew + Indonesian + Norwegian bokmÃ¥l + Slovenian + Spanish + + +Overview of Changes from GLib 2.25.6 to GLib 2.25.7 +=================================================== + +* NOTE: API/ABI breaks since 2.25.6 release: + - g_dbus_connection_sync{,_sync} takes a new 'reply_type' argument + - GSettingsBackendClass 'list' virtual function changed + + GSettings backends and things using GDBus may need to be rebuilt. + +* GDBus: many build-related fixes + +* GDBus (service): return a DBus error when receiving a method call for + an unknown interface. + +* GSettings: fix 'make install' bug in gsettings.m4 for generated schema + files + +* GSettings: avoid non-portable use of LC_MESSAGES + +* better approach to handling man pages + + +* Bugs fixed: + 619527 please improve docs on g_file_make_symlink + 619391 send-with-reply should have expected result signature + 618616 Use stack-allocated GVariantBuilders + 617004 Build with "--disable-nls" fails under MinGW/Win32 + 619142 Build fixes (GDBus) + +* Updated translations: + Estonian + Galician + Norwegian bokmÃ¥l + +Overview of Changes from GLib 2.25.5 to GLib 2.25.6 +=================================================== + +* GDBus: introspection improvements +* GDBus: build fixes + +* GSettings: GSettingsBackend ABI changed **** NOTE **** +* GSettings: --uninstall option for schema compiler +* GSettings: new m4 macro with more power +* GSettings: thread support + +* rework of file notification on Solaris +* fixes for gold linker + +* Bugs fixed: + 619038 increase gsettings.m4 power + 619031 method-calls-in-thread test failing + 618839 Typo at translation message + 616864 GSETTINGS_CHECK_RULE doesn't work with multiple files + 618730 gunixcredentialsmessage.c doesn't compile on GNU/kfreebsd + 616314 Make GSettings (partially) threadsafe + +* Updated Translations: + Indonesian + Galician + Spanish + +Overview of Changes from GLib 2.25.4 to GLib 2.25.5 +=================================================== + +* GDBus: Fix serialization of empty arrays + +* GDBus: Plug various memory leaks + +* GSettings: Fix problems with GSETTINGS_CHECK_RULE + +* Bugs fixed: + 616731 GSETTINGS_CHECK_RULE doesn't work in non-srcdir builds + 616864 GSETTINGS_CHECK_RULE doesn't work with multiple files + 618615 mem leaks in parse_value_from_blob + 618622 Plug some mem leaks in gdbus + 618650 Plug a mem leak in gdbusauth + 618663 Plug mem leaks in gdbus tests & examples + +* Updated translations: + Spanish + + +Overview of Changes from GLib 2.25.3 to GLib 2.25.4 +=================================================== + +* GDBus D-Bus support has been merged. This provides an API + to replace dbus-glib + +* GVariant no requires strings to be UTF-8. You can use byte + arrays for non-UTF-8 strings. + +* GSettings allows to bind string properties to byte arrays + +* The schema compiler supports range restrictions + +* Bugs fixed: + 618051 socket-server|client.c fail to compile under AIX... + 616102 GSettings ignores and + 616720 Chunked quark allocation + 616877 Several issues with g_socket_receive_message + 616892 gio: Add a boxed type for GFileAttributeMatcher + 616967 Add g_regex_get_compile_flags() and g_regex_get_match_flags() + 617767 g_settings_[gs]et_strv() 'length' argument has missing docs... + 617914 gtester-report: cope with binaries with no test cases + 617937 output_stream_close vs output_stream_close_async semantics + 615494 Connction timeouts produce partially invalid error messages + 617823 glib-compile-schemas problems with an out of source build + 617947 glib-mkenums: add @valuenum@ support + +* Translation updates: + Galicaian + Norwegian bokmÃ¥l + Shavian + Spanish + + +Overview of Changes from GLib 2.25.2 to GLib 2.25.3 +=================================================== + +* New macro: G_GNUC_DEPRECATED_FOR, a variant of G_GNUC_DEPRECATED + that lets you add replacement information (requires gcc 4.5) + +* Rename AM_GSETTINGS autoconf macro to GLIB_GSETTINGS + +* Rename gschema-compile utility to glib-compile-schemas + +* Add support for timeouts in GSocket + +* Bugs fixed: + 589989 Compilation error on Solaris 9 + 616648 Change AM_GSETTINGS macro to GLIB_GSETTINGS + 587898 I/O timeouts for GSocket + 614541 Add G_TYPE_ERROR boxed type for GError + + +Overview of Changes from GLib 2.25.0 to GLib 2.25.2 +=================================================== + +* Include a 'gsettings' utility, for commandline access to GSettings + +* Install a AM_GSETTINGS autoconf macro similar to AM_GCONF + +* GSettings can bind the writability of a key explicitly + +* There is now a predefined boxed type for GError + +* Bugs fixed: + 615379 g_new macros crash if sizeof(struct_type) == 0 + 616312 Add m4 rule equivalent to GCONF_SCHEMAS_INSTALL + 616295 mapping bug for uint64 + 616216 glib compile from remote directory fails + 615960 Fix size passed to connect() for abstract sockets + 616432 Crash in gschema-compile + 616331 gsettings-schema-convert uses imaginary types + 616309 gsettings-schema-convert should output gettext-domain + 616384 Add mention of GConfBridge in conversion docs + 616311 gschema-compile outputs in current directory + 616276 simplify gschema-compile test setup + 616156 keys with unnecessary empty options arrays + 616405 gsettings missing g_return_if_fail's + 616245 Use G_DEFINE_INTERFACE macro + 614541 Add G_TYPE_ERROR boxed type for GError + +* Updated translations: + Catalan (Valencian) + Galician + Kannada + Spanish + + +Overview of Changes from GLib 2.24.0 to GLib 2.25.0 +=================================================== + +* The GSettings framework has been merged. This provides the API to + replace GConf. DConf will provide a backend implementation for it. + GConf will also provide a backend implementation to ease the + transition. We provide utilities to assist with schema conversion + and data migration, as well as a porting guide. + +* Translation updates: + Bengali + Catalan + Danish + Gujarati + Marathi + Thai + Traditional Chinese + + +Overview of Changes from GLib 2.23.6 to GLib 2.24.0 +=================================================== + +* Bug fixes: + 613601 buglet in dup_close_on_exec_fd + 584284 g_data_input_stream_read_until_async behaves confusingly + 613748 Write errors in middle of copy cause hang + 613923 splice_stream_with_progress: wrong error handling + 613667 Typo in GObject documentation + 613618 gvariant format string docs unclear + +* Translation updates: + Basque + Ukrainian + Vietnamese + + +Overview of Changes from GLib 2.23.5 to GLib 2.23.6 +=================================================== + +* Class private data: + - support for private data associated with a GTypeClass + +* GVariant merge is now complete: + - loading functions and parser merged + +* Windows improvements: + - socket fixes + - various build improvements + - removal of GCC/C99isms in favour of portable code + - drop unmaintained Visual Studio 8 support + +* Minor API addition: + - g_desktop_app_info_get_filename() + +* Bugs fixed: + 521707 Class private data + 612502 build fails on glib/tests/gvariant.c + 612832 [GDesktopAppInfo] New function g_desktop_app_info_get_filename + 612702 [PATCH] Fix GSocket-related crash on Windows + 612736 Improve the documentation about single include + 610858 gvariant test fails sometimes + 612327 uninitialized variable + +* New translations: + Afrikaans + LowGerman + +* Updated translations: + Czech + Finnish + Galician + Greek + Punjabi + Romanian + Serbian + + +Overview of Changes from GLib 2.23.4 to GLib 2.23.5 +=================================================== + +* New API addition: g_malloc_n() and friends used to implement an + overflow-safe family of g_new() macros. + +* GVariant: + - GVariantBuilder and GVariantIter are now merged. + - The variable arguments API is now merged. + - The parser will be in a future release. + +* GIO: + - Remove GUtf8InputStream (which never appeared in a stable release) + for now since it doesn't satisfy the needs of its main intended use + case. We hope to reimplement this feature in a better form in a + future release. + +* Bugs fixed: + 609531 missing licence headers + 612107 Missing G_FILE_ATTRIBUTE_TRASH_ORIG_PATH + 611897 g_io_modules_scan_all_in_directory leaks + 608196 Overflow-safe g_new family + 611696 gio uses GetAddrInfo which requires special handing on windows 2k + 605667 Don't use G_PARAM_SPEC_VALUE_TYPE when we know the pspec is valid + 610860 test_g_file_open_readwrite fails if $HOME is unwritable + 552912 glib-2.18 /live-g-file/test_copy_move failed when run as root + 609813 Renaming a file discards file notes + +* Updated translations: + Basque + Brazilian Portuguese + British English + Bulgarian + Catalan + Danish + Estonian + French + German + Hungarian + Italian + Lithuanian + Norwegian bokmÃ¥l + Portuguese + Russian + Slovenian + Spanish + Swedish + Traditional Chinese + + +Overview of Changes from GLib 2.23.3 to GLib 2.23.4 +=================================================== + +* GVariant: The core of GVariant has been merged now, with some + API still to follow. + +* GIO: + - There is a new interface GFileDescriptorBased for file descriptor + based IO. GLocalFile{Input,Output}Stream implement it + - Use splice(2) to transfer data between file descriptors without + extraneous copies + - Add a way to request move events from file monitors + +* Bugs fixed: + 609143 *result_uncertain is never assigned in g_content_type_guess + 604086 Use splice(2) when doing local file copies + 547890 No move events for GFileMonitorEvent? + 568760 nautilus freezes due to a bug in garray.c:322 + 609962 Add info about the use of G_DEFINE_INTERFACE + 609564 g_base64_encode_close docs should mention outbuf size... + 610484 g_variant_equal bug + 610131 libasyncns does not compile on Solaris 8 + 609530 missing single header include guards + +* Updated translations: + Czech + Estonian + Galician + German + Korean + Polish + Slovenian + Spanish + Traditional Chinese + + +Overview of Changes from GLib 2.23.2 to GLib 2.23.3 +=================================================== + +* GLib now has a facility for locks that consume only one bit of + storage inside an integer: g_bit_lock() + +* GVariant: The serializer has been merged, with more API to follow + +* Bugs fixed + 548967 1 bit mutex lock + 604967 2.22.3 libasyncns build fails on HP-UX 11.11 + 608602 G_VALUE_COLLECT_INIT variables shadow those in G_VALUE_COLLECT + 608743 Crash in g_hostname_to_ascii visiting certain website in epiphany + 599197 array ref and unref functions crash on NULL array. + 608159 mem leak in g_io_modules_scan_all_in_directory + +* Translation updates + Brazilian Portuguese + Czech + French + Norwegian bokmÃ¥l + Slovenian + Spanish + Thai + + +Overview of Changes from GLib 2.23.1 to GLib 2.23.2 +=================================================== + +* We are now using gcc builtins for atomic operations when available + +* g_assert() grew the ability to store assertions in core dumps + +* GIO supports lazy loading of GIO modules, and there is a new + gio-querymodule utility that goes along with this. + Packagers will need to adapt to this. + +* Threading changes: + - The requirements for g_thread_init() have been relaxed slightly, + it can be called multiple times, and does not have to be the first + call. + - GObject now links to GThread and threads are enabled automatically + when g_type_init() is called. + - Thread-safety issues with boxed types in GObject have been fixed. + +* GObject: + - Another bunch of performance work has landed + +* GVariant: + - GVariantType has been merged, with the rest of the GVariant + API to follow. + +* Bugs fixed: + 568760 nautilus freezes due to a bug in garray.c:322 + 602417 Document lifecycles of GSimpleAsyncResult and friends + 604824 crash in Epiphany: Selecting my Slashdot bo... + 448888 don't init g_slice for always-malloc + 531902 Use GCC atomic buildins for g_atomic* + 554887 boxed type registration is not thread safe + 586150 unresolved symbols when building glib 2.21.2 on OS X Tiger + 589176 row gvalue transform array exponentially + 594872 Support storing assertion messages into core dump + 602240 Upgrade libasyncns to 0.8 + 603590 Speed up G_VALUE_COLLECT + 604457 gutf8inputstream.c: increasing unknown size pointer + 605686 GCharsetConverter doesn't flush + 605733 g_memory_output_stream_new violates GObject standards + 605883 g_object_new() processes varargs even when there are none + 605977 invalid utf-8 conversion in g_local_file_get_parse_name(... + 606775 Enable threads by default in gobject + +* Translation updates: + Asturian + Basque + Bengali + Bulgarian + Estonian + Norwegian bokmÃ¥l + Spanish + Thai + Ukrainian + + +Overview of Changes from GLib 2.23.0 to GLib 2.23.1 +=================================================== + +* GObject performance work has landed: + - Construction of simple objects is much faster + - Interface lookup is lock-free and constant-time now + - Reduced locking overhead when dealing with types + +* GType now has a G_DEFINE_INTERFACE convenience macro + +* GIO gained GUtf8InputStream, an input stream that + performs utf-8 validation + +* GLib now has byte-swap macros for gsize and gssize + +* Bugs fixed: +557151 Determining the newly_constructed boolean in gobject.c... +557100 Performance improvements for GObjectClasses that don't... +501166 Warning message says IA__g_type_init instead of g_type_init +585375 Performance and Contention problems with g_type_class_ref... +587892 Race in GType when instantiating the same class for the... +603270 Input Stream validating utf8 +603476 gioenums.h:62: error: comma at end of enumerator list +603540 g_time_val_from_iso8601 uses uninitialised variable +603982 Stack overflow when reading file async with filter +604645 G_DEFINE_INTERFACE_* documentation is not generated +604875 Use of sa_len conflicts with system header +320482 provide G_DEFINE_TYPE like macros for interfaces + +* Updated translations: + Estonian + Hebrew + Norwegian bokmÃ¥l + Vietnamese + Welsh + + +Overview of Changes from GLib 2.22.x to GLib 2.23.0 +=================================================== + +* GIO: + - GConverter: a generic interface for stateful conversions of data, + suitable for charset conversion, compression, decompression, regexp + replacement. Concrete implementations are GCharsetConverter, + GZlibCompressor and GZlibDecompressor. GConverterInputStream, + GConverterOutputStream are stream implementations that convert data + while loading or saving it. + - GMounts can now have a 'default location': a path that reflects + the main entry point for the user (e.g. the home directory). + - As a consequence of the compression support, GIO depends on zlib now. + +* GObject: + - G_IMPLEMENT_INTERFACE_DYNAMIC: a convenience macro for adding + interfaces to dynamic types. + +* GModule: + - The -pthread flag has been added to all gmodule .pc files, because + it is not generally permissible to load modules that are linked + against libpthread if the program has not been compiled with threading + support. + +* Bugs fixed: + 601637 GUnixFDMessage should contain a GUnixFDList + 585566 GSocketListener API issues + 572252 Bug in g_file_test() function. + 600550 g_app_info_create_from_commandline doesn't treat arguments properly + 541236 not detecting exact content type + 350200 [PATCH] GTypeModule derived class unref does not unload plugin + 589631 Please enclose literal values with double quotes + 577711 cross compile check for g++ broken + 600620 Support X-GNOME-FullName in GAppInfo + 598899 GWin32DirectoryMonitor is broken + 593809 Nautilus does not restore the position of the icons on the desktop... + 563627 g_get_prgname() threadsafety + 600141 Add -pthread to gmodule pkg-config + 593856 file and directory monitors don't work when glib is compiled... + 324930 Nautilus should disallow copying of symlink to FAT drive early + 587300 Deadlock when calling g_cancellable_disconnect in a... + 595138 GFile not robust with invalid input + 591216 Warning building resolver.o + 590016 Does not compile under MinGW32 + Wine + 591214 Warnings building gcancellable.o + 561998 Have specific entry points (paths) for mounts... + 508157 Add G_IMPLEMENT_INTERFACE_DYNAMIC + 535159 g_file_has_parent + +* Updated translations: + Brazilian Portuguese + Catalan + Estonian + Galician + Norwegian bokmÃ¥l + Shavian + Slovenian + Spanish + Swedish + + +Overview of Changes from GLib 2.22.1 to GLib 2.22.2 +=================================================== + +* GIO: + - Support case-sensitive globs in the shared mime database, + including support for the newer cache format that allows these. + Case-sensitive globs have been introduced in shared-mime-info + version 0.70 + +* GObject: + - Speed up creation of simple objects + +* Bugs fixed: + 597194 Typo in _G_TYPE_CVH macro + +* Updated translations: + Russian + + +Overview of Changes from GLib 2.22.0 to GLib 2.22.1 +=================================================== + +* Bugs fixed: + 596064 Test file marked for translation + 595972 possibly invalid search in mime_info_cache_dir_add_... + 596561 C99 style of declaration of variable in gmessages.c + 596314 g_utf16_to_utf8 returns an invalid UTF8 string + 596748 g_async_result_get_source_object returns a new ref + 593809 Nautilus does not restore the position of the icons... + 593775 uses inotify_init1 unconditionally + +* Updated translations: + Bengali + Hebrew + + +Overview of Changes from GLib 2.21.6 to GLib 2.22.0 +=================================================== + +* Add gdb python macros to make gobject debugging more pleasant + +* Bugs fixed: + 579050 Allow making selected critical and warning messages non-fatal + 594759 g_socket_send_message fails due to invalid sendmsg params + 593941 GNetworkAddress skipping addresses when enumerating + 594597 Fix build with srcdir != builddir + 595619 Include gdb pretty printers + +* Changes that might affect bindings: + - The error parameter of g_simple_async_result_set_from_error has been + made const. + +* Updated translations: + Assamese + Bengali India + British English + Bulgarian + Catalan + Czech + Danish + Finnish + Galician + Greek + Gujarati + Hindi + Japanese + Kannada + Malayalam + Marathi + Norwegian bokmÃ¥l + Oriya + Polish + Punjabi + Romanian + Serbian + Simplified Chinese + Slovenian + Spanish + Tamil + Telugu + Thai + Traditional Chinese + Ukrainian + Vietnamese + + +Overview of Changes from GLib 2.21.5 to GLib 2.21.6 +=================================================== + +* Minor API additions: + g_mkstemp_full is a variant of g_mkstemp that allows to specify flags + and permissions + +* Bugs fixed: + 593232 g_rand_new: read no more than requested from /dev/urandom + 591995 use saved errno + 589491 g_time_val_from_iso8601 doesn't handle some cases + 593406 Permissions set to 777 after copying via Nautilus + 594034 Add g_mkstemp_full() + +* Updated translations: + Assamese + Basque + Brazilian Portuguese + Czech + Estonian + French + German + Hungarian + Italian + Kannada + Malayalam + Marathi + Norwegian bokmÃ¥l + Oriya + Portuguese + Swedish + Tamil + Turkish + + +Overview of Changes from GLib 2.21.4 to GLib 2.21.5 +=================================================== + +* A performance problem with trashing of many files has been fixed + +* GResolver now invalidates the libc resolv.conf cache as needed + +* Minor api additions: + - g_cancellable_make_pollfd returns a boolean now. And there is a + new function g_cancellable_release_fd that can be used to released + the resources used by a GCancellable. + +* Bugs fixed: + 589988 Compilation error on Solaris 9 (missing stdint.h) + 588901 gtcpconnection.c won't compile + 584246 GResolver needs to call res_init() when network state changes + 591714 Figure out failure handling for g_cancellable_make_pollfd() + 591532 redundent '/' returned from g_file_resolve_relative_path + 591378 Use MSG_NOSIGNAL in GSocket if it's available + 589649 API documentation migration for Base64 Encoding + 591840 configure fails with autoconf 2.64 + +* Updated translations: + Basque + Brazilian Portuguese + Bulgarian + Danish + Estonian + Finnish + Galician + Gujarati + Hndi + Irish + Japanese + Korean + Norwegian bokmÃ¥l + Polish + Portuguese + Punjabi + Spanish + Swedish + Telugu + Traditional Chinese + Thai + + +Overview of Changes from GLib 2.21.3 to GLib 2.21.4 +=================================================== + +* GTree is now refcounted + +* Bugs fixed: + 587938 Undocumented limitation for g_str_equal + 587773 refcounts for GTree + +* Updated translations: + French + Hebrew + Norwegian bokmÃ¥l + Spanish + Swedish + Traditional Chinese + Ukrainian + + +Overview of Changes from GLib 2.21.2 to GLib 2.21.3 +=================================================== + +* GMappedFile is refcounted now + +* Mainloop: It is now possible to set per-thread default contexts, + with g_main_context_push_thread_default. + +* glib-mkenums supports a @basename@ substitution, in addition + to @filename@. + +* GIO: + - Vfs implementations can support storing of per-file metadata. + - GCancellable can now be subclassed. + - Unmount and eject methods now optionally allow interaction, via + variants that take a GMountOperation object. + +* Bugs fixed: + 556706 Inconsistent help arguments -h, -? + 579449 FileChoosers no longer work if an idle handler is active + 579933 mainloop FD_CLOEXEC has a race condition + 579984 alternate GMainContext support + 585937 gio/gsocket.c (glib 2.21.2) does not compile (Windows/mingw) + 586675 Runtime library location + 586797 Add GCancellables to GSocket ops + 586868 g_filename_complete_get_completions doesn't always return... + 587415 g_resolver_lookup_by_name_finish returns a freed list + 587434 regression tests fail, at least on x86_64 + 586928 Avoid g++ warning in g_error() + +* Updated translations: + Estonian + Hebrew + + +Overview of Changes from GLib 2.21.1 to GLib 2.21.2 +=================================================== + +* GIO: + - g_socket_speaks_ipv4 is a new function to check if a socket can + speak IPv4. + - g_socket_listener_add_address gained a new effective_address out + parameter. + - GIO now returns special icons for XDG user directories, by the + name folder-music, folder-documents, etc. + - GIO gained support for starting/stopping of drives, which can be used + in connection with external hard disk enclosures, disk arrays, iSCSI + devices, etc. See g_file_start/stop_mountable. + +* GLib: + - g_reload_user_special_dirs_cache is a new function to force GLib to + reload the XDG user directory mapping from disk. + +* Bug fixes: + 584574 glib compile failure on Mac OS X with gunixresolver.c and... + 585566 GSocketListener API issues + 584255 Incorrect freeing of thread pool in GThreadedSocketService + 585088 g_string_chunk_insert_len stops at nul bytes + 585360 Monitor fontconfig configuration files using gio causes m... + 580103 Terminal starts on Display :0.0 when started on :0.1 in D... + 580301 network: a few issues on old darwin + 583398 SRV weight sorting is incorrect + 584176 build fixes on FreeBSD + 585189 g_cancellable_reset() must be called in same thread as g_... + 585280 compilation dies on gio/gsocket.c, needs sys/uio.h to con... + 585281 gio/gunixfdmessage.c needs sys/types.h for platforms that... + 585478 don't leak the inotify fd + 585575 g_socket_listener_add_inet_port() doesn't do the right thing + 585599 g_socket_listener_add_socket() consumes the socket + 585676 GEmblem doesn't reference its 'icon' if that is set as a ... + 585717 "bytes" nautilus translation to french is not shown in th... + 541276 XDG directories should have their own icons + 585726 Grammatical error in GList documentation + 585520 Wrong warning option in documentation + 585673 GNOME Goal: Remove deprecated glib symbols + 585591 Starting/stopping drives + +* Updated translations: + Bengali India + Norwegian bokmÃ¥l + + +Overview of Changes from GLib 2.21.0 to GLib 2.21.1 +=================================================== + +* GIO: + - Support for network IO has been added, including a low-level + socket API and a high-level API for network connections and + services. + - Support for read-write access with GIOStream and its subclasses. + - GMount gained a pre-unmount signal. + +* Bug fixes: + 576104Implement GMount::pre-unmount + 578769 implement GWinHttpFileInputStream::close_fn + 582856 gsocket.c doesn't compile on Solaris + 569375 g[u]intptr undocumented + 573246 [FIX] g_desktop_app_info_dup() can access NULL pointer + 575013 g_cancellable_push_current() does not allow NULL + 577884 live-g-file.c:461: error: format ‘%d’ expects type ... + 578499 g_output_stream_splice and stream closing with gnio strea... + 579558 Application employing gvfs crashes with only libgvfscommo... + 583001 SIGPIPE (grr!) + 583061 Please add convenience function to connect to machines by... + 583198 typo in error message + 583206 use g_set_error_literal where appropriate + 583229 void function g_async_initable_init_async returns value + 583324 locking problem in g_main_context_iterate() + 583408 void function g_socket_control_message_serialize returns ... + 578786 wrong and confusing error message + 583205 g_inet_address_to_bytes has no length outparam + 583196 mem leak in keyfile test + 583663 GSocketType enum ends with a comma + 569024 Make g_error_new_valist public + 569376 missing G_G[U]INTPTR_FORMAT + 580347 off-by-1 bug in GWinHttpFile + +* Updated translations: + Oriya + Spanish + Valencian-Catalan + + +Overview of Changes from GLib 2.20.x to GLib 2.21.0 +=================================================== + +* GIO: + - New helper functions g_cancellable_connect/disconnect to avoid + race conditions when connecting to the "cancelled" signal on + GCancellable. + - New types and methods for dealing with IPv4 and IPv6 addresses (and + UNIX domain socket addresses under UNIX). This does not include code + for actual socket I/O. + - GResolver provides asynchronous and cancellable APIs for resolving + hostnames, reverse lookup of IP addresses and resolving SRV records. + +* Glib now provides hash and comparison functions for int64 and double + types, suitable for use with GHashTable. + +* GArray, GPtrArray and GByteArray can be ref counted now, and have + boxed types. + +* Bugs fixed: + 572844 Helper for GCancellable::cancelled connect/disconnect + 578363 goption docs should be improved + 548466 async/cancellable DNS resolver + 579830 param spec strings should use P_() + 579862 requesting xattr::foo ends up calling getxattr(..., user... + 580453 Hash and equal functions for gint64 and gdouble + 580450 Reference counting and boxed types for arrays + 580194 gresolver doesn't build on Solaris + 580301 network: a few issues on old darwin + 580299 network: include sys/types.h before sys/socket.h to insur... + 572508 gmarkup speedup + 580546 g_strtoull() referenced in documentation... + 580656 g_key_file_set_string_list erroneously asserts list != NULL + 579272 leaks in g_simple_async_result_set_op_res_gpointer + + +* Updated translations: + Catalan (ca) + Pashto (ps) + Spanish (es) + + +Overview of Changes from GLib 2.20.0 to GLib 2.20.1 +=================================================== + +* Bug fixes: + 575555 Use fsync() when replacing files to avoid data loss on + 575708 runaway inotify madness + 575270 GVolumeMonitor::mount-pre-unmount not being emitted + 577128 glib make check Failed to execute child process... + 573673 Always show "backup" directories + 578369 g_time_val_from_iso8601() parses timezones incorrectly + 578002 Fix a small typo in GFile docs + 578017 G_DEFINE_TYPE_EXTENDED docs + +* Updated translations: + Arabic + Assamese + Basque + Bularian + Brazilian Portuguese + British English + Catalan + Danish + French + Galician + German + Greek + Hungarian + Italian + Japanese + Kannada + Lithuanian + Malayalam + Norwegian bokmÃ¥l + Oriya + Polish + Punjabi + Russian + Simplified Chinese + Slovenian + Spanish + Swedish + Tamil + + +Overview of Changes from GLib 2.19.9 to GLib 2.20.0 +=================================================== + +* Base64 support: Avoid integer overflows. CVE-2008-4316 + +* Bugs fixed: + 574019 GChecksum: document and guarantee hex characters in lower case + 573454 Unable copy/move files to directories symlinked to gvfs share + 561172 gnome-open fails on local URIs with anchors + 573970 crash in gunixvolumemonitor:update_mounts when unmounting + 573843 g_get_current_dir returns non-absolute path + +* Updated translations: + Assamese (as) + Bengali (bn_IN) + Czech (cs) + Hindi (hi) + Italian (it) + Japanese (ja) + Lithuanian (lt) + Malayalam (ml) + Marathi (mr) + Oriya (or) + Polish (pl) + Romanian (ro) + Telugu (te) + + +Overview of Changes from GLib 2.19.8 to GLib 2.19.9 +=================================================== + +* GMarkup: + - Considerable speedup + +* GIO + - Add G_FILE_CREATE_REPLACE_DESTINATION flag to allow replacing + the destination of a copying operation as if it did not exit before. + - Be more careful when classifying files as desktop files + - Support desktop file key X-GIO-NoFuse which disables the use + of fuse pathnames for %u and %U arguments + +* Bugs fixed: + 572672 glib/gthread.c: argument is different type + 572464 Doc for g_file_get_contents + 572151 “it's†and “its†confused in docs and comments + 570501 g_win32_get_system_data_dirs uses invalid conversion... + 167569 g_string_append_printf crashes on win32 when used... + 572508 gmarkup speedup + 560564 Replacing a symlink with its linked file truncates... + 549298 impossible to copy files with p (pipe) flag + 543183 Clarify docs for g_file_has_prefix + 540461 g_memory_output_stream_get_data_size() doesn't behave... + 573462 GEmblemedIcon leak + 573421 Clarify message format in GMountOperation + 573658 Deadlock in giomodule.c + 556706 Inconsistent help arguments -h, -? + 573527 Wrong shell to run config.status in Makefile.in.in + 573128 A couple of typos in GObject documentation + +* Updated translations: + Catalan (ca) + British English (en_GB) + Spanish (es) + Basque (eu) + Finnish (fi) + French (fr) + Gujarati (gu) + Hebrew (he) + Hungarian (hu) + Korean (ko) + Maithili (mai) + Norwegian bokmÃ¥l (nb) + Dutch (nl) + Portugese (pt) + Swedish (sv) + Thai (th) + Traditional Chinese (zh_HK) + Traditional Chinese (zh_TW) + + +Overview of Changes from GLib 2.19.7 to GLib 2.19.8 +=================================================== + +* GIO: Fix missing exports of new API + +* Fix strict aliasing warnings and violations to make Glib work + with gcc 4.4 + + +Overview of Changes from GLib 2.19.6 to GLib 2.19.7 +=================================================== + +* GIO + - GFile gained an attribute for the actual file size in bytes + - GMountOperation gained an "aborted' signal that allows to abort + a mount operation from the backend side + +* Bugs fixed: + 523742 Use noinst for non-installable libraries + 566747 URIs opened with firefox %u load as local files + 541225 Can't compile gio on AIX duplicate case value in gioerror.c + 571598 GAsyncResult with NULL gobject + 505042 add file attribute for actually used file size in bytes + +* Updates translations: + Basque (eu) + Gujarati (gu) + Italian (it) + Japanese (ja) + Norwegian bokmÃ¥l (nb) + Dutch (nl) + Portugese (pt) + Thai (th) + Vietnamese (vi) + + +Overview of Changes from GLib 2.19.5 to GLib 2.19.6 +=================================================== + +* New format macro to print goffset data: G_OFFSET_FORMAT + +* GIO: + - Add a GFilter{Input,Output}Stream::close-base-stream properties which + determine whether the base stream will be closed when the filter stream + is finalized. + - g_data_input_stream_read_line and ..._read_until have asynchronous + variants now. + +* Bugs fixed: + 568294 A wrong reference in the description of g_bookmark_file_... + 563141 RFE: define G_OFFSET_FORMAT + 569105 g_time_val_to_iso8601() assumes time_t==long + 568394 dropping the last reference to a stream filter closes... + 568741 g_buffered_input_stream_fill_async doesn't work + 568723 g_buffered_input_stream_fill_async doesn't take count == -1 + 568575 _async functions for GDataInputStream + +* Updated translations: + Bulgarian (bg) + Finnish (fi) + Hungarian (hu) + Oriya (or) + Swedish (sv) + Traditional Chinese (zh_HK) + Traditional Chinese (zy_TW) + + +Overview of Changes from GLib 2.19.4 to GLib 2.19.5 +=================================================== + +* Update included PCRE to 7.8 + +* g_base64_decode_inplace: New function to do base64 decoding in place + +* Bugs fixed: + 567138 get_package_directory_from_module() does not free ... + 566569 gregex docs clarification + 566573 g_match_info_fetch_pos docs + 564728 Add function to decode base64 encoded data in place + 567838 G_STRUCT_OFFSETOF fails to compile under icc 9.1 + 567977 textdomain() macro should not return NULL ... + 512779 --disable-regex breaks compilation + 566770 error code 0 for Too many open files is useless + 565484 g_content_type_guess passes non-UTF8 text to XDG ... + +* Updated translations: + Catalan (ca) + Spanish (es) + Italian (it) + Swedish (sv) + + +Overview of Changes from GLib 2.19.3 to GLib 2.19.4 +=================================================== + +* GIO: + - Use O_NOATIME when sniffing mimetypes + - Add a convenience method to check if a GSimpleAsyncResult + is valid + +* Bugs fixed: + 560676 function access for g_threads_supported + 565905 There is no g_context_group_set_translation_domain + 564210 SUN Studio 12 has supported visibility attribute + 565136 GObject's "notify" signal parameters are wrong in gtk-doc + 565831 error in interface creation sample + 566348 g_file_open_tmp uses the wrong g_mkstemp on win32 + 566064 Add NOATIME flag to query_info_flags + 566170 g_async_result_verify_source_object + +* Updated translations: + Spanish (es) + Norwegian bokmÃ¥l (nb) + Brazilian Portugese (pt_BR) + Simplified Chinese (zh_CN) + + +Overview of Changes from GLib 2.19.1 to GLib 2.19.3 +=================================================== + +* Bugs fixed: + 508021 Add support for the CRIS and CRISv32 architectures + 526320 should not list mounts that the user doesn't have permission to use + 558458 Cannot build gio tests on Solaris using SUN cc + 555465 GUnix{Input,Output}Stream lacks fd/close_fd_at_close property + 558298 Hide ecryptfs mounts + 515777 incorrect date&time on copy + 562452 Ensure we return G_IO_ERROR_CANCELLED if cancelling + g_simple_async_result_run_in_thread + 473150 g_type_module_use inconsistently increases the use + counter in case of error + 563150 G_GU?INT*_MODIFIER/FORMAT docs + 563156 Document printing and scanning gunichar values + +* Updated translations: + Hebrew (he) + Italian (it) + + +Overview of Changes from GLib 2.19.0 to GLib 2.19.1 +=================================================== + +* GIO: + - g_icon_to_string, g_icon_new_for_string: GIcon serialization support + - G_FILE_ATTRIBUTE_PREVIEW_ICON: new file attribute for preview images + - g_app_info_get_commandline: new function to get the full commandline + - g_mount_shadow, g_mount_unshadow, g_mount_is_shadowed: New functions + to 'shadow' mounts (i.e. hide them from the UI when they already + have a different representation, like a bookmark) + +* Bugs fixed: + 556186 gpoll.h breaks gmain.h inclusion + 557087 mem leak in g_content_types_get_registered + 556921 gpoll.h breaks hal compilation + 557210 g_compute_checksum_for_* asserts with less than 2 bytes + 558381 Add support for compile time assertions + 558185 'parent' variable in g_local_file_get_child_for_display_name() + hits g_object_unref(NULL) assertion + 558513 g_warn_if_fail FIXME in gtestutils + 558672 NULL key lookup using g_hash_table_lookup_extended() + 555740 gicon serialization + 557182 preview functionality + 528320 Incorrect icons displayed for files with custom mimetype icons + 556910 Memory leak: sub + 557592 Missing include in gwinhttpfile.c + 556415 Crash on Windows 2000 in g_winhttp_vfs_init() + 555935 Clarify the mechanism of overwriting properties + 552776 ac_cv_func_posix_getgrgid_r not mentioned + 559448 GObject Reference Manual (typo) + 561212 GFileReadMoreCallback API doc refers to non-existant function + 560569 gkeyfile doesn't use the set list_separator in some cases + 560568 gkeyfile docs buglet + 559413 g_option_group_set_error_hook docs buglet + 562378 callback return value not respected for callback option + with no arg + 559110 Do not include libintl.h after glibintl.h + 557603 carbon check output misplaced + 562544 g_key_file_get_string and g_key_file_get_value + documentation does not explain the difference + 547264 Missing "no flags" flag + 562638 GDebugKey key member should be const + 562639 g_parse_debug_flags() parsing "help" + 562549 g_byte_array_free should tell how free data + 559452 GObject Reference Manual (typo) + 559462 GObject Reference Manual (typo) + 559517 GObject Reference Manual (typo) + 562538 GObject interface tutorial shouldn't finalise with + "Please forget everything" + 561352 Leak of icon description + 561375 Leaks mountpoint description + 561807 inotify_sub.c: dup_dirname() fails to remove trailing '/' + 562393 g_buffered_input_stream_read_byte broken if data available + 541715 win32 : patch for warnings and signature problems in recent code + 547481 g_data_input_stream_read_line behaves not as stated in the docs + 548163 Nautilus displays wrong error message for too long file names + 559633 gtk_image_new_from_gicon does not always work for .desktop files + 555486 – No way to recover command line from GAppInfo + +* Translation updates: + Spanish (es) + Ukrainian (uk) + + +Overview of Changes from GLib 2.18.1 to GLib 2.19.0 +=================================================== + +* Rewrite GHashTable to use open addressing with quadratic probing instead + of chaining. This has the potential to reduce memory fragmentation + significantly, while being slightly faster due to better locality and + no need to call alloc/free functions for nodes. Benchmarks suggest it + also uses less memory overall. + +* Make g_poll available as public api + +* New macros g_assert_error and g_assert_no_error to assert + that a GError is set or unset + +* g_cancellable_make_pollfd: New method to make a GPollFD for a cancellable + +* g_app_info_can_delete, g_app_info_delete, g_app_info_reset_type_associations: + New functions to clean up app infos and content types + +* When launching applications, always pass fuse file:// uris when possible, + and let gio convert such uris back to gio uris. + +* Bugs fixed: + 505361 gunixinputstream.c assumes poll() available + 509446 portable blocking gio cancellation + 553820 gpoll.c: undeclared identifier + 553724 python interpretter path not patched in correctly + 553857 gbacktrace.h requires signal.h + 553447 g_assert_no_error() + 554092 glib doesn't return G_FILE_ERROR_NOENT et al on OS X + 528670 Always pass file:/// uri's in GAppLaunchContext + 555224 Improve g_format_size_for_display doc + 555309 giochannel breaks on error + 554790 g_convert() misbehaves with winiconv versions + 555314 mem leak in gmarkup + 555313 GFileAttribute boxed type get_type function should... + 552861 glib-2.0.m4 calls system(3) without storing its result + 554557 Patch to fix gcc warnings about missing format specifiers + 552107 Small libtool fixes + 551355 Make glib build with libtool 2.2 + 555311 format not a string literal and no format arguments + 556101 static mutex yields warnings with g++ + 556186 gpoll.h breaks gmain.h inclusion + 526456 Open addressing in GHashTable + 553426 cancellable clarifications + 545350 GAppInfo deletion + 545351 Reset associations for content type + 552168 volume's mount not mounted after g_volume_mount_finish + 554970 segfault when update-desktop-database is not available... + 554745 GFileAttributeInfoList should be boxed + 555121 Improved build-time handling of gio module-dir + 555711 Wrong fallback order of mimetype icons + 555331 Deprecate adoption of mounts + 556335 make check fails in abicheck.sh + 556334 Warning when building without selinux support + 556422 g_file_enumerator_next_file: unclear... + +* Updated translations: + Arabic (ar) + Danish (da) + Polish (pl) + Brazilian Portugese (pt_BR) + Romanian (ro) + Russian (ru) + + +Overview of Changes from GLib 2.18.0 to GLib 2.18.1 +=================================================== + +* Bugs fixed: + 550433 g_test_init doesn't recognize --help + 523463 Core dump in gmain.c:2482:IA__g_main_context_check + 551228 G_STRFUNC on recent Sun compiler should be expanded... + 551410 gtestutils.c: using printf without prototype + 551731 g_date_set_time[_t] docs should mention what timezone + 548321 is not included in gi18n-lib.h + 551149 xdgmime mem leak + 550647 synchronous pipe I/O when reading mount reply + 551887 Docs for g_desktop_app_info_new_from_filename aren't... + 551681 g_content_type_guess() too naive with filenames + 552352 g_app_info_launch doesn't work if "Path" key... + 551408 gmodule.def generated to builddir... + 552359 g_file_info_get_icon should return GThemedIcon, and... + +* Updated translations: + Arabic (ar) + Bengali India (bn_IN) + British English (en_GB) + Hindi (hi) + Croatian (hr) + Korean (ko) + Oriya (or) + Turkish (tr) + Telugu (te) + + +Overview of Changes from GLib 2.17.7 to GLib 2.18.0 +=================================================== + +* Win32: + - rework the g_poll() implementation to match poll() semantics more closely + +* Bugs fixed: + 324234 Using g_io_add_watch_full() to wait for connect() to return... + 548278 Async GETs connections are always terminated unexpectedly... + 500246 Bug fixes for giowin32 + 523939 Example program for GValue + 550096 GBookmarkFile parser is not forward compatible + 550040 Move GString, rand and printf tests to the unit test framework + 550104 trivial documentation fix for g_get_home_dir + 548988 g_file_replace fails on Windows when the target file exists + 550059 Wrong docs for g_emblemed_icon_add_emblem + 548800 Missing a g_object_get_type function + 550056 Missing documentation for g_emblemed_icon_get_emblems + +* Updated translations: + Bulgarian (bg) + Czech (cs) + German (de) + Estonian (et) + Basque (eu) + French (fr) + Hebrew (he) + Hungarian (hu) + Italian (it) + Japanese (ja) + Lithuanian (lt) + Maithili (mai) + Dutch (nl) + Swedish (sv) + Thai (th) + Ukrainian (uk) + Vietnamese (vi) + + +Overview of Changes from GLib 2.17.6 to GLib 2.17.7 +=================================================== + +* More fixes for 64-bit Windows + +* GIO + - Add a vfs implementation for HTTP and HTTPS URIs on Windows + +* Bugs fixed: + 546329 API docs for g_utf8_normalize() are incorrect + 546876 Modify GMarkup parser to accept  ..  + 547200 g_utf8_find_next_char() issues + 547637 unconditional #include of sys/statfs.h in configure + 547337 G_DISABLE_DEPRECATED breaks tests build + 547832 gtk+-2.12.11 fails to build - AC_PROG_MMAP too strict + 502498 Test framework assertion failures should follow gcc + 546371 Improve docs re g_file_monitor + 546483 GThemedIcon:use-default-fallbacks is not readable without... + 546132 GFileIcon is bindings-unfriendly + 542156 zfs mount in home directory shown on nautilus desktop + 535124 umask 002 not being applied for new directories... + 547080 g_file_copy leaks expected errors + 546582 Callbacks from GFileMonitor present a GFile... + 547262 Missing link in the docs + +* Updated translations: + Arabic (ar) + Catalan (ca) + Spanish (es) + Basque (eu) + Finnish (fi) + Galician (gl) + Hebrew (he) + Marathi (mr) + Norwegian bokmÃ¥l (nb) + Portugese (pt) + Brazilian Portugese (pt_BR) + Swedish (sv) + Thai (th) + + +Overview of Changes from GLib 2.17.4 to GLib 2.17.6 +=================================================== + +* Fix problems on 64-bit Windows + +* g_markup_context_get_user_data: New function to access + the user_data outside of callbacks + +* GIO + - g_mount_guess_content_type_sync: synchronous version of + g_mount_guess_content_type + - GEmblem: A GIcon implementation that adds emblem-related + metadata to icons + - GEmblemedIcon: A GIcon implementation that can add emblems + to icons + +* Bugs fixed: + 544088 option_test_LDADD is left in tests/Makefile.am + 544465 gmarkup makes it hard to use pre-rolled parsers + 545485 Implicit declaration of utime() + 545798 "Since: 2.18" mark is missing in g_set_error_literal... + 544140 fam-helper 64-bit issue + 529694 SELinux context setting support + 545157 wrong/no list of "open with" applications for .cc... + 545203 gfile.c: argument is different type + 545457 gdmsetup crashed with SIGSEGV in g_unix_mount_guess... + 544177 Fix trivial cut and paste error in documentation + 545395 Language tweak for g_value_set_string* docs + 541036 Gnumeric crashes when trying to open Desktop... + 546079 leak in xdgmime + 545395 Language tweak for g_value_set_string* docs + 546017 Don't copy attributes when copying a symlink + +* Updated translations: + Arabic (ar) + Estonian (et) + Galician (gl) + Italian (it) + Japanese (ja) + Korean (ko) + Norwegian bokmÃ¥l (nb) + Pashto (ps) + Portugese (pt) + + +Overview of Changes from GLib 2.17.3 to GLib 2.17.4 +=================================================== + +* GIO: + - New API to handle content types: g_mount_guess_content_type, + g_content_type_guess_for_tree. + - Export the eject-button signal on the volume monitor class + - New API to enable out-of-process volume monitors: + g_volume_get_activation_root + +* GObject: + - New API to handle signals without slots in the class structure: + g_signal_new_class_handler, g_signal_override_class_handler + +* Internationalization: + - Add an NC_ macro that is a no-op equivalent of C_ + +* GMarkup: + - Add two new functions g_markup_parse_context_push, + g_markup_parse_context_pop to support "subparsers" + +* Bugs fixed: + 541208 Functions to easily install and use signals without... + 541507 Ambiguous description of assigned characters in the... + 543040 async reading on dummy file will crash on GIO_USE_VFS=local + 543560 enable gio-FEN back-end warnings on Solaris will crash... + 528317 GRegex does not allow recursion limit + 337518 GMarkup: Subparser support + 541794 drive-eject-button signal + 541793 activation root for volumes + 467707 test_iconv_state() in tests/convert-test.c fails on AIX 5.3 + 428048 2 of 51 tests fail on Solaris + 542332 small fix for error message in GMarkup + 482413 get_contents_stdio -- overflow and memory corruption + 406120 g_ascii_strtod + 334234 "printf" format error + 536996 Missing noop i18n macro equivalent to C_ + 540616 mem leak in filechooser button + 539229 gobject-query calls itself query + 521589 [RFC] gobject documentation should mention Vala + 543168 Description of G_SLICE=debug-blocks discourages its use + 543220 Case collision on gio-extension-points.html + 530759 update the gobject tutorial to the XXI century + 535223 gbookmark file inefficiency ... + 543504 crash in Epiphany Web Browser: Opening local file + +* Updated translation: + German (de) + Estonian (et) + Pashto (ps) + Albanian (sq) + Thai (th) + Traditional Chinese (zh_HK) + Traditional Chinese (zh_TW) + + +Overview of Changes from GLib 2.17.1 to GLib 2.17.3 +=================================================== + +* PCRE + - fix for CVE-2008-2371 + +* Bugs fixed: + 538119 glib's mainloop leaks a pipe to sub-processes + 537635 Corrections and improvements to g_time_val_{to,from}_iso8601 + 539067 The document g_io_channel_win32_new_fd() says... + 535949 annotate g_strip_context and g_dpgettext with G_GNUC_FORMAT + 539123 annotate g_d[n]gettext with G_GNUC_FORMAT + 539074 Cannot get exit status with g_spawn_command_line_sync + 316221 G_LOCK warns about breaking strict-aliasing rules + 539770 migrate gstrfunc unit tests to gtest + 539626 Update docstrings for g_object_freeze_notify and g_object_thaw_notify + 538044 unconditional use of LC_MESSAGES + 540545 Monotonic time and timer offset + 535947 want g_set_error_literal + 539999 glibconfig.h: add GLIB_USING_SYSTEM_PRINTF + 536252 GFileEnumerator should allow access to the containing GFile + 538362 Get Win32 icons back in the file chooser + 540802 g_list_prepend doesn't concat lists + 540423 unrecoverable error after g_seekable_truncate + 538836 make check failure on PPC and ALPHA: pltcheck.sh on g_atomic_pointer_get + 539090 g_content_type_from_mime_type() should unalias + 540331 g_file_append_to () documentation: can return NULL + 534639 add g_desktop_app_info_new_from_keyfile + 536733 gio build failure on Irix + 536160 Add g_file_monitor() + 538127 FileChooser broken on win32 + 531476 /live-g-file/test_traverse_structure test fails on Mac HFS+ + 538564 gio should have gio-types.h + 540047 glib-genmarshal.c: '#include ' is too before + +Updated translations: + Korean (ko) + Occitan (oc) + + +Overview of Changes from GLib 2.17.0 to GLib 2.17.1 +=================================================== + +* New function: g_utime(), a gstdio wrapper for utime() + +* New functions: g_dgettext() and g_dngettext(), wrappers + for corresponding gettext functions with added functionaliy + +* Support the latest version of the shared-mime spec, including + icons for mime types + +* New function: g_themed_icon_prepend_name() + +* Bugs fixed: + 535418 Please document which glib version defines goffset + 528715 Misprint in the description of the interface g_type_class_add_private + 528714 Misprint in the description of the interface g_param_spec_flags + 537260 Doc bug in G_TYPE_INSTANCE_GET_CLASS() + 530527 Misprint in the description of the interface + g_cclosure_marshal_VOID__FLAGS + 530526 Misprint in the description of the fields 'class_init' and + 'class_finalize' of the structure GTypeInfo + 528719 Improvement to the documentation of the "g_object_connect" interface + 528172 gtk_signal_handlers_unblock_* functions return value + amount of matched signals, not amount of actually unblocked + 528717 Misprint in the description of the parameter 'type_id' for + the interface g_type_register_fundamental + 528716 Misprint in the description of the parameter 'iface_data' for + the callback types GInterfaceInitFunc and GInterfaceFinalizeFunc + 537555 GObject instantiation not thread safe + 537546 'desktop' shortcut in file chooser looks like a generic folder + 537392 Additional colon in xattr name + 536641 Filesystem querying in gio does not list AFS and autofs file systems + 528600 g_dummy_file_get_parent("scheme://example.com/") + 503071 Application direction changes to right to left even if theres no + translation + 502511 g_assert_cmphex prints invalid message + 338162 Use po/LINGUAS + 314453 Nautilus crashes in Solaris when browsing the attached file + 529321 make check fails in glib/pcre + 455215 g_get_user_special_dir: no reference about G_USER_DIRECTORY_DOWNLOAD + fallback to $HOME/Desktop if xdg-user-dirs is not in use + 498732 g_key_file_to_data cannot fail + 511367 add g_file_make_directory_with_parents + 531900 Use __builtin_offsetof for G_STRUCT_OFFSET if building with + gcc 4.0 or newer + 536158 also bump GHashTable version when a node is removed via + g_hash_table_iter_remove()/g_hash_table_iter_steal() + 531403 g_utf8_collate broken on Mac + 535628 test/patterntest.c still includes gpattern.h directly + 535625 alias.h:2648: error: 'utime' undeclared here (not in a function) + +* Translation updates: + Arabic (ar) + German (de) + Italian (it) + Norwegian bokmÃ¥l (nb) + Thai (th) + + +Overview of Changes from GLib 2.16.x to GLib 2.17.0 +=================================================== + +* Update to Unicode 5.1 + +* Update included libcharset to the one shipped with libiconv 0.12 + +* Update included PCRE to 7.7 + +* Enforce that only toplevel headers are directly included. + This is turned on by default for GObject and GIO. To turn + it on for GLib, define G_DISABLE_SINGLE_INCLUDES. + +* Fix library version of GIO. GLib 2.16 shipped with libgio-2.0.so.0.0.0 + +* On Solaris, use FEN for file monitoring in GIO + +* Use the GIO_EXTRA_MODULES environment variable to find + additional GIO modules + +* G_GNUC_ALLOC_SIZE: New macro that wraps the gcc alloc_size + function attribute + +* g_checksum_reset: New function to reset the state of a GChecksum + +* g_unix_mount_monitor_set_rate_limit: New function to limit the + rate at which events are reported + +* g_file_query_file_type: New utility function to query the type of + a file + +* g_memory_output_stream_get_data_size: New function to obtain the + size of the written data. + +* Bugs fixed: + 522292 Gives warnings in glib/gutils.h with GCC in C99 mode + 523298 win_iconv can't convert from UTF-8 to GB18030 (or vice versa) + 518160 replace two g_strdup_printf calls in GBookmarkFile + 523877 gbookmarkfile: avoid using g_string_append_printf() and + other optimizations + 525192 100% CPU if run main loop with no IO sources + 315437 extern inline -> static inline + 524314 g_convert() on Win32 implicitly converts full width + alphanumerics into half width + 525732 Error in documentation for g_list_first + 525674 A typo in gmarkup.c + 448943 g_timeout_add_seconds() problems + 525972 UCS-4 not in the new win_iconv implementation + 526619 make test-report crash + 491554 Update to Unicode 5.1.0 + 519137 g_slice_dup macro needs cast for 64-bit platform + 528752 Win32 build and SSL not working + 530457 G_USER_DIRECTORY_DOWNLOAD folder improperly mapped + 528667 Typos in testing module documentation + 459905 Bug in wcwidth data + 534085 g_unichar_iswide_cjk() has a totally wrong table + 501651 Update glib/libcharset + 519026 G_STMT_START/G_STMT_END test a non-existent preprocessor symbol + 534319 GLib's .pc files could use Libs.private + 534137 Typo in g_spawn_async_with_pipes doc + 517419 gio win32 directory monitor + 526796 Wrong order of arguments in g_file_copy's fallback + 530196 _g_local_file_has_trash_dir() doesn't handle st_dev == 0 + 532965 Should not return filesystem::free for certain file systems + 525553 fix typo and nitpicking in GArray documentation + 526572 Missing * in declaration of parent_class in Object + Destruction section of GObject Reference Manual + 528648 Extra >s in Object Construction section + 535021 g_param_spec_internal documentation should + describe purpose of nick and blurb + 521513 Firefox crash when using file picker + 528433 gdesktopappinfo snafu ... + 533369 API g_file_info_get_attribute_string () unables to get "... + 521045 glib f_fstypename miscellany + 521672 compile error + 521946 control rate limit on GUnixMountMonitor + 522335 Fails to build: glib/gtester.c:276: error: 'ARG_MAX' unde... + 523015 Implement sliding window based upload operation + 523019 Use new GCC 4 feature + 523338 list nfs4 as a nfs mount type + 524350 Make glib build without NLS again + 524579 g_file_copy reports wrong total on progress callback for ... + 524742 A typo in gtestutils.c. + 524950 Minor documentation typos. + 525866 the user directory should not be considered as a mount to... + 526320 should not list mounts that the user doesn't have permiss... + 527132 nautilus crash when making ftp connection + 532852 CRITICAL **: totem_pl_parser_parse_with_base: assertion `... + 534759 Build failure in gio + 534764 Typo in error produced by g_file_make_directory + 521851 Redudant tests in gunixmounts.c + 524344 glib/gthread.h still use G_GNUC_PRETTY_FUNCTION + 525060 glib fails to build with -DG_DISABLE_ASSERT in CPPFLAGS o... + 534177 Invalid description of the interface g_cclosure_marshal_S... + 520715 Add GFile method g_file_query_file_type + 523039 nautilus can't access to trash/computer/network if gvfs i... + +* Updated translations: + Arabic (ar) + Bulgarian (bg) + Catalan (ca) + Czech (cs) + Greek (el) + Candian English (en_CA) + British English (en_GB) + Spanish (es) + Estonian (et) + Basque (eu) + Galician (gl) + Hebrew (he) + Hungarian (hu) + Japanese (ja) + Lithuanian (lt) + Norwegian bokmÃ¥l (nb) + Dutch (nl) + Occitan (oc) + Portugese (pt) + Russian (ru) + Slovak (sk) + Albanian (sq) + Swedish (sv) + Turkish (tr) + Vietnamese (vi) + + +Overview of Changes from GLib 2.16.0 to GLib 2.16.1 +=================================================== + +* Fix a crash in g_themed_icon_new + +* Update the included PCRE to 7.6 + + +Overview of Changes from GLib 2.15.6 to GLib 2.16.0 +=================================================== + +* Fix the definition of G_INLINE_FUNC to work with gcc 4.3.0 + +* GIO: + - Add missing GMountMountFlags argument to g_unix_volume_mount + - Fix the adopt_orphan_mount vfunc to take a volume monitor + reference + - Add properties to GThemedIcon for bindings sake + +* Bugs fixed: + 520484 gvfsd-trash crashed with SIGSEGV in g_path_is_absolute() + 510855 g_checksum_update(): Take -1 for length. + 517676 g_themed_icon_new*() do more than call g_object_new(). + 518816 should handle rmdir returning EEXIST correctly + 519352 g_[s]list_delete_link() docs + 519489 Fixes for sparse warnings in gio + 520169 add monitor argument to vfunc for GVolumeMonitor + 520700 Add type check in g_file_query_exists + 521145 FILE_READ_ONLY_VOLUME not present on Mingw32 + 518720 No MIME type for empty files + 521013 in documentation, goffset doesn't say "Since 2.x" + 521028 Missleading error messages from g_io_channel_set_encoding() + 517484 GMainLoop could set the thread "Alertable" for APCs to be... + +* Updated translations: + Assamese (as) + Bengali India (bn_IN) + Czech (cs) + German (de) + Spanish (es) + Estonian (et) + Finnish (fi) + French (fr) + Gujarati (gu) + Italian (it) + Lithuanian (lt) + Malayalam (ml) + Marathi (mr) + Norwegian bokmÃ¥l (nb) + Romanian (ro) + Russian (ru) + Slovak (sk) + Ukrainian (uk) + + +Overview of Changes from GLib 2.15.5 to GLib 2.15.6 +=================================================== + +* GIO: + - New file attributes: trash::item-count, filesystem::use-preview + - Rename g_file_contains_file to g_file_has_prefix + - g_file_query_filesystem_info grew async variants + - g_themed_icon_append_name: new convenience function + - g_content_type_get_icon is implemented now + - Only show mounts in /media and ~ + - g_file_contains_file has been renamed to g_file_has_prefix + +* Win32: + - g_win32_get_package_installation_directory_of_module: new function + which supersedes g_win32_get_package_installation_directory + - Use alertable wait functions so that I/O completion routines or + user-mode Asynchronous Procedure Calls can be run + - Fix race conditions in g_spawn implementation on win32 + +* Other: + - g_uri_get_scheme has been renamed go g_uri_parse_scheme + +* Updated translations: + Arabic (ar) + Belarusian Latin (be@latin) + Catalan (ca) + British English (en_GB) + Finnish (fi) + Galician (gl) + Hebrew (he) + Italian (it) + Kannada (kn) + Norwegian bokmÃ¥l (nb) + Dutch (nl) + Brazilian Portugese (pt_BR) + Vietnamese (vi) + + +Overview of Changes from GLib 2.15.4 to GLib 2.15.5 +=================================================== + +* Update the included PCRE to 7.6 + +* GIO: + - g_volume_should_automount: new function to determine if a volume + should be mounted automatically + - g_file_query_default_handler: new convenience function to get + the default handler for a file + - g_app_info_launch_default_for_uri new convenience function to + launch the default handler for a URI + - Use mimeapps.list and defaults.list as discussed on xdg list + recently + - g_app_info_get_default_for_uri_scheme has a real implementation + now (gvfs provides a GConf-based implementation) + - There is the beginning of a test suite + - standard::description: new file attribute + - GMountMountFlags flags argument added to mount calls + +* GObject: + - class initialization is now threadsafe + +* Updated translations: + Arabic (ar) + Catalan (ca) + Spanish (es) + Basque (eu) + Italian (it) + Japanese (ja) + Kannada (kn) + Korean (ko) + Macedonian (mk) + Occitan (oc) + Portugese (pt) + Brazilian Portugese (pt_BR) + Swedish (sv) + Thai (th) + + +Overview of Changes from GLib 2.15.3 to GLib 2.15.4 +=================================================== + +* G_GNUC_PRETTY_FUNCTION has been deprecated + +* GIO: + - g_file_copy has an async variant now + - Drives and volumes now have API to get identifiers + like Hal UDIs or UUIDs. + - There is now a registration API to let modules register + extensions they provide, such as volume monitor implementations + +* Bugs fixed: + 511807 g_time_val_to_iso8601() uses MT-unsafe gmtime() function + 316260 [patch] Doc patches for gnode (2.8.1) + 385132 solaris gettext support fix + 484261 ./configure check for system PCRE unicode support fails w... + 510292 GOption main help not shown + 511580 Implement g_file_copy_async + 511654 Compile errors due to C99 constructs + 487909 g_utf8_strreverse and combining marks + 512381 unused variable 'is_main_group' + +* Updated translations: + Arabic (ar) + Belarusian (be) + Czech (cz) + Spanish (es) + French (fr) + Galician (gl) + Portugese (pt) + Russian (ru) + Swedish (sv) + Thai (th) + + +Overview of Changes from GLib 2.15.2 to GLib 2.15.3 +=================================================== + +* GChecksum: + - g_checksum_update can accept nul-terminated strings + - The MD5 implementation works correctly on buffers + that are longer than 64 bytes + +* GIO: + - Don't include a copy of the inotify headers, rely on system headers + - g_file_find_enclosing_mount has an async variant now + - Reduntant seek API on file streams has been removed + +* Bugs fixed: + 508602 gmemory{in|out}putstream.c: unknown pointer size + 508771 There is no g_file_test/exists() for GFile + 508773 g_uri_escape_string() documentation unclear. + 509465 AM_PATH_GLIB_2_0 doesn't support gio + 509626 async functions: Document allowed NULL callback? + 509990 GSeekable documentation unclear + 510448 No inotify support on ARM or SH5 + 510855 g_checksum_update(): Take -1 for length. + +* Updated translations: + Basque (eu) + Marathi (mr) + Swedish (sv) + Ukrainian (uk) + + +Overview of Changes from GLib 2.15.1 to GLib 2.15.2 +=================================================== + +* GIO: + - Mount operation API change: unhandled methods get reported via + the reply, rather than by the signal emission return value + - File monitor API change: Add a GError argument to g_file_monitor_file + - g_unix_mount_guess_should_display(): new function + +* Bugs fixed: + 508224 [PATCH] FAM backend crashes due to double free + 508074 GAsyncResult documentation suggests g_freeing it. + 508108 GFile documentation slightly unclear. + 508309 rpc_pipefs mount points should be hidden + 508378 GFileInfo documentation implies that it changes attribute... + 508719 g_file_get_relative_path fails if parent is root + 508773 g_uri_escape_string() documentation unclear. + +* Updated translations: + Arabic (ar) + Spanish (es) + Hebrew (he) + Italian (it) + Korean (ko) + Turkish (tr) + + +Overview of Changes from GLib 2.15.0 to GLib 2.15.1 +=================================================== + + * Portability fixes: + - Assertion functions are marked as noreturn again + - Handling of inline functions has been fixed to work with gcc 4.3 + - C99 comments have been removed from headers + - The nonportable sed -i option is no longer used + + * GIO: + - Clarified the semantics of g_app_info_get_all() + - API for memory input and output streams has been changed a bit + - GDirectoryMonitor has been removed; GFileMonitor can monitor + files and directories now + + * Bugs fixed: + 504829 Invalid environment passed to g_spawn_async in g_desktop_... + 505258 crash in Users and Groups: Adding a user + 505815 g_content_types_get_registered should not g_free keys + 491218 g_timer_new() doesn't initialize timer->end + 315437 extern inline -> static inline + 476856 Inconsistency between standard and implementation of the ... + 480122 g_module_open fails to open modules with ".la" extension + 495589 gspawn.c failing to set FD_CLOEXEC + 500273 doesn't build with --disable-visibility + 504142 Do not show empty groups in --help output + 504879 giofam incorrectly linked + 505042 add file attribute for actually used file size in bytes + 505058 xattr namespace docs + 505674 Misprint in the definition of the macro G_CCLOSURE_SWAP_DATA + 505730 Fails to build on OSX 10.4: _NSGetEnviron not declared + 505887 older darwin lacks lchown + 506374 gmemoryinputstream api + 506461 Conversion of g_assert_not_reached() and friends into fun... + 503051 Small bug in glib interface + 506395 Updates to GIO documentation + 507628 Missing .pc entry for gio linking against glib + 505195 [patch] typo in g_try_new0 docs + 507822 g{file,directory}monitor changes signal problem + 506377 gmemoryoutputstream write implementation + 507835 bug in gunixinputstream + + * Updated translations: + Arabic (ar) + Belarusian Latin (be@latin) + Spanish (es) + Basque (eu) + Irish (ga) + Hebrew (he) + Occitan (oc) + Vietnamese (vi) + + +Overview of Changes from GLib 2.14.x to GLib 2.15.0 +=================================================== + +Major new features: + + * GIO: a VFS API, designed to replace GnomeVFS. The GIO implementation + in GLib has support for local filesystems. The new, separate gvfs + module contains various backend implementations (cifs, ftp, sftp, + http, ...) + + * GChecksum: provides various hash algorithms, such as MD5, SHA-1 + and SHA-256 + + * GTest: a test framework + +Smaller additions: + + * GHash: + - GHash has iterators, as an alternative to g_hash_table_foreach + + * GMarkup: + - g_markup_parse_context_get_element_stack: New function to + get the stack of open elements + - G_MARKUP_PREFIX_ERROR_POSITION: New flag to improve error + reporting + - g_markup_collect_attributes: Convenience function for handling + attributes + +* GKeyFile: + - Functions that take a GError now return a boolean to indicate + success, instead of void + - Various performance improvements + +* GAsyncQueue: + - g_async_queue_new_full: new function that allows to specify + a free function for leftover elements + +* GError: + - g_prefix_error and g_propagate_prefixed_error: New functions + to ease error propagation + +* Internationalization: + - C_: A new 2-argument variant of the Q_() macro + - Use native character set conversion API on Windows + +* GLib builds with automake 1.10 + +* Bugs fixed: + 455725 specific combination of g_utf8_strlen and g_pattern_match... + 467537 g_convert_with_iconv() not resetting iconv() state correc... + 497033 Commandline option parser should warn about missing optio... + 504527 gchecksum: Conditional jump or move depends on uninitiali... + 445362 Non-numeric local labels in gatomic.c are causing linker ... + 482313 gregex: no way to tell why compilation failed + 317775 main loops continues to run after g_main_loop_quit() has ... + 418778 Insufficient pkg-config version requirement + 436293 g_option_context_new() doc should mention that the string... + 466557 glib-mkenums shifts ARGV[0] to undefined + 468882 GKeyFile doesn't accept "True" as a true boolean value + 469551 application --help messages are garbaged on none UTF-8 lo... + 479724 Memory leak upon calling "g_main_loop_run" in the seconda... + 490061 outptrs uninitialized after g_parse_long_long + 490637 gobject documentation patch + 495294 glib-genmarshal prints warnings but returns 0 + 496046 option to prefix location of errors for GMarkup + 498113 tests/regex-test fails on 64bit environment + 500506 Fails to build on OSX 10.4 + 500638 gkeyfile speedup ... + 500875 Make check fails as there is no "test" target for "build"... + 502511 g_assert_cmphex prints invalid message + 502927 g_array_index triggers cast aligment warning + 503029 g_time_val_from_iso8601 parse non-ISO8601 dates + 503222 Need context to translate + 503420 gkeyfile leaks a hash table + 503470 Fix build when builddir != srcdir + 504227 Inverse variant for g_test_trap_assert_stdout, g_test_tra... + 71704 file include order + 491957 Misprint in the specification of the interface "g_main_co... + 491959 Misprint in description of the structure "GThreadPool" + 491965 Mistype in the specification of the function "g_hook_list... + 491966 Misprint in the specification of the interface "g_main_co... + 491968 The documentation does not mention the restriction for th... + 491970 The documentation for the interface "g_date_clamp" is inc... + 491974 The documentation of the interface "g_main_context_iterat... + 491975 The documentation for the interfaces "g_io_channel_read_u... + 491979 Misprint in the description of the interfaces g_key_file_... + 491982 Misprint in the description of the interface "g_key_file_... + 501107 EXTRA_DIST automake warnings + 501997 g_utf8_normalize() returns NULL on invalid string + 502590 C_/g_dpgettext efficiency + 464259 g_set_application_name() docs should say "Since 2.2" + 496518 gbase64.c API doc clarification + 498728 g_key_file_get_*_list should set length to 0 when returni... + 500361 Improve docs for g_array_free() and g_ptr_array_free() + 501853 g_checksum_get_digest docs + 503862 Allow NULL strings in g_parse_debug_string() + 142676 Q_ + 367550 Add g_async_queue_new_full() with GDestroyNotify function + 375651 Minor enhancements to GKeyFile API + 443648 MD5 digest support + 449937 Upgrade auto* sources to be clean under automake1.9 + 452887 gmarkup context "get element" function is useless when ca... + 491549 [PATCH] Eliminate libiconv dependency on Windows + 500507 GHashTableIter API + +* Translation updates + Belarusian Latin (be@latin) + Czech (cs) + German (de) + Spanish (es) + Esperanto (et) + French (fr) + Korean (ko) + Marathi (mr) + Norwegian bokmÃ¥l (nb) + Brazilian Portugese (pt_BR) + Slovenian (sl) + Swedish (sv) + + +Overview of Changes from GLib 2.14.2 to GLib 2.14.3 +=================================================== + +* Update PCRE to 7.4 + +* Bugs fixed: + 487491 Fix some warnings from sparse + 488068 Small (one-time) memory leak in glib_gettext initialization + 493688 TYPE macro "_get_type ()" is documented wrong + +* Updated translations: + Arabic (ar) + Belarusian Latin (be@latin) + Estonian (et) + Irish (ga) + Slovenian (sl) + + +Overview of Changes from GLib 2.14.1 to GLib 2.14.2 +=================================================== + +* Bugs fixed: + 476849 Invocation of the interface "g_hook_free" fails in certai... + 359165 marshallers can throw warnings with -Wunused + 477957 more discussion on g_value_set_object vs. g_value_take_ob... + 478459 G_DEFINE_DYNAMIC_TYPE_EXTENDED doesn't work with G_IMPLEM... + 483337 inline is disabled for MSVC when compiling C code + 478349 Broken link to gettext website + 469231 g_spawn optimization for setting all open fds to CLOEXEC + +* Updated translations: +Arabic (ar) +Galician (gl) +Hebrew (he) +Korean (ko) + + +Overview of Changes from GLib 2.14.0 to GLib 2.14.1 +=================================================== + +* Bugs fixed: + 476840 Invocation of the interface "g_utf8_strreverse" crashes f... + 444765 Fix FIXME in gregex.c when new pcre is out + 464145 g_markup_escape_text Produces Invalid XML + 465625 g_type_default_interface_ref() does not ensure working g_... + 466768 Clearify that comments can be put anywhere in a Key-file. + 474229 The GError documentation should give convention for the G... + 474899 G_BREAKPOINT() docs inaccurate + 475854 Overuse of -lpcre when using system pcre + 473879 Incorrect includes in gregex.c + 468694 Typoes in documentation + 469051 g_snprintf () talks about characters where it probably me... + 457601 Missing arch specific atomic implementation + 475923 Missing pcre flags when static-linking against glib + 475619 glibthread-2.0.la does not list -lpthread + +* Updated translations: + Bulgarian (bg) + Catalan (ca) + Danish (da) + German (de) + Canadian English (en_CA) + British English (en_GB) + Spanish (es) + Estonian (et) + Finnish (fi) + French (fr) + Gujarati (gu) + Hungarian (hu) + Italian (it) + Georgian (ka) + Kannada (kn) + Lithuanian (lt) + Makedonian (mk) + Norwegian (nb) + Dutch (nl) + Polish (pl) + Portugese (pt) + Brazilian Portugese (pt_BR) + Romanian (ro) + Russian (ru) + Albanian (sq) + Serbian (sr, sr@Latn) + Swedish (sv) + Tamil (ta) + Thai (th) + Ukrainian (uk) + Vietnamese (vi) + + +Overview of Changes from GLib 2.13.7 to GLib 2.14.0 +=================================================== + +* Last-minute API additions: + - Make g_unichar_combining_class public + - Add goffset type, add G_MAXSSIZE and G_MINSSIZE + +* Update PCRE to 7.2 + +* Bugs fixed: + 453998 Make _g_unichar_combining_class() public + 462549 gregex.c: variable is declared at middle of block + 417068 g_file_test doc inconsistency + +* Updated translations: + Assamese (as) + Basque (eu) + Kannada (kn) + Malayalam (ml) + Dutch (nl) + Polish (pl) + Brazilian Portugese (pt_BR) + Turkish (tr) + + +Overview of Changes from GLib 2.13.6 to GLib 2.13.7 +=================================================== + +* The memory corruption warning from the slice allocator that + occurred when threads were initialized after the slice allocator + has been removed, as the slice allocator now works fine + in this scenario. + +* New functions g_once_init_enter() and g_once_init_leave() make + it easier to write threadsafe one-time initialization functions + +* Bugs fixed: + 454473 Simple XML Subset Parser terminates on invalid XML + 445813 g_module_open error, add file name + 453796 errno gets clobbered by g_filename_display_name + 341988 don't use "-c" with msgfmt in Makefile.in.in + 447048 Please produce slightly more output during long tests + 454785 GModule documentation lists same block of code twice. + 454786 GModule documentation lists same paragraph twice. + 383155 small docs quirks in gobject/closure API documentation + 65041 _get_type() functions aren't thread safe + +* Updated translations + Assamese (as) + Spanish (es) + Gujarati (gu) + Japanese (ja) + Korean (ko) + Macedonian (mk) + + +Overview of Changes from GLib 2.13.5 to GLib 2.13.6 +=================================================== + +* Reintroduce a GType typedef whose removal in 2.13.5 + caused trouble for C++ bindings + +* Bugs fixed: + 450216 docs not explicit enough about g_free() + 451459 g_type_register_static_simple calls g_type_register_static + +* Updated translations + Norwegian bokmÃ¥l (nb) + Sinhala (si) + + +Overview of Changes from GLib 2.13.4 to GLib 2.13.5 +=================================================== + +* xdg-user-dirs support: + - the Desktop directory is guaranteed to be defined + - user-dirs.dirs is no longer reloaded on changes + +* Slice allocator: + - new api to duplicate slices + +* Regular expression support: + - GRegex is a boxed type now + +* Bugs fixed: + 44793 make check failing in trunk + 354522 Small problem with PLT hiding 6 symbols + 363986 glib 2.12.4 does not compile with SGI IDO cc + 443869 g_type_class_add_private doesn't warn when adding 0-sized... + 446859 Legitimately return 0 for g_quark_from_string(NULL) + 447534 Small typo in g_timeout_add_seconds() doc + 447583 GStaticRWLock + 447935 g_get_current_dir SIGSEGV on long path + 448260 CLAMP has surprising result if low > high + 57693 g_string_vprintf() + 442029 add g_slice_dup() + 445065 Add GRegex boxed type + 448819 Add full version of g_timeout_add_seconds() + +* Updated translations: + Swedish (sv) + Oriya (or) + Hebrew (he) + Spanish (es) + Estonian (et) + + +Overview of Changes from GLib 2.13.3 to GLib 2.13.4 +=================================================== + +* Bugs fixed: + 444121 g_get_user_special_dir deadlocks + 444161 invalid UTF8 in key name shows up as valgrind error in g_... + 444130 g_option_context_get_help() is broken when there's a desc... + + +Overview of Changes from GLib 2.13.2 to GLib 2.13.3 +=================================================== + +* GKeyFile: + - Added defines for easier handling of desktop files + +* Unicode support: + - Update g_unichar_iswide_cjk for Unicode 5.0 + +* Regular expression support: + - GRegex structs can now be ref-counted + - Some new functions for dealing with incremental + replacement have been added + - The GRegexEvalCallback signature has been changed + +* g_get_user_special_dir() has been added to support + xdg-user-dirs + +* Bugs fixed: + 419376 Functions using named subpatterns behave inconsistently w... + 434358 g_regex_fetch_named() and g_regex_fetch_named_pos() are b... + 423708 typo in the README.win32 file see patch below + 339225 Add new defines for easier handling of .desktop files + 442265 API additions/changes for GRegex + 432651 Add a glib-ish xdg_user_dir_lookup + +* Updated translations: + Estonian (et) + Norwegian bokmÃ¥l (nb) + + +Overview of Changes from GLib 2.13.1 to GLib 2.13.2 +=================================================== + +* Unicode support: + - Add g_unichar_ismark() + +* GOption: + - Allow to use callbacks for remaining args + +* Updated translations: + Belarusian Latin (be@latin) + British English (en_GB) + Galician (gl) + Norwegian bokmÃ¥l (nb) + Oriya (or) + Spanish (es) + Thai (th) + + +Overview of Changes from GLib 2.13.0 to GLib 2.13.1 +=================================================== + +* GRegex: + - Portability fixes + - Split into immutable GRegex and GMatchInfo + - Add g_regex_get_max_backref() and g_regex_get_capture_count() + to obtain information about the compiled regex + +* GKeyFile: + - Fix roundtrip problems + - Add g_key_file_load_from_dirs() + +* Unicode support: + - Fix corner cases in case conversion routines + +* GOption: + - Add a function to get the formatted help string + +* GHash: + - Add new functions g_hash_table_get_keys() and + g_hash_table_get_values() to retrieve the keys and + values in list form + +* Updated transations: + Simplified Chinese (zh_CN) + Arabic (ar) + + +Overview of Changes from GLib 2.12 to GLib 2.13.0 +================================================= + +* Add GSequence, a list that is implemented using + a balanced binary tree. + +* Add GRegex, an implementation of Perl regular expressions, + based on PCRE. + +* Use Posix monotonic clocks instead of gettimeofday() + for GTimer when available. + +* Support static initialization of GQeues with G_QUEUE_INIT, + g_queue_init() and g_queue_clear(). + +* Add g_string_chunk_clear() for clearing a + GStringChunk. + +* Add g_unichar_get_script() to obtain Unicode + script information. + +* Add g_unichar_iszerowidth() to obtain information + about zero-width characters. + +* Add G_GNUC_MAY_ALIAS which wraps the gcc may_alias + type attribute. + +* G_GNUC_INTERNAL has a working definition for the + Sun Studio compiler. This requires the macro to + be positioned before the function declaration. + +* The slice allocator can produce detailed debugging + information with G_SLICE=debug-blocks. + +* Modules support G_DEBUG flags resident-modules and + bind-now-modules. + +* Add G_DEFINE_DYNAMIC_TYPE() to make it easier + to define types in modules. + +* Bug fixes: too many to list them in detail here. + +* New and updated translations (be,bg,bn,ca,cs,de, + en_CA,en_GB,et,fa,fr,he,hu,it,ja,ku,lt,mg,mk,ml, + nb,ne,nn,pt,pt_BR,ro,sr,sr@Latn,sv,ta,uk,vi,zh_CN, + zh_HK,zh_TW) + + +Overview of Changes from GLib 2.12.1 to GLib 2.12.2 +=================================================== + +* Unicode updates: + - Normalization is following Unicode TR #29 + - g_unichar_isxdigit() only accept characters + for which g_unichar_xdigit_value() returns a value + - g_unichar_toupper and g_unichar_tolower leave + unconvertable characters in place instead of + replacing them by NUL + +* Bugs fixed + 348491 g_utf8_strup() and g_utf8_strdown() returns + string with NUL bytes + 349825 GKeyFile always inserts a newline before a group + 347842 g_unichar_isxdigit() is too general about what + it considers a digit + 348694 g_utf8_normalize() hasn't been updated to PR #29 + 348785 Hint about G_DEBUG in Message Logging docs + 349792 Wrong english string (UI) + 349952 gparamspecs.c uses gcc feature + +* Translation updates (ca,cs,de,dz,es,eu,fi,gu,ko, + nl,pl,tr,uk,zh_HK,zh_TW) + + +Overview of Changes from GLib 2.12.0 to GLib 2.12.1 +=================================================== + +* Update to final Unicode Character Database 5.0.0 + +* Bugs fixed: + 346660 issues with base64 api documentation / g_base64_decode_cl... + 348136 Coverity reports allocation of wrong size CID #2839 + 336281 Update to UCD 5.0 + 346197 g_date_strftime %F option doesnt work for win32 + 348011 Small optimization to real_toupper() + 246494 prototype mismatch in glib/gconvert.c + +* New and updated translations (bg,bn_IN,ca,dz,eu,fi, + fr,he,it,ja,mk,or,pt) + + +Overview of Changes from GLib 2.11.4 to GLib 2.12 +================================================= + +* Bugs fixed: + 344905 leap-year bug in g_time_val_from_iso8601 w/o HAVE_TIMEGM + +* Updated translations (cy,nb,nl) + + +Overview of Changes from GLib 2.11.3 to GLib 2.11.4 +=================================================== + +* GBookmarkFile: + - g_bookmark_file_remove_item returns a boolean + +* g_mkstemp accepts the XXXXXX in the middle of + the template + +* Bugs fixed: + 344868 g_key_file_to_data should separate groups + +* Updated translations (de,es,fr,gu,hi,ko,th) + + +Overview of Changes from GLib 2.11.2 to GLib 2.11.3 +=================================================== + +* GBookmarkFile: + - g_bookmark_file_move_item: Return TRUE in case of + an empty target + +* Bugs fixed: + 343919 gunicollate.c: strxfrm bug on VC8 + +* Updated translations (fi) + +Overview of Changes from GLib 2.11.1 to GLib 2.11.2 +=================================================== + +* Add g_ascii_stroll to parse signed 64bit integers + +* GMarkup: add a flag to treat CDATA as text + +* GHashTable: add functions to remove all entries + +* GMainLoop: add functions to find the currently + running source, and determine if it is destroyed + +* Bug fixes: + 342563 g_atomic_thread_init() needs to be called before + other _g_*_thread_init() functions + 343548 Potential use after free in callers of g_string_free() + 168538 Wish: Clearing contents of GHashTables + 321886 GTK+ cannot be reliably used in multi-threaded + applications + 341826 goption.c: 'strtoll' is C99's function + 343899 g_ascii_formatd dosn't work as expected for all + format strings + 317793 Make GEnumValue strings const + 337129 Compile warnings in G_IMPLEMENT_INTERFACE + 303622 What is G_TYPE_CHAR? + +* Updated translations (bg,dz,eu,gl,ja,ko,nl,th,vi) + + +Overview of Changes from GLib 2.11.0 to GLib 2.11.1 +=================================================== + +* GOption + - Support 64-bit integers + - Allow optional text before and after the options + in help output + +* Bug fixes: + 340538 gbase64-test writes OOB + 340816 GKeyFile set_string_list invalid memory reads + 339105 g_key_file_parse_value_as_double + 340434 convert-test.c fails (function test_one_half) + 311043 Memory leaks (and potential infinite loops) + when using G_ERRORCHECK_MUTEXES + 335198 Error checking mutexes are fubar + 341237 Add a G_OPTION_ARG_INT64 + 341192 g_io_channel_set_flags not implemented on win32 + 336120 Allow adding description before/after GOption + --help output body + 341191 misplaced check in g_relation_delete + 340530 mismatched calloc / g_free in win32 threads + +* Updated translation (es) + +Overview of Changes from GLib 2.10.x to GLib 2.11.0 +=================================================== + +* GBookmarkFile: a parser for files containing bookmarks + stored using the Desktop Bookmark specification. + +* Base64 encoding support + +* Unicode 5.0 support + +* GOption supports floating point numbers + +* GKeyFile supports floating point numbers + +* Bug fixes: + 155884 gatomic.c should be based on new SDK + 157877 update-desktop-database doesn't handle duplicate entries + 164719 keyfile parser doesn't support floats + 327662 Import BookmarkFile from libegg + 329548 Add G_OPTION_ARG_DOUBLE + 329789 option-test.c type confusion + 332841 Segmentation Fault when %llu is passed to vasnprintf and + HAVE_SNPRINTF is not defined + 333879 gthread/gthread-win32.c: IsDebuggerPresent needs '#define + _WIN32_WINDOWS 0x0401' + 333916 g_timer_elapsed docs should mention that microseconds + may be NULL + 334440 dlerror() portability issue causes crash on (old) a.out + NetBSD platform + 334646 goption + error out params + 334799 g_remove() must check return value of remove() + 334943 make check FAIL: threadpool-test + 335215 Some breakages with GThreadPool + 336085 g_option_context_new parameter lacks better explanation + 336677 Documentation for g_object_ref_sink() is incorrect + 337027 gbookmarkfile.c: sys/time.h include error + 337553 Wrong escaping of URIs + 338572 Dereferencing NULL value in g_key_file_get_group_comment + 338845 g_completion_complete_utf8 crashes when NULL is passed to it + 339337 g_bookmark_file_set_description + 339338 gbookmarkfile.c, function expand_exec_line + 339340 gbookmarkfile.c, function bookmark_app_info_dump + +* Translation updates (bg,en_GB,et,gl,gu,he,hi,ka,nb,nl,nn, + or,pt_BR,ro,tr,vi,zh_CN) + + +Overview of Changes from GLib 2.10.0 to GLib 2.10.1 +=================================================== + +* Bugs fixed: + 314794 Broken pthread detection on Darwin [Gregor Riepl] + 322476 Missing check for .dylib [Vladimir Panov] + 333651 Inconsistent _g_charset_get_aliases prototype [Julio + M. Merino Vidal] + 333761 GInitiallyUnowned breaks application code [Sven Herzberg] + +* Win32 changes: + - Fix g_listenv() implementation. + - Allow up to 100 GPrivate structs + +* Translation updates (fr,hu,lt,pl,sv) + + +Overview of Changes from GLib 2.9.6 to GLib 2.10.0 +================================================== + +* Bugs fixed: + 328997 64bit pointer trunction in glib slab-allocator + [Pascal Hofstee] + 331110 g_cond_broadcast(inform_cond) without holding + inform_mutex [Chris Wilson, Sebastian Wilhelmi] + 332093 Fix some leaks in the tests [Kjartan Maraas] + 332435 g_utf8_strlen returns wrong value if a maximum + number of bytes to check is specified + [Matthias Clasen] + 331367 gslice requires more POSIX-like semantics for + GPrivate destructors [Tor Lillqvist] + +* Documentation improvements [Matthias, Kang Jeong-Hee, + Tor Lillqvist, Stefan Kost] + +* Translation updates (el,eu,ka,uk) + +Overview of Changes from GLib 2.9.5 to GLib 2.9.6 +================================================= + +* Bugs fixed: + 329124 distclean removes README [Kjartan Maraas, Tim Janik] + 317679 GRelation field type not documented [Behdad Esfahbod] + 329123 Typo in GTime docs [Kjartan Maraas] + +* Documentation improvements [Sven Herzberg, David + Schleef, Kjartan Maraas, Behdad Esfahbod] + +* Translation updates (cs,cy,it,ko,pt,sq,sr,sr@Latn,ru + +Overview of Changes from GLib 2.9.4 to GLib 2.9.5 +================================================= + +* Memory management: + Runtime debugging support: The slice allocator + can be turned off by setting G_SLICE=always-malloc + in the environment. Zeroing of freed memory can + now be turned on at runtime by setting + G_DEBUG=gc-friendly in the environment. [Tim Janik] + +* Bugs fixed: + 328253 HP-UX/IA-64 uses ".so" as default shared library + extension [Albert Chin] + 143380 unicode-encoding test fails converting to UTF-16 + with libiconv [Marc Moorcroft] + 328254 Build breakage (GSlice) [Jens Ganseuer] + 328705 C99ism in glib/gmem.c [Kazuki Iwamoto] + +* Translation updates (da,et,zh_CN) + +Overview of Changes from GLib 2.9.3 to GLib 2.9.4 +================================================= + +* Type system: + Fix a problem with g_object_compat_control() which + can lead to segfaults in GTK+ applications on 64bit + platforms. + +* Thread suppport: + Unused threads now fall back to the global pool after + 500 milliseconds, where they wait for another + max-idle-time milliseconds. [Sebastian Wilhelmi] + +* Fix a memory allocation problem in GKeyFile. [Morten + Welinder] + + +Overview of Changes from GLib 2.9.2 to GLib 2.9.3 +================================================= + +* GTree: + - Replace the simple recursive implementation by + a nonrecursive, threaded one [Maurizio Monge] + +* Change g_filename_display_name and + g_filename_display_basename to use the Unicode + replacement character U+FFFD instead of a question + mark, and don't append "(invalid encoding)" [Matthias] + +* Documentation improvements [Sven Herzberg, Federico + Mena Quintero, Stefan Kost] + +* Bugs fixed: + 323937 gslice.c in glib 2.9.1 doesn't build on Mac OS X + [Bogdan Nicula] + 326558 Some test failures on IRIX 6.5 [Daichi Kawahata] + 169285 "threaded" tree implementation for GTree + [Maurizio Monge] + 326747 g_filename_display_basename adds (invalid encoding) + [Alberto Ruiz] + +Other contributors: Christian Kellner, Murray Cumming + +New and updated translations (bg,ca,de,es,et,gu,ja,nl,th,vi) + + +Overview of Changes from GLib 2.9.1 to GLib 2.9.2 +================================================= + +* Memory management: + - Add tests for cache colorization [Tim Janik] + - Minimize space consumption if small amounts of differently + sized slices are allocated, at a small performance cost. [Tim] + +* Thread support: + - Add g_atomic_pointer_set() and g_atomic_int_set() [Tim Janik, + Sebastian Wilhelmi] + - Add g_thread_pool_set_sort_function() to allow sorting the + tasks of a threadpool. [Martyn Russell] + - Add g_thread_pool_set_idle_time() to allow unused threads + to exit after a certain time. [Martyn] + +* Type system: + - introduce a new type GInitiallyUnowned, which has an initial + floating reference. [Tim] + - Add support for GType parameters. [Matthias] + +* Main loop: + - Add g_main_context_is_owner() to determine if the current + thread is the owner of the context. [Michael Meeks] + +* Provide g_access(), g_chdir(), g_unlink(), g_rmdir() as + wrapper functions instead of macros. [Manish Singh] + +* Documentation improvements [Tim, Matthias, Federico Mena Quintero, + Stefan Kasal, Dan Williams] + +* New and updated translations (en_CA,fi,fr,gl,ml,nb,no,zh_HK,zh_TW) + +* Bugs fixed: + 324179 g_allocator_new() returns pointer to const dummy which Gtk+ 2.8 + tries to modify [J. Ali Harlow] + 324332 g_option_context_parse() returns false without setting error + [Tim-Philipp Müller] + 324950 GLIB 2.9.1 testcase errors [Dan Yefimov] + 325015 gslice.c: process.h is needed on Windows [Kazuki Iwamoto] + 321978 G_DATALIST_GET_FLAGS() macro is not casting datalist to + gpointer [Andrew Paprocki] + 316221 G_LOCK warns about breaking strict-aliasing [Michal Benes, + Stanislav Brabec] + 325273 Error in documentation for glib_check_version () [Declan Naughton] + 325310 g_spawn_sync hangs when catching both stdout and + stderr [Tor Lillqvist] + 325249 gcc warning when using g_rmdir from [Jani Monoses] + 325864 glib/gthreadpool.c:"#define debug(...)" is C99 [Kazuki Iwamoto] + 325874 Should say somewhere that source IDs are > 0 [Dan Williams] + 325438 a typo (compatability) [Stefan Kasal] + 323937 gslice.c in glib 2.9.1 doesn't build on Mac OS X [Bogdan Nicula] + + +Overview of Changes from GLib 2.9.0 to GLib 2.9.1 +================================================= + +* Memory management + - The slice allocator is implemented [Tim Janik] + - g_slice_free_chain() has been renamed to + g_slice_free_chain_with_offset() [Tim, Behdad Esfahbod] + - Mem chunks are deprecated [Matthias Clasen] + +* Data structures + - Hash tables are refcounted, and have a boxed type [Tim] + +* Thread support + - Support for Solaris threads has been removed + [Sebastian Wilhelmi, Andrew Paprocki] + - g_async_queue_sort(), g_async_queue_push_sorted() have + been added to allow GAsyncQueue to be used as a priority + queue, together with the corresponding _unlocked + variants [Martyn Russell] + +* GObject: + - The concept of a floating initial reference has been + moved from GtkObject to GObject [Tim] + +* Win32 changes: + - Make g_rename() replace existing files [Tor Lillqvist] + +* Misc new API: + - G_GUINT64_CONSTANT macro to define guint64 + constants [Andrew Paprocki] + - G_GNUC_WARN_UNUSED_RESULT macro to instruct the + compiler to emit a warning if the value returned + by a function is ignored. [Arjan van de Ven, Alex Larsson] + - GList and GSList now have sort functions which take an + extra user data argument [Martyn Russell] + - g_param_spec_ref_sink() has been added for consistency [Tim] + +* $LOGNAME is respected when determining user data. [Laszlo Peter] + +* Other changes and bug fixes [Tim, Matthias, Behdad, + Christian Persch, Benedikt Meurer, Andrew Paprocki, + Kazuki Iwamoto, Alexis S. L. Carvalho, Stanislav Brabec, + Andreas Schwab, Kalle Vahlman] + +* Documentation + - Deprecation warnings carry version information [Matthias] + - The slice allocator has been documented [Matthias, Tim] + - Other improvements [Morten Welinder] + +Overview of Changes from GLib 2.8.x to GLib 2.9.0 +================================================= +* Unicode support: + - The Unicode tables have been updated to Unicode 4.1, + adding several new values to the GUnicodeBreakType + enumeration. This breaks Pango <= 1.10 + [Behdad Esfahbod] + - The various Unicode character predicate functions + (g_unichar_isalpha, g_unichar_isdigit,...) have + been optimized + [Behdad] + - g_utf8_pointer_to_offset, g_utf8_offset_to_pointer: + These functions handle negative offsets now, and + going backwards in g_utf8_offset_to_pointer uses + "stutter stepping". + [Larry Ewing, Matthias Clasen] + +* Memory management: + - Mem chunks are no longer used internally in GLib and + GObject. GMemChunk will be deprecated in GLib 2.10 + - All APIs based on GAllocator (g_list_push/pop_allocator, + and similar push/pop_allocator functions for other + data structures) have been deprecated, since they + never worked as intended. + - The g_slice_* functions have been added as a + new API for fast allocation of small memory blocks. + The implementation in GLib 2.9.0 is just a simple + wrapper around malloc. GLib 2.10 will have an + efficient and scalable implementation. + [Tim Janik, Matthias] + +* Pattern matching: + - g_pattern_match has been optimized to avoid + unnecessary recursion. + [Tim, Matthias] + +* g_intern_string, g_intern_static_string: + - New functions to intern strings. These are now used + by GObject to avoid duplicating static strings + [Matthias] + +* g_thread_foreach: + - New function to iterate over all GThreads + [Tim, Matthias] + +* g_date_set_time_t, g_date_set_time_val: + - New functions to set a GDate from a time_t or + GTimeVal value. g_date_set_time has been deprecated + in favor of these. + [Roger Leigh] + +* g_snprintf and g_vsnprintf: + - These functions are no longer declared in gprintf.h, + since they are in glib.h + [Matthias] + +Overview of Changes from GLib 2.8.0 to GLib 2.8.1 +================================================= +* Optimize single-character insertions in GString [Ross Burton] +* Fix build problems on OS X +* Fix build problems on Win32 [Tor Lillqvist, Hans Breuer] +* Other bug fixes [Matthew F. Barnes, Stepan Kasal] +* Documentation improvements [Tristan van Berkom, Behnam + Esfahbod, Gustavo Carneiro, Stepan Kasal, Matthias] +* New and updated translations (ca,cy,ko,ro,uk) + +Overview of Changes from GLib 2.7.7 to GLib 2.8.0 +================================================= +* Make g_value_transform() handle enum values + correctly on ppc64. [Michael Lorenz] + (Third-party code accessing enumeration values + in GValues should also be changed to access + v_long, not v_int, in order to work on bigendian + 64bit machines.) +* Make g_flags_get_first_value() handle a value + of 0 meaningfully. [Tim-Philipp Müller] + +Overview of Changes from GLib 2.7.6 to GLib 2.7.7 +================================================= +* Make atomic operations on s390 work [Matthias] +* Fix C++ guards in gstdio.h [Tor Lillqvist] + +Overview of Changes from GLib 2.7.5 to GLib 2.7.6 +================================================= +* Add native implementations of atomic operations + on s390 [Matthias] +* Make atomic reference counting of closures + work on s390 [Matthias] +* Avoid an infinite loop in g_convert_with_iconv(). + [Sebastian Bacher] +* Documentation improvements [Ross Burton] + +Overview of Changes from GLib 2.7.4 to GLib 2.7.5 +================================================= +* Thread-related changes + - Fix build issues on HP-UX [Paul Cornett] + - Threadsafe access to flags stored in datasets [Tim Janik] + - Fix several issues with atomic refcounting for + closures, objects and paramspecs [Tim] + - Improve tests for atomic refcounting changes [Tim] +* Fix handling of stateful encodings in g_convert_* [Matthias] +* Fix translation of GOption help output [Dan Winship] +* Catch format errors in translations. This may cause + "make check" to fail when using older versions + of gettext [Matthias] +* Win32 bug fixes [Tor Lillqvist] +* Documentation improvements [Ross Burton, Jochen Baier, + Matthias, Tim] +* New and updated translations (de,fi,gu,pl,pt,tr,zh_TW) + +Overview of Changes from GLib 2.7.3 to GLib 2.7.4 +================================================= +* Fix g_atomic_pointer_compare_and_exchange + on Sparc64 [Gert Doering] +* Fix a hang in g_thread_pool_free. [Hong Jen Yee] +* Win32 bug fixes [Tor Lillquist] +* Other bug fixes [Benoit Dejean, Manish Singh] +* Documentation improvements [Bryan Silverthorn, + Callum McKenzie] +* New and updated translations (de,lt,sq,zh_CN) + +Overview of Changes from GLib 2.7.2 to GLib 2.7.3 +================================================= +* GOption + - Allow callbacks with optional arguments [Pawel Sliwowski] + - Allow to turn off the automatic long option name + disambiguation [Adam McLaurin] + - Only allow printable ASCII as short option names [Matthias] +* Win32 + - Build fixes [Tor Lillqvist] + - Rewrite iochannel socket implementation [Tor] +* GObject + - Threadsafety improvements; in particular, refcounting + of objects is done atomically now. [Wim Taymans, Tim Janik] +* Bug fixes [Morten Welinder, Matthias, Wim Taymans] +* Documentation improvements [Richard Laager, Matthias] +* New and improved translations (bf,cs,hu,nb,nl,no) + +Overview of Changes from GLib 2.7.1 to GLib 2.7.2 +================================================= +* Win32 build fixes [Hans Breuer] +* Bug fixes [Mikael Magnusson] +* Documentation improvements [Matthias Clasen] +* New and updated translations (en_CA,es,et,ja,sr,sr@Latn,zh_TW) + +Overview of Changes from GLib 2.7.0 to GLib 2.7.1 +================================================= +* GOption + - Allow callback arguments without parameters [Dan Winship] +* GMappedFile: an mmap wrapper [David Schleef, Behdad Esfahbod] +* Misc new functions: + - g_get_host_name [Tor Lillqvist] + - g_mkdir_with_parents [Tor] + - g_build_pathv, g_build_filenamev [Todd A. Fisher, + Matthias Clasen] +* Bug fixes [Roger Leigh, Masatake YAMATO, Kjartan Maraas, + Manish Singh, Tor, Murray Cumming, Kian Duffy, Morten Welinder] +* Documentation improvements [Hong Gang XU, Dan Winship, Matthias] +* New and updated translations (bg,cs,da,en_CA,es,et,nb,nl,no, + sk,th,zh_TW) + +Overview of Changes from GLib 2.6.x to GLib 2.7.0 +================================================= +* GKeyFile + - Add unit tests [Matthias Clasen, Suren A. Chilingaryan] + - Accept \r\n as line end [Bastian Nocera] + - Don't interpret leading zeros as octal numbers. [Matthias] + - Make key and group removal work [David Hoover, Matthias Hasselmann] +* GOption + - Improve formatting of --help output [Matthias, Noah Levitt] + - Accept -? [Matthias] + - Warn about duplicate main groups [Jeff Franks] + - Treat '-' as non-option argument [Tim Musson, Thomas Leonard] + - Report missing arguments as errors [Björn Lindqvist] + - Add a boxed type for GDate [Tim-Philipp Müller] +* GTree + - g_tree_remove() and g_tree_steal() return status information [Matthew F. Barnes] +* Stdio wrappers + - Work regardless of large file support [Manish Singh] + - Add g_access(), g_chmod(), g_creat(), g_chdir [Tor Lillqvist] +* GObject + - Implement "toggle references" to help language bindings [Owen Taylor] + - Allow to mark names, nicks and blurbs of pspecs as static [Ben Maurer, Matthias] + - Make pspec lookup a bit faster [Morten Welinder] +* Add g_listenv() to list all set environment variables [Hans Petter Jansson] +* Add g_file_set_contents() to atomically write a file. [Søren Sandmann, + Sven Neumann, Manish, Alexis S. L. Carvalho] +* Add g_try_malloc(), g_try_new(), g_try_new0() and g_try_renew() [Stefan Kost] +* Add g_utf8_collate_key_for_filename() to sort filenames taking + extensions and numeric suffixes into account. [Ole Laursen, Alex Larsson] +* Add G_GNUC_NULL_TERMINATED to mark varargs function with + NULL-terminated argument lists. [Marc Meissner] +* Win32 changes + - Improved debugability [Ulf Lamping, Hans Breuer] + - Make filename handling more robust [Tor, Billy Skaggs] + - Improve g_get_system_data_dirs() [Tor] + - Use more precise timers [Tor] + - Build fixes [Kazuki Iwamoto, Hans, Tor, Robert Ögren] +* Other bug fixes [Roger Leigh, Owen, Matthias, Morten, Kjartan Maraas, + Pawel Sakowski, Tor, Simon Budig, Ed Avis, Manish, Nicolas Laurent, + Bastien, Fabrício Barros Cabral, Michael Banck, Daniel Atallah, + J. Ali Harlow, Tim Janik, Hazael Maldonado Torres, Sven, Jon-Kare Hellan, + Dave Benson, Tommi Komulainen, Benjamin Otte, Brian Cameron, Changwoo Ryu, + Christian Biere, Noah, Benoît Carpentier] +* Documentation improvements [Vincent Untz, Matthias, Tim-Philipp Müller, + Morten, Matthew, Federico Mena Quintero, Sebastian Bacher, Oliver Sessink, + Stefan, Jared Lash, Tor, Owen, Daniel Vaillard, Mathieu Lacage] +* New and updated translations (ca,cs,da,el,en_CA,en_GB,es,et,eu,fa,fr,gl, + hu,id,it,lt,mn,ne,nl,pl,pt,pt_BR,ro,rw,sk,sq,sr,sr@Latn,tl,uk,xh,zh_CN) + +Overview of Changes from GLib 2.6.0 to GLib 2.6.1 +================================================= +* GOption + - Make gtk_init(NULL, NULL) work again [Marcin Krzyzanowski] + - Improve handling of -- [Matthias Clasen] + - Don't show G_OPTION_REMAINING in --help output [Matthew F. Barnes] +* g_find_program_in_path() doesn't return directories [Tommi Komulainen] +* Add gmodule-export-2.0.pc [Matthias] +* Win32 changes + - Improve hangling of UNC paths [Tor Lillqvist] + - g_getenv(), g_setenv(), g_unsetenv(), g_find_program_in_path() + take and return UTF-8 now [Tor] + - Make g_file_test() work more reliably, and use PATHEXT + when check for executables [Tor] + - Build and cross-compilation fixes [J. Ali Harlow] +* Other bug fixes [Jens Hatlak, Morten Welinder, + Tor, Kalpesh Shah, Adrian Bunk] +* Documentation improvements [Marcin Krzyzanowski, Tor, Crispin + Flowerday, Mariano Suárez-Alvarez, Christian Biere, Danny Milo, + Vincent Untz, Bastien Nocera] +* New and updated translations (cy,de,nl,ru,sq,sv) + +Overview of Changes from GLib 2.4.x to GLib 2.6.0 +================================================= + +* Major new APIs + - GOption, a commandline option parser + - GKeyFile, a parser/editor for the .ini like files + - Functions to support the XDG basedir specification + - Wrappers for common POSIX pathname functions to handle filename + encodings consistently. On Windows, these use UTF-8. + +* Miscellaneous new functions + - g_filename_display_name() converts filenames in displayable UTF-8 strings + - g_uri_list_extract_uris() splits uri lists + - g_date_get_iso8601_week_of_year() gets ISO 8601 week numbers + - g_log_set_default_handler() installs an alternate default log handler + - g_get_language_names() obtains a list of applicable locale names + - g_strv_length() calculates the length of NULL-terminated string arrays + - g_win32_get_windows_version() determines the Windows version + - G_GNUC_INTERNAL marks functions as non-exported + - glib_check_version() checks the GLib version at runtime + - g_debug() completes the family of logging functions + +* Performance improvements + - Optimize g_utf8_validate() + - Optimize g_markup_parse_context_parse() + - Reduce signal connection complexity from O(n) to O(1) + - Get rid of many PLT entries for internally used exported symbols + - Reduce code size by removing literal strings from g_return_if_fail() + +* Other changes + - On Windows, GLib functions that take file name arguments now require + those to be in UTF-8. Functions that return file names return UTF-8. + - Use higher precision for mathematical constants + - Don't convert to/from UTF-8 in g_filename_to_uri/g_filename_from_uri + - Support ll as printf format modifier for long long on all platforms + - Clean up the ABI and enforce the list of exported symbols + - Add a .pc file for using gmodule in libraries + - Require ngettext + +Overview of Changes from GLib 2.5.7 to GLib 2.6.0 +================================================= +* GOption: Don't list help options if group-specific + options have been requested [Glynn Foster] +* Make g_get_language_names() track locale changes [Christian Persch] +* Win32 bug fixes [Tor Lillqvist] +* Bug fixes [Philippe Blain, Owen Taylor, Sebastian Wilhelmi] +* New and updated translations (da,es,ja,lt,zh_CN) +Bugs fixed: 159530,100697,160271,160645,157255 + +Overview of Changes from GLib 2.5.6 to GLib 2.5.7 +================================================= +* Optimize g_utf8_validate() [Owen Taylor, Matthias Clasen] +* Optimize g_markup_parse_context_parse() [Havoc Pennington, + Morten Welinder] +* Reduce signal connection complexity from O(n) to O(1) + [Sven Neumann] +* Add a .pc file for using gmodule in libraries [Owen] +* Add G_GNUC_MALLOC to mark functions returning newly + allocated memory [Matthias] +* Win32 bug fixes [Hans Breuer, Tor Lillqvist, Robert Ögren, + Bruce Hochstetler] +* Bug fixes [Kazuki IWAMOTO, Matthias, Manish Singh, Morten, + Frederic Crozat, Tor] +* Documentation improvements [Matthias, Tor, Owen] +* New and updated translations (cs,da,de,en_CA,en_GB,es,nb,nl,sq,zh_CN) + +Overview of Changes from GLib 2.5.5 to GLib 2.5.6 +================================================= +* GOption + - Add G_OPTION_FLAG_REVERSE to allow options + which unset a boolean variable [Tor Lillqvist] +* GChildWatch + - Use sigaction instead of signal [Jonas Jonnson, + Archana Shah] + - Make the very first SIGCHLD work [Gustavo Carneiro] +* Bug fixes [Morten Welinder, Tor, David MacLachlan, + Manish Singh, J. Ali Harlow] +* Documentation improvements [Matthias Clasen, Tor] +* Updated translations (da,ja,tr,zh_CN) + +Overview of Changes from GLib 2.5.4 to GLib 2.5.5 +================================================= +* GKeyFile + - Cleanups, add more error checking [Ray Strode] + - Fall back to the untranslated string when getting + locale strings [Mark McLoughlin] +* GOption + - Document GOption [Matthias Clasen] + - Better support for rest arguments [Owen Taylor, Matthias] + - Handle conflicts between groups [Matthias] +* Add g_lstat() to the stdio wrappers [Tor Lillqvist] +* Add g_filename_display_name() to convert filenames + in displayable UTF-8 strings [Alex Larsson, Matthias] +* Win32 bug fixes [Kazuki IWAMOTO, Hans Breuer, Tor] +* Bug fixes [Christophe Fergeau, Morten Welinder, + Owen, Kjartan Maraas, Mark] +* Documentation improvements [Matthias, Tor] + +Overview of Changes from GLib 2.5.3 to GLib 2.5.4 +================================================= +Add GKeyFile, a parser/editor for the .ini like files used in various + freedesktop.org specifications. [Ray Strode] +Make the handling of filename encodings consistent across all + GLib functions, introduce wrappers for common POSIX + functions which accept the same filename encoding. [Tor Lillqvist, + Owen Taylor] +GOption + - Rename g_context_option_error_quark() to a more language-binding + friendly name [Murray Cumming] + - Accept backslashes in filenames on Win32 [Tor Lillqvist] +* Strip the internal aliasing prefix IA__ from function names in + assertions [Matthias Clasen] +* Add a function to split uri lists. [Matthias] +* Win32 bug fixes + - Don't open console windows [Tor] +* Other bug fixes [Philippe Blain, Robert Ögren, Hidetaka Iwai, Matthias, + Morten Welinder, Mats-Ola Persson, Tor, Nickolay V. Shmyrev, Kjartan Maraas, + Anders Carlsson, Tim-Philipp Müller, Lucas Rocha, Andrea Campi, Manish + Singh, Thomas Fitzsimmons, Kazuki IWAMOTO] +* Documentation improvements [Matthias, Linus Walleij, Nickolay, Philippe, + Adam Hooper, Gustavo Carneiro] +* New and updated translations (cs,en_CA,en_GB,ja,nb,nl,or,sr,sr@Latn,sq) + +Overview of Changes from GLib 2.5.2 to GLib 2.5.3 +================================================= +* GOption + - set the program name from argv[0] [Masatake YAMATO] + - make contexts work without a main group [Anders Carlsson] +* Performance + - Get rid of many PLT entries for internally used exported symbols, + and clean up the ABI at the same time and make make check check the + list of exported symbols. [Matthias Clasen] +* Add API to get ISO 8601 week numbers [Niklas Lundell] +* Add API to install an alternate default log handler [Darin Adler] +* Add API to obtain a list of applicable locale names [Hidetoshi Tajima] +* Reduce code size bloat by removing literal strings from + the g_return_if_fail() macros [Owen Taylor] +* Add g_strv_length [Tim-Philipp Müller] +* Win32 changes + - Add API to determine the Windows version [Tor Lillqvist] +* Other bug fixes [Stepan Kasal, Anders, Tor, Kazuki Iwamoto, + Manish Singh] +* Documentation improvements [Morten Welinder, Matthias] +* New and updated translations (es,nn,ro) + +Overview of Changes from GLib 2.5.1 to GLib 2.5.2 +================================================= +* Add G_GNUC_INTERNAL macro [Arjan van de Ven] +* Add GOption, a commandline option parser [Anders Carlsson] +* Add glib_check_version [Michael Natterer] +* Add XDG basedir API [Ray Strode] +* Require ngettext [Danilo Segan] +* Bug fixes [Manish Singh, Ray Strode, Vincent Noel, + Jon-Kare Hellan, Jody Goldberg] +* Win32 bug fixes [Tor Lillqvist, Hans Breuer, Peter Zelezny] +* Documentation improvements [Matthias Clasen, Vincent Untz, Christian Persch] +* New and updated translations (bs,eu,fi,gu,ne,pa) + +Overview of Changes from GLib 2.5.0 to GLib 2.5.1 +================================================= + +* Bug fixes [Oliver Guntermann, Sven Neumann, James + Henstridge, Hiroyuki Ikezoe, Matthias Clasen, Robert + Ögren, Tommi Komulainen] +* Documentation improvements [Soeren Sandmann, + Christophe Fergeau, Danek Duvall] +* New and updated translations (eu,hi) + +Overview of Changes from GLib 2.4.1 to GLib 2.5.0 +================================================= + +* New functions g_debug [Sven Herzberg] +* Use higher precision for mathematical constants [Morten + Welinder] +* Don't convert to/from UTF-8 in g_filename_{to,from}_uri + [Federico Mena Quintero] +* Win32 + - Handle empty digit string in printf() functions + correctly [Tor Lillqvist] + - Support ll as format modifier for long long [Tor] + - Be more careful about HOME [Tor, Ivan Wong] + - Bug fixes [John Ehresman] +* Miscellaneous bug and portability fixes [Danilo Segan, + Owen Taylor, Nikolai Weibull, Benoît Carpentier, Morten + Welinder, Manish Singh, Sven Neumann, Julio M. Merino Vidal, + Kaz Sasayama, Murray Cumming, Federico, Mariano Suarez-Alvarez] +* Documentation updates [Matthias Clasen, Crispin Flowerday, + Tommi Komulainen, Federico Mena Quintero, Ed Griffiths] +* New and updated translations (ja,ne,no,wa) + +Overview of Changes from GLib 2.4.0 to GLib 2.4.1 +================================================= + +* Win32 bug fixes [Tor Lillqvist, Roger Leigh, John Ehresman] +* Miscellaneous bug and portability fixes [Owen Taylor, + Matthias Clasen, Jonas Jonsson, Christian Krause, + Nickolay V. Shmyrev, Christophe Saout, Philippe Blain, + Piotr Klaban] +* Documentation updates [Matthias] +* New and updated translations (ca,cs,cy,el,en_CA,en_GB,es,eu,fi, + fr,gu,he,id,nl,pt,pl,ru,sr,sr@ije,sr@Latn,sv,uk) + +Overview of Changes from GLib 2.3.6 to GLib 2.4.0 +================================================= + +* Handle invalid-UTF-8 in g_log() properly [Matthias Clasen] +* Win32 bug fixes [Tor Lillqvist, Bruce Hochstetler] +* Miscellaneous bug and portability fixes [Olivier Biot, David L. Cooper II, + Kjartan Maraas, Frédéric L. W. Meunier, Christof Petig, Manish Singh, + Sebastian Wilhelmi] +* Documentation updates [Owen] +* Updated translations (hr,ro) + +Overview of Changes from GLib 2.3.5 to GLib 2.3.6 +================================================= + +* GAtomic bug fixes [Sebastian Wilhelmi, Mark McLoughlin] +* GMain threading fixes and improvements [Sebastian] +* Win32 [Tor Lillqvist] + - restore some symbols extraneously exported from gobject to maintain ABI compatibility + - Misc build improvements and fixes [Tor, Cedric Gustin, Hans Breuer] +* Documentation updates [Sebastian, Takeshi AIHANA, Matthias, Sven Herzberg] +* New and updated translations (be,es,fi,ga,pa,sr@ije,zh_CN) + +Overview of Changes from GLib 2.3.3 to GLib 2.3.5 +================================================= + +* Make glib-mkenums parse initializers with macros. [Matthias Clasen, muppet] +* Respect locale era in g_date_set_parse(). [Theppitak Karoonboonyanan] +* Add atomic operations and use it for the async queue and + gonce implementation. [Sebastian Wilhelmi] +* Documentation improvements [Sebastian, Matthias, Sven Herzberg] +* Add g_main_depth() for finding the recursion depth of the main + loop [Owen Taylor, Tim Janik, Stefan Westerfeld] +* Add g_spawn_close_pid(), needed on win32 [J. Ali] +* Win32 fixes. [Hans Breuer, J. Ali Harlow] +* Misc bugfixes [Sebastian, Matthias, Balazs Scheidler, Owen] +* Updated translations (cy,et,ga,sq) + +Overview of Changes from GLib 2.3.2 to GLib 2.3.3 +================================================= + +* Add a native AIX gmodule implementation. [Laurent Vivier] +* Add g_node_copy_deep(). [James M. Cape, Matthias Clasen] +* Extend GQueue API to match the GList API. [Soeren Sandmann] +* Add g_hash_table_find(). [Tim Janik] +* Add a G_MODULE_BIND_LOCAL flag. [David Schleef] +* Inline g_string_append_c() when possible. [Owen Taylor, Tim] +* Wrap waitpid() as a GSource. [Jonathan R. Blandford] +* Add g_completion_complete_utf8(). [Theppitak Karoonboonyanan, + Matthias] +* Add g_strsplit_set(). [Soeren] +* Documentation improvements. [Vincent Untz, Sebastian Wilhelmi, + Soeren, Matthias] +* Win32 build fixes. [Tor Lillqvist] +* Misc bugfixes [Manish Singh, Noah Levitt, Simon Josefsson, + Morten Welinder, Damien Carbery, Julio M. Merino Vidal, Sebastian, + Matthias] +* Updated translations (nn,cs,it,ko,sq,ms,az,hr,uk,sr,sr@Latn,sq,ta) + +Overview of Changes from GLib 2.3.1 to GLib 2.3.2 +================================================= + +* Add G_MAXSIZE. [Manish Singh] +* Add g_rand_new_with_seed_array(), g_rand_set_seed_array(), + implementing the init-by-array functionality of the + original mersenne twister. Add g_rand_copy(). Improve seeding. + [George Lebl] +* Add a lowercase_name option to glib-mkenums. [Murray Cumming] +* Add g_ptr_array_foreach(). [Matthias Clasen] +* Add g_timer_continue(). [Tim-Philipp Müller] +* Fix a threadsafety issue in mem chunks. [Matthias, Balazs Scheidler] +* Fix g_filename_{to,from}_utf8() on Win32 and improve + g_file_test() there too [Hans Breuer] +* Add a boxed type for NULL-terminated string arrays. [Matthias] +* Add G_DEFINE_TYPE() plus variants to ease the constuction + of GObject boilerplate code. [Tim Janik] +* Support & in password GECOS field [Matthias, Soeren Boll Overgaard] +* Documentation improvements [Matthias, Manish] +* Win32 build fixes [Hans] +* Misc bug fixes [Damien Carbery, Matthias, Manish, Olivier Poncet, + Zack Rusin] +* Updated translations (ar,de,fa,ga,mn,nn,no,sq) + +Overview of Changes from GLib 2.3.0 to GLib-2.3.1 +================================================= + +* Add glib/gi18n.h and glib/gi18n-lib.h for common + gettext support, including a Q_() macro for translation + with context [Matthias Clasen] +* Add a more flexible G_FILENAME_ENCODING variable + as a replacement for G_BROKEN_FILENAMES [Matthias] +* Fix the return value g_main_context_iterate() for + newly ready sources [Padraig O'Briain] +* Handle Hangul composition for normalization [Noah Levitt] +* Add G_{MIN,MAX,MAXU}INT{8,16,32}. [Mark Jones, Matthias] +* Add G_GSIZE_FORMAT/G_SSIZE_FORMAT [Manish Singh] +* Add G_STRFUNC as a portable wrapper for __func__ [Tim Janik] +* Documentation improvements [Matthias] +* GObject [Tim Janik] + - Support '-' in g_signal_connect()/disconnect() names + like 'swapped-signal'. + - Add g_type_class_peek_static() and use to optimize + g_object_new() for static types [Tim] + - Allow setting construct-only properties from within + init() implementations + - Enforce readability/writeability in g_object_set/get() +* Fix bug with g_ascii_strtod and multi-byte separator. + [Behdad Esfahbod, Roozbeh Pournader] +* Misc bug fixes [Matthias, John Ehresman, Andrew Lanoix, + Tor Lillqvist, Mark McLoughlin, Tim-Philipp Müller, Manish, + Morten Welinder] +* Updated translations (ca,cs,da,es,fr,ja,nn,no,pt,ru) + +Overview of Changes from GLib 2.2.x to GLib-2.3.0 +================================================= + +* Replace Trio printf by gnulib vasnprintf [Matthias Clasen] +* Update Unicode data to Unicode 4.0 [Noah Levitt] +* Support XML-safe formatted output with + g_markup_[v]printf_escaped [Owen Taylor] +* Add g_file_read_link to read symbolic links [Matthias] +* Add g_unichar_get_mirror_char to obtain the + mirrored variant of a character [Noah] +* Support for one-time initialization functions. + [Sebastian Wilhelmi] +* Miscellaneous API additions: g_vasprintf + g_string_chunk_insert_len, g_setenv, g_unsetenv [Matthias] +* Docs improvements [Matthias] +* Add support instance-private data on classed types + [Mark McLoughlin, Tim Janik, Owen] +* Optimize signal emissions [Soeren Sandmann, Tim] +* Support a "default vtable" per interface [Tim] +* Add support for properties on interfaces [Owen, Tim] +* Miscellaneous API additions: g_value_take_string(), + g_value_take_param(), g_value_take_object(), + g_value_take_boxed(). [Matthias] +* Win32 build fixes [Tor Lillqvist] + +Overview of Changes from GLib 2.1.5 to GLib-2.2.0 +================================================= + +* Fix a problem with g_thread_init() on 64-bit problems + [Alceste Scalas, Sebastian Wilhelmi] +* Add assembly implementations of byteswap macros + for ia64 and x86_64. [Manish Singh] +* IOChannel fixes for Win32 [Tor Lillqvist, Thorsten Maerz] +* Updated translations (bg,ca,es,da,fi,lv,ru,sk) + +Overview of Changes from GLib 2.1.4 to GLib-2.1.5 +================================================= + +* Win32 bug fixes [Tor Lillqvist] +* Various post-rewrite fixes for glib-gettext.m4 [Owen Taylor, + Jody Goldberg, Kjartan Maraas, Johannes Stezenbach] +* Ensure we have a GUINT64_FORMAT by pulling in Trio + if necessary [Manish Singh] +* Further Trio build fixes [Matthias Clasen, Owen] +* Hack around gcc, libtool issues with -pthread [Owen] +* Docs improvements [Matthias] +* Bug and portability fixes +* Updated and new translations (bg,de,fi,fr,sq,fr) + +Other contributors: Kai Poitschke, Morten Welinder + +Overview of Changes from GLib 2.1.3 to GLib-2.1.4 +================================================= + +* autoconf changes to make it possible to cross compile + GLib. [Owen Taylor, Dan Kegel, Amy Lin, Dimi Shahbaz, + Johannes Stezenbach] +* Use libintl when it has bind_textdomain_codeset() and + GLib doesn't. [Owen] +* Improve generation of pseudo-random integers [Morten Welinder, + Sebastian Wilhelmi] +* Avoid literal UTF-8 in favor of octal escapes [Owen, Tomas Ogren] +* Cleanup include order [Sven Neumann] +* autoconf cleanups and bug fixes [Daniel, Matthias Clasen, Owen] +* Doc fixes and additions [Matthias] + +Other contributors: James M. Cape, Frederic Crozat, Martin Gansser, + Phuc LeHong, Manish Singh, Joshua Weage, Morten Welinder + +Overview of Changes from GLib 2.0.x to GLib-2.1.x +================================================= + +* Add copy of the Trio library to build and use for printf() when + system printf isn't good enough. Add g_printf()/etc. [Matthias Clasen] +* Add g_str_has_suffix()/g_str_has_prefix() [Alex Larsson] +* Add g_markup_parse_context_get_element() [Matthias] +* Add g_utf8_strreverse [Matthias] +* Add g_ascii_strtoull() [Tim Janik] +* Support scanning of 64-bit values with GScanner [Tim] +* Add g_set/get_application_name() [Havoc Pennington] +* Add G_LIKELY()/G_UNLIKELY() macros for hinting branch probabilities. + Use for g_return_if_fail(). [Matthias Clasen] +* Add G_GNUC_DEPRECATED macro [Tom Tromey] +* Improve the seeding algorithm of GRandom to avoid problems + with certain pathological seeds. Support G_RANDOM_VERSION=2.0 + environment variable. [Sebastian Wilhelmi] +* Improve thread configure checks, use -pthread where applicable + [Sebastian] +* Improve handlng of thread priorities [Sebastian] +* Fix up parameter names that might shadow functions from + system headers [Soeren Sandmann] +* Clean up usage of deprecated functions [Manish Singh] +* Docs fixes and improvements. In particular, include "Since" information. + [Matthias, Soeren, Martin Schulze, Daryll Strauss, Bill Janssen, + Owen Taylor, Morten Welinder]. + +Overview of Changes in GLib 2.0.7 +================================= + +* Fix C++ warnings in gtype.h [Dom Lachowicz] +* Fix g_type_fundamental_next() [Tim Janik] +* Fix various missing includes of config.h [Morten Welinder] +* Handle main loop initialization before g_thread_init [Sebastian Wilhelmi] +* Various 64-bit fixes [Manish Singh] +* Fix GPoll on Win32 [Tor Lillqvist, Herman Bloggs] +* Fix bug with buffering on UTF-8 IOChannels [Daniel Elstner] +* Misc bug and build fixes [Soren Andersen, Gustavo Carneiro, Tor, + Tim, Havoc Pennington, Matthias Clasen, Sebastian Rittau, + Masahiro Sakai, Arvind Samptur, HideToshi Tajima, Owen Taylor] +* Updated and new translations (be,cs,de,*fa,it,lv,pt_BR,tr) + +Overview of Changes in GLib 2.0.6 +================================= + +* Fix problem with interface prerequisites [Jon Trowbridge, Dave Camp] +* Clean up debug spew from GObject [Anders Carlsson] +* Compiler warning fixes [David L. Cooper II] +* Fix some problems with g_build_path() [Guillaume Chazarain, Owen Taylor] +* Fixes for --disable-debug [Sebastian Wilhelmi] +* Threading fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, + Rajkumar Sivasamy, Laurent Vivier] +* Documentation fixes [Jacob Berkman, Manuel Clos, Jared Dukat, + Sebastian Rittau, Linus Welleij] +* Misc bug fixes [Anders Carlsson, Sam Couter, Morten Welinder, Owen] +* Updated translations (bg,ko,vi) + +Overview of Changes in GLib 2.0.5 +================================= + +* Fix problem with interface prerequisites [Jon Trowbridge, Dave Camp] +* Clean up debug spew from GObject [Anders Carlsson] +* Compiler warning fixes [David L. Cooper II] +* Fix some problems with g_build_path() [Guillaume Chazarain, Owen Taylor] +* Fixes for --disable-debug [Sebastian Wilhelmi] +* Threading fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, + Rajkumar Sivasamy, Laurent Vivier] +* Documentation fixes [Jacob Berkman, Manuel Clos, Jared Dukat, + Sebastian Rittau, Linus Welleij] +* Misc bug fixes [Anders Carlsson, Sam Couter, Morten Welinder, Owen] +* Updated translations (bg,ko,vi) + +Overview of Changes in GLib 2.0.4 +================================= + +* Fix some 64-bit problems. (George Lebl, David L. Cooper II) +* Add note about Tru64 iconv to INSTALL. (Manuel Op de Coul) +* Fix problem with timouts > MAXINT. (Tim Janik, Owen Taylor) +* Updated translations (ca,es,fr,ja,gl,ms,nl,pl,pt,ru) + +Overview of Changes in GLib 2.0.3 +================================= + +* Handle sorting 0-length arrays (Ron Arts) +* Threading fixes (Sebastian Wilhelmi) +* Portability fixes (Miroslaw Dobrzanski-Neumann, Jacob Berkman, Gareth Pierce, + Sebastian, Qingjiang Yuan) +* Various fixes for glib-2.0.m4. (Jim Gettys, others.) +* Locate right glib-genmarshal when cross-compiling. (Mitch Natterer) +* Win32 fixes (Tor Lillqvist) +* Try to fix g_get_charset() related segfaults. (Owen) +* Fixes for gettext detection. (Dan Winship, HideToshi Tajima, Boyd Lynn Gerber, + Andrew P. Lentvorski, Jr.) +* Fix g_scanner_unexp_token() (Tim Janik, Sven Neumann) +* g_markup fixes. (Matthias Clasen.) +* Bug fixes and cleanups (Daniel Elstner, Matthias, Laszlo Peter, Morten Welinder, + Wayne Schuller) + +Overview of Changes in GLib 2.0.1 +================================= + +* Portability fixes for Sun's Forte compiler [Erwann Chenede] +* Performance improvements for GObject parameter lookup, + g_filename_to/from_utf8() [Alex Larsson] +* Actually check interface prerequisites [Matthias Clasen, + Miroslaw Dobrzanski-Neumann] +* Fix problem with glib-mkenums taking huge amounts of stack. [Owen Taylor] +* Fix g_signal_handlers_disconnect_by_func() for C++ [Damien Sandras] +* Fixes for g_log() and threading. + [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann, Tim Janik] +* Make g_print(), g_printerr(), g_warning(), etc, convert from + UTF-8 to the encoding of the locale [Sebastian Wilhelmi, Tim] +* Fixes for GIOChannel on windows. [Tor Lillqvist] +* Fix gsize/gint mismatches in giochannel.c [Miroslaw Dobrzanski-Neumann] +* Fix file descriptor leak in g_file_get_contents() [Matthias] +* Workaround iconv() problems on older Solaris [Lauri Alanko] +* Fix warnings with gcc-3.1 about asm const [Cody Russel] +* Minor bug fixes. + +Other contributors: Hans Breuer, LEE Sau Dan, Sven Neumann, Salmaso Raffaele, + Akira Tagoh, Morten Welinder + + +Overview of Changes in GLib 2.0.0 +================================= + +* Thread portability fixes [Sebastian Wilhelmi] +* Documentation updates [Owen Taylor] +* Make g_strerror(), g_strsignal() properly return UTF-8, + call bind_text_domain_codeset() so that error strings + are in UTF-8 as well. [Owen, Tor Lillqvist] + +Overview of Changes in GLib 2.0.0 rc1: +====================================== + +* Win32 fixes [Tor Lillqvist] +* Portability fixes [Finlay Dobbie, Miroslaw Dobrzanski-Neumann] +* Fix up g_date_strftime [Daniel Elstner] +* Add some structure padding [Tim Janik] +* Make g_get_homedir() prefer the users home directory to $HOME + +Other contributors: Matthias Clasen, Paolo Maggi, Christian Rose + +Overview of Changes in GLib 1.3.15: +=================================== + +* Speed up marshalers by using private access to GValue + [Anders Carlsson, Tim Janik] +* Reduce GValue to 2 elements [Tim] +* Add G_DEBUG environment variable, G_DEBUG=fatal_warnings [Matthias Clasen] +* Fixes for AIX compilation [Miroslaw Dobrzanski-Neumann] +* Add padding to various structures [Owen Taylor, Tim] +* Win32 fixes [Tor Lillqvist] + +Other contributors: James Henstridge, Ryan Lovett, Morten Welinder, + Daniel Elstner + +Overview of Changes in GLib 1.3.14: +=================================== + +* Register value transformations for gint64, guint64 [Andy Wingo] +* Build with large-file support [Sven Neumann, Owen Taylor] +* Fix handling of hostnames in URI's [Darin Adler] +* Main loop bug fixes [Havoc Pennington, Owen] +* Doc fixes and improvements [Manish Singh, Tim Janik] +* Support ' as attribute delimiters in GMarkup [Matthias Clasen] +* Win32 fixes [Hans Breuer, Tor Lillqvist] +* Threading bug and build fixes [Sebastian Wilhelmi, Miroslaw Dobrzanski-Neumann] +* Miscellaneous bug fixes + +Other contributors: Matthias Clasen, James Henstridge, Mitch Natterer, + Morten Welinder. + +Overview of Changes in GLib 1.3.13: +=================================== + +* Fix g_filename_to/from_uri for Win32 [Tor Lillqvist, Darin Adler] +* Miscellaneous win32 fixes [Tor, Hans Breuer] +* Fix thread options for gcc on AIX [Jerome Zago, Sebastian Wilhelmi] +* Documentation improvements [Ron Steinke, Matthias, Sebastian] +* Cache iconv converters as used by g_convert() [Jeffrey Stedfast] +* Bug fixes [Sven Neumann, Owen Taylor, Matthias Clasen, Jeffrey, + Laszlo Peter, Havoc Pennington, Tim Janik] + +Overview of Changes in GLib 1.3.12: +=================================== + +* Implement closure chaining, fixing up API (Tim Janik) +* Closure chaining test case (James Henstridge) +* Make GType long not int where both are equal width (Tim) +* Win32 fixes and improvements (Hans Breuer, Tor Lillqvist) +* Fixes for NetBSD. (Dan Winship) +* Use snprintf() for g_printf_string_upper_bound() where possible. (Matthias Clasen) +* Save space for GBSearchArray (Tim Janik) +* Documentation improvements. (Matthias, Sven Neumann, Havoc Pennington) + +Other contributors: Darin Adler, Chris Blizzard, Anders Carlson, Daniel Elstner, Michael Meeks, + Mark McLoughlin, Dave Neary, Manish Singh, Owen Taylor, HideToshi Tajima, + Sebastian Wilhelmi. + + +Overview of Changes in GLib 1.3.11: +=================================== + +* Win32 fixes [Hans Breuer, Tor Lillqvist] +* Documentation improvements [Matthias Clasen] +* Portable directory handling API [Hans] +* Threading fixes [Sebastian Wilhelmi, Havoc Pennington] +* Fix excess relocations in Unicode tables [Andrew Taylor] +* Fix gpattern for UTF-8 [Matthias Clasen] +* Support overriding class closures [Tim Janik] +* Support for derivation from G_TYPE_POINTER [Owen Taylor] +* Hide pointers to type information inside GType to reduce locking + [Alex Larsson, Tim] +* Adds check for direct inclusion of gobject/*.h [Owen] +* GObject API cleanups [Tim] + +Other contributors: Darin Adler, Jacob Berkman, Daniel Egger, Eric Lemings, + Michael Meeks, Mark McLoughlin, Arkadiusz Miskiewicz, Dan Winship + + +Overview of Changes in GLib 1.3.10: +=================================== + +* Many Win32 fixes and improvements [Tor Lillqvist] +* Documentation improvements [Matthias Clasen] +* g_string_printfa() renamed to g_string_append_printf() +* Use libcharset from libiconv to implement charset detection + more portably. [Owen Taylor, Hidetoshi Tajima] +* Add 64 bit type support to GObject [Joshua Pritikin, Mathieu Lacage, Owen] +* Make support for 64 bit integers a requirement [Joshua] +* GPattern improvements [Tim Janik, Matthias] +* Locale independent g_ascii_strtod / g_ascii_dtostr [Alex Larsson] +* Many bug fixes and minor tweaks. + +Other Contributors: Darin Adler, Jakub Jelinek, James Antill, Andrew Taylor, + Ben Gertzfield, Elliot Lee, Manish Singh, Abel Cheung, Laszlo Peter, + Sven Neumann, George Lebl, Raja Harinath, Sebastian Wilhelmi, + Jacob Berkman + + +Overview of Changes in GLib 1.3.9: +================================== + +* Fixes for comparison of threads [Sebastian Wilhelmi] +* Use vasprintf() when possible for g_strdup_printf [Matthias Clasen] +* Win32 fixes [Tor Lillqvist, Hans Breuer] +* Add a len argument to g_ascii_strup/strdown +* Bug, portability fixes, cleanups. + +Other Contributors: Darin Adler, Katsuhiro Okuno, Joshua N. Pritikin + + +Overview of Changes in GLib 1.3.8: +================================== + +* Documentation updates [Owen] +* Made GType interfaces overridable in derived types +* Many win32 fixes [Tor Lillqvist] +* Miscellaneous cleanups and fixes + +Other contributors: + Darin Adler, Matthias Clasen, Ron Steinke, Hans Breuer, Alex Larsson + + +Overview of Changes in GLib 1.3.7: +================================== + +* Integrate GClosure support into the main loop [Owen Taylor] +* More GSignal convenience functions (macros) [Sven Neumann, Tim Janik] +* Introduced weak references for GObject [James Henstridge, Sven, Tim] +* Minor hash table optimizations +* Main loop and threading improvements [Sebastian Wilhelmi] +* Added g_ascii_* functions to be used for locale insensitive UTF-8 + compliant code instead of old string functions [Darin Adler, Alex Larsson] +* Add functions for Unicode case-conversion, normalization, and + collation [Owen]* GString improvements [Owen] +* Reworked the GIOChannel code [Hidetoshi Tajima, Ron Steinke] +* Removed glib-config-2.0 in favour of pkgconfig [Sebastian] +* Make code 64bit clean [Mark Murnane] +* More G_CONST_RETURN fixes +* Many improvements to the win32 code [Tor Lillqvist, Hans Breuer] +* Miscellaneous bug and API fixes + +Other contributors: + Michael Natterer, Christopher James Lahey, Padraig O'Briain, + Matthias Clasen, Josh Pritikin, Steve Baker, Cesar Rincon, Garry R. Osgood, + Michael Meeks, Laszlo Peter, Martin Baulig, Kjartan Maraas, Andrew Lanoix, + Peter Williams + + +Overview of Changes in GLib 1.3.6: +================================== + +* Threads have a "return value" from g_thread_join +* Removed ability to adjust thread stack size +* Prefix warnings with progname/PID by default, change toggle for this to + be an env variable G_MESSAGES_PREFIXED not a compile-time option +* GMarkup speedups +* GDate const, convenience fixups +* Include test cases that headers are compilable by C++ compiler +* Add ability to spawn processes with argv[0] != executable path. +* g_strstr_len, g_strrstr, g_strrstr_len +* Add length argument to g_utf8_strchr and g_utf8_strrchr. +* Misc bug fixes + + +Overview of Changes in GLib 1.3.5: +================================== + +* Added an installed glib-mkenums Perl program for parsing enumeration + declarations from header files. +* Mark some additional deprecated functions. +* Bug and Portability fixes + + +Overview of Changes in GLib 1.3.4: +================================== + +* Efficiency improvements for GThreadPool +* A few bug fixes +* Build fixes +* Documentation improvements + + +Overview of Changes in GLib 1.3.3: +================================== + +GLib: + +* More user_data support in various functions. +* Main loop API revamps to support per-thread main loops. +* Unicode handling improvements. +* Implemented debugging traps. +* G_CONST_RETURN specification all over the place. +* Various new small utility functions. +* Random number generator precision improvements. +* New configure option --disable-mem-pools. +* Many Win32 improvements. +* Added g_try_malloc() friends varinats. +* Many documentation improvements. +* Many threading improvements, support for dynamic allocation + of static mutexes. +* GHookLIst API cleanups. +* Improved format support of GDate parser. +* String function speed improvements with new g_stpcpy(). +* Hashtable API additions. +* New GPatternSpec for shell-style pattern matching (from GtkPatternSpec). +* Optimizations, cleanups, bug fixes. + +GObject: + +* Added many convenience functions. +* GClosure and GParamSpec use float/sink ref-counting scheme now. +* Reworked property change notification. +* Binary searchable array cleanups, so it's widely usable now. +* Added static content keeping for some GValue types. +* Support for statically scoped signal parameters. +* Extinguished property trailer args in set/get interface. +* Added support for abstract types. +* G_CONST_RETURN specification all over the place. +* Split parameter exchange functionality into value transforms + and parameter conversions. +* Added signal emission hooks and signal accumulators. +* Added interface prerequisites to support is_a (interface, object) + relations. +* Implemented GValueArray. +* New types, boxed: G_TYPE_VALUE, G_TYPE_CLOSURE, G_TYPE_GSTRING + GParamSpecs: G_TYPE_PARAM_PARAM, G_TYPE_PARAM_POINTER, G_TYPE_PARAM_CLOSURE, + G_TYPE_VALUE_ARRAY, G_TYPE_PARAM_UNICHAR, G_TYPE_PARAM_VALUE_ARRAY. +* Varrags value collection improvements. +* Implemented debugging traps. +* Made things thread-safe. +* Many documentation improvements. +* Many cleanups, optimizations and bug fixes. + + +Overview of Changes in GLib 1.3.2: +================================== + +GLib: + +* Win32 build improvements [Tor] +* Improvements to error reporting + (g_critical(), g_return_if_reached()) [Darin] +* Add g_strlcpy/g_strlcat [David Wheeler] +* New IO channel implementation for Win32 [Tor] +* Make g_array_free, g_string_free return pointer to memory requested + not to be freed. [Darin] +* Added GError based error reporting for thread functions. [Sebastian] +* Moved reference docs into GLib distribution. [Owen] +* Added g_convert() for doing convenient character set conversions based + on iconv. (GLib now requires libiconv or a native iconv.) [Havoc/Owen] +* Various Unicode handling additions (g_ucs4_to_utf8, g_utf8_validate(), + g_{locale,filename}_{to,from}_utf8) [Robert/Havoc/Owen] +* Portability fixes for threading. [Sebastian] +* Added convenient functions for launching new processes (g_spawn_*), + and shell quoting/unquoting functions. [Havoc] +* Split glib.h into many headers. [Sebastian] +* Added a simple callback-based parser for XML-like files (GMarkup). [Havoc] +* Fixed confusions between comparison functions that return <0, 0, >0 + and equaility functions that return FALSE,TRUE. [Sebastian] +* Added safe/portable temporary file manipulation functions. [Tor] +* autoconf improvements. [Raja] +* Many documentation improvements. +* Bug fixes. + +GObject: + +* Added boxed and pointer types. [Tim/Jonathan] +* Added callback abstraction (GClosure) [Tim] +* Added signal system (GSignal) [Tim] +* Make GTypePlugin an interface [Tim] +* Added GTypeModule - a simple GTypePlugin instantiation [Owen] +* Bug fixes. + + +What's new in GLib 1.3.1: +========================= + +* New GObject library added including object system based on + the GTK+ object system. +* Functions for getting the properties of Unicode characters, + computing the canonical decomposition and ordering combining + characters aand manipulating UTF-8 string manipulation based + on libunicode. +* GString now properly handles embedded nuls. +* Multiple fixes from the 1.2.x branch. +* Upgrade to libtool 1.3.3 +* Full thread support (thread creation and destruction). +* BeOS port, BeOS dynamic modules. +* Many improvements to the Windows ports. +* Improvements to the OS/2 port, OS/2 module support. +* Double ended queue implementation. +* GLib macros for printf() formatting, e.g. G_GULONG_FORMAT = "lu" +* New configure option --enable-msg-prefix to prefix messages, warnings + et ceteri with the program name and the process id. +* New thread-safe random number generator Mersenne Twister. +* g_strcompress() added, g_strescape() had a slight API change, and + more tightly defined semantics. +* the g_string(x) macro has been removed, #x may be used instead. + + diff --git a/glib/README.in b/glib/README.in new file mode 100644 index 0000000..03fa8c3 --- /dev/null +++ b/glib/README.in @@ -0,0 +1,288 @@ +General Information +=================== + +This is GLib version @GLIB_VERSION@. GLib is the low-level core +library that forms the basis for projects such as GTK+ and GNOME. It +provides data structure handling for C, portability wrappers, and +interfaces for such runtime functionality as an event loop, threads, +dynamic loading, and an object system. + +The official download locations are: + ftp://ftp.gtk.org/pub/glib + http://download.gnome.org/sources/glib + +The official web site is: + http://www.gtk.org/ + +Information about mailing lists can be found at + http://www.gtk.org/mailing-lists.html + +To subscribe, send mail to gtk-list-request@gnome.org +with the subject "subscribe". + +Installation +============ + +See the file 'INSTALL' + +How to report bugs +================== + +Bugs should be reported to the GNOME bug tracking system. +(http://bugzilla.gnome.org, product glib.) You will need +to create an account for yourself. + +In the bug report please include: + +* Information about your system. For instance: + + - What operating system and version + - For Linux, what version of the C library + + And anything else you think is relevant. + +* How to reproduce the bug. + + If you can reproduce it with one of the test programs that are built + in the tests/ subdirectory, that will be most convenient. Otherwise, + please include a short test program that exhibits the behavior. + As a last resort, you can also provide a pointer to a larger piece + of software that can be downloaded. + +* If the bug was a crash, the exact text that was printed out + when the crash occured. + +* Further information such as stack traces may be useful, but + is not necessary. + +Patches +======= + +Patches should also be submitted to bugzilla.gnome.org. If the +patch fixes an existing bug, add the patch as an attachment +to that bug report. + +Otherwise, enter a new bug report that describes the patch, +and attach the patch to that bug report. + +Patches should be in unified diff form. (The -up option to GNU diff.) + +Notes about GLib 2.32 +===================== + +* It is no longer necessary to use g_thread_init() or to link against + libgthread. libglib is now always thread-enabled. Custom thread + system implementations are no longer supported (including errorcheck + mutexes). + +* The thread and synchronisation APIs have been updated. + GMutex and GCond can be statically allocated without explicit + initialisation, as can new types GRWLock and GRecMutex. The + GStatic_______ variants of these types have been deprecated. GPrivate + can also be statically allocated and has a nicer API (deprecating + GStaticPrivate). Finally, g_thread_create() has been replaced with a + substantially simplified g_thread_new(). + +* The g_once_init_enter()/_leave() functions have been replaced with + macros that allow for a pointer to any gsize-sized object, not just a + gsize*. The assertions to ensure that a pointer to a correctly-sized + object is being used will not work with generic pointers (ie: (void*) + and (gpointer) casts) which would have worked with the old version. + +* It is now mandatory to include glib.h instead of individual headers. + +* The -uninstalled variants of the pkg-config files have been dropped. + +* For a long time, gobject-2.0.pc mistakenly declared a public + dependency on gthread-2.0.pc (when the dependency should have been + private). This means that programs got away with calling + g_thread_init() without explicitly listing gthread-2.0.pc among their + dependencies. + + gthread has now been removed as a gobject dependency, which will cause + such programs to break. + + The fix for this problem is either to declare an explicit dependency + on gthread-2.0.pc (if you care about compatibility with older GLib + versions) or to stop calling g_thread_init(). + +* g_debug() output is no longer enabled by default. It can be enabled + on a per-domain basis with the G_MESSAGES_DEBUG environment variable + like + G_MESSAGES_DEBUG=domain1,domain2 + or + G_MESSAGES_DEBUG=all + +Notes about GLib 2.30 +===================== + +* GObject includes a generic marshaller, g_cclosure_marshal_generic. + To use it, simply specify NULL as the marshaller in g_signal_new(). + The generic marshaller is implemented with libffi, and consequently + GObject depends on libffi now. + +Notes about GLib 2.28 +===================== + +* The GApplication API has changed compared to the version that was + included in the 2.25 development snapshots. Existing users will need + adjustments. + +Notes about GLib 2.26 +===================== + +* Nothing noteworthy. + +Notes about GLib 2.24 +===================== + +* It is now allowed to call g_thread_init(NULL) multiple times, and + to call glib functions before g_thread_init(NULL) is called + (although the later is mainly a change in docs as this worked before + too). See the GThread reference documentation for the details. + +* GObject now links to GThread and threads are enabled automatically + when g_type_init() is called. + +* GObject no longer allows to call g_object_set() on construct-only properties + while an object is being initialized. If this behavior is needed, setting a + custom constructor that just chains up will re-enable this functionality. + +* GMappedFile on an empty file now returns NULL for the contents instead of + returning an empty string. The documentation specifically states that code + may not rely on nul-termination here so any breakage caused by this change + is a bug in application code. + +Notes about GLib 2.22 +===================== + +* Repeated calls to g_simple_async_result_set_op_res_gpointer used + to leak the data. This has been fixed to always call the provided + destroy notify. + +Notes about GLib 2.20 +===================== + +* The functions for launching applications (e.g. g_app_info_launch() + + friends) now passes a FUSE file:// URI if possible (requires gvfs + with the FUSE daemon to be running and operational). With gvfs 2.26, + FUSE file:// URIs will be mapped back to gio URIs in the GFile + constructors. The intent of this change is to better integrate + POSIX-only applications, see bug #528670 for the rationale. The + only user-visible change is when an application needs to examine an + URI passed to it (e.g. as a positional parameter). Instead of + looking at the given URI, the application will now need to look at + the result of g_file_get_uri() after having constructed a GFile + object with the given URI. + +Notes about GLib 2.18 +===================== + +* The recommended way of using GLib has always been to only include the + toplevel headers glib.h, glib-object.h and gio.h. GLib enforces this by + generating an error when individual headers are directly included. + To help with the transition, the enforcement is not turned on by + default for GLib headers (it is turned on for GObject and GIO). + To turn it on, define the preprocessor symbol G_DISABLE_SINGLE_INCLUDES. + +Notes about GLib 2.16 +===================== + +* GLib now includes GIO, which adds optional dependencies against libattr + and libselinux for extended attribute and SELinux support. Use + --disable-xattr and --disable-selinux to build without these. + +Notes about GLib 2.10 +===================== + +* The functions g_snprintf() and g_vsnprintf() have been removed from + the gprintf.h header, since they are already declared in glib.h. This + doesn't break documented use of gprintf.h, but people have been known + to include gprintf.h without including glib.h. + +* The Unicode support has been updated to Unicode 4.1. This adds several + new members to the GUnicodeBreakType enumeration. + +* The support for Solaris threads has been retired. Solaris has provided + POSIX threads for long enough now to have them available on every + Solaris platform. + +* 'make check' has been changed to validate translations by calling + msgfmt with the -c option. As a result, it may fail on systems with + older gettext implementations (GNU gettext < 0.14.1, or Solaris gettext). + 'make check' will also fail on systems where the C compiler does not + support ELF visibility attributes. + +* The GMemChunk API has been deprecated in favour of a new 'slice + allocator'. See the g_slice documentation for more details. + +* A new type, GInitiallyUnowned, has been introduced, which is + intended to serve as a common implementation of the 'floating reference' + concept that is e.g. used by GtkObject. Note that changing the + inheritance hierarchy of a type can cause problems for language + bindings and other code which needs to work closely with the type + system. Therefore, switching to GInitiallyUnowned should be done + carefully. g_object_compat_control() has been added to GLib 2.8.5 + to help with the transition. + +Notes about GLib 2.6.0 +====================== + +* GLib 2.6 introduces the concept of 'GLib filename encoding', which is the + on-disk encoding on Unix, but UTF-8 on Windows. All GLib functions + returning or accepting pathnames have been changed to expect + filenames in this encoding, and the common POSIX functions dealing + with pathnames have been wrapped. These wrappers are declared in the + header which must be included explicitly; it is not + included through . + + On current (NT-based) Windows versions, where the on-disk file names + are Unicode, these wrappers use the wide-character API in the C + library. Thus applications can handle file names containing any + Unicode characters through GLib's own API and its POSIX wrappers, + not just file names restricted to characters in the system codepage. + + To keep binary compatibility with applications compiled against + older versions of GLib, the Windows DLL still provides entry points + with the old semantics using the old names, and applications + compiled against GLib 2.6 will actually use new names for the + functions. This is transparent to the programmer. + + When compiling against GLib 2.6, applications intended to be + portable to Windows must take the UTF-8 file name encoding into + consideration, and use the gstdio wrappers to access files whose + names have been constructed from strings returned from GLib. + +* Likewise, g_get_user_name() and g_get_real_name() have been changed + to return UTF-8 on Windows, while keeping the old semantics for + applications compiled against older versions of GLib. + +* The GLib uses an '_' prefix to indicate private symbols that + must not be used by applications. On some platforms, symbols beginning + with prefixes such as _g will be exported from the library, on others not. + In no case can applications use these private symbols. In addition to that, + GLib+ 2.6 makes several symbols private which were not in any installed + header files and were never intended to be exported. + +* To reduce code size and improve efficiency, GLib, when compiled + with the GNU toolchain, has separate internal and external entry + points for exported functions. The internal names, which begin with + IA__, may be seen when debugging a GLib program. + +* On Windows, GLib no longer opens a console window when printing + warning messages if stdout or stderr are invalid, as they are in + "Windows subsystem" (GUI) applications. Simply redirect stdout or + stderr if you need to see them. + +* The child watch functionality tends to reveal a bug in many + thread implementations (in particular the older LinuxThreads + implementation on Linux) where it's not possible to call waitpid() + for a child created in a different thread. For this reason, for + maximum portability, you should structure your code to fork all + child processes that you want to wait for from the main thread. + +* A problem was recently discovered with g_signal_connect_object(); + it doesn't actually disconnect the signal handler once the object being + connected to dies, just disables it. See the API docs for the function + for further details and the correct workaround that will continue to + work with future versions of GLib. diff --git a/glib/acglib.m4 b/glib/acglib.m4 new file mode 100644 index 0000000..4778bfa --- /dev/null +++ b/glib/acglib.m4 @@ -0,0 +1,131 @@ +## Portability defines that help interoperate with classic and modern autoconfs +ifdef([AC_TR_SH],[ +define([GLIB_TR_SH],[AC_TR_SH([$1])]) +define([GLIB_TR_CPP],[AC_TR_CPP([$1])]) +], [ +define([GLIB_TR_SH], + [patsubst(translit([[$1]], [*+], [pp]), [[^a-zA-Z0-9_]], [_])]) +define([GLIB_TR_CPP], + [patsubst(translit([[$1]], + [*abcdefghijklmnopqrstuvwxyz], + [PABCDEFGHIJKLMNOPQRSTUVWXYZ]), + [[^A-Z0-9_]], [_])]) +]) + +# GLIB_AC_DIVERT_BEFORE_HELP(STUFF) +# --------------------------------- +# Put STUFF early enough so that they are available for $ac_help expansion. +# Handle both classic (<= v2.13) and modern autoconf +AC_DEFUN([GLIB_AC_DIVERT_BEFORE_HELP], +[ifdef([m4_divert_text], [m4_divert_text([NOTICE],[$1])], + [ifdef([AC_DIVERT], [AC_DIVERT([NOTICE],[$1])], + [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)dnl +$1 +AC_DIVERT_POP()])])]) + +dnl GLIB_IF_VAR_EQ (ENV_VAR, VALUE [, EQUALS_ACTION] [, ELSE_ACTION]) +AC_DEFUN([GLIB_IF_VAR_EQ],[ + case "$[$1]" in + "[$2]"[)] + [$3] + ;; + *[)] + [$4] + ;; + esac +]) +dnl GLIB_STR_CONTAINS (SRC_STRING, SUB_STRING [, CONTAINS_ACTION] [, ELSE_ACTION]) +AC_DEFUN([GLIB_STR_CONTAINS],[ + case "[$1]" in + *"[$2]"*[)] + [$3] + ;; + *[)] + [$4] + ;; + esac +]) +dnl GLIB_ADD_TO_VAR (ENV_VARIABLE, CHECK_STRING, ADD_STRING) +AC_DEFUN([GLIB_ADD_TO_VAR],[ + GLIB_STR_CONTAINS($[$1], [$2], [$1]="$[$1]", [$1]="$[$1] [$3]") +]) + +# GLIB_SIZEOF (INCLUDES, TYPE, ALIAS) +# --------------------------------------------------------------- +# The definition here is based of that of AC_CHECK_SIZEOF +AC_DEFUN([GLIB_SIZEOF], +[AS_LITERAL_IF([$3], [], + [AC_FATAL([$0: requires literal arguments])])dnl +AC_CACHE_CHECK([size of $2], AS_TR_SH([glib_cv_sizeof_$3]), +[ # The cast to unsigned long works around a bug in the HP C Compiler + # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects + # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. + # This bug is HP SR number 8606223364. + _AC_COMPUTE_INT([(long) (sizeof ($2))], + [AS_TR_SH([glib_cv_sizeof_$3])], + [AC_INCLUDES_DEFAULT([$1])], + [AC_MSG_ERROR([cannot compute sizeof ($2), 77])]) +])dnl +AC_DEFINE_UNQUOTED(GLIB_TR_CPP(glib_sizeof_$3), $AS_TR_SH([glib_cv_sizeof_$3]), + [The size of $3, as computed by sizeof.]) +])# GLIB_SIZEOF + +dnl GLIB_BYTE_CONTENTS (INCLUDES, TYPE, ALIAS, N_BYTES, INITIALIZER) +AC_DEFUN([GLIB_BYTE_CONTENTS], +[pushdef([glib_ByteContents], GLIB_TR_SH([glib_cv_byte_contents_$3]))dnl +AC_CACHE_CHECK([byte contents of $5], glib_ByteContents, +[AC_TRY_RUN([#include +$1 +main() +{ + static $2 tv = $5; + char *p = (char*) &tv; + int i; + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + for (i = 0; i < $4; i++) + fprintf(f, "%s%d", i?",":"", *(p++)); + fprintf(f, "\n"); + exit(0); +}], + [glib_ByteContents=`cat conftestval` dnl'' +], + [glib_ByteContents=no], + [glib_ByteContents=no])]) +AC_DEFINE_UNQUOTED(GLIB_TR_CPP(glib_byte_contents_$3), [$[]glib_ByteContents], + [Byte contents of $3]) +popdef([glib_ByteContents])dnl +]) + +# GLIB_CHECK_VALUE(SYMBOL, INCLUDES, ACTION-IF-FAIL) +# --------------------------------------------------------------- +AC_DEFUN([GLIB_CHECK_VALUE], +[AC_CACHE_CHECK([value of $1], AS_TR_SH([glib_cv_value_$1]), + [_AC_COMPUTE_INT([$1], AS_TR_SH([glib_cv_value_$1]), [$2], [$3])]) +])dnl + +# GLIB_CHECK_COMPILE_WARNINGS(PROGRAM, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# --------------------------------------------------------------------- +# Try to compile PROGRAM, check for warnings +m4_define([GLIB_CHECK_COMPILE_WARNINGS], +[m4_ifvaln([$1], [AC_LANG_CONFTEST([$1])])dnl +rm -f conftest.$ac_objext +glib_ac_compile_save="$ac_compile" +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext' +AS_IF([_AC_EVAL_STDERR($ac_compile) && + AC_TRY_COMMAND([(if test -s conftest.err; then false ; else true; fi)])], + [$2], + [echo "$as_me: failed program was:" >&AS_MESSAGE_LOG_FD +cat conftest.$ac_ext >&AS_MESSAGE_LOG_FD +m4_ifvaln([$3],[$3])dnl]) +ac_compile="$glib_ac_compile_save" +rm -f conftest.$ac_objext conftest.err m4_ifval([$1], [conftest.$ac_ext])[]dnl +])# GLIB_CHECK_COMPILE_WARNINGS + +# GLIB_ASSERT_SET(VARIABLE) +# ------------------------- +AC_DEFUN([GLIB_ASSERT_SET], +[if test "x${$1+set}" != "xset" ; then + AC_MSG_ERROR($1 [must be set in cache file when cross-compiling.]) +fi +])dnl diff --git a/glib/acinclude.m4 b/glib/acinclude.m4 new file mode 100644 index 0000000..cac7f21 --- /dev/null +++ b/glib/acinclude.m4 @@ -0,0 +1,452 @@ +dnl @synopsis AC_FUNC_VSNPRINTF_C99 +dnl +dnl Check whether there is a vsnprintf() function with C99 semantics installed. +dnl +AC_DEFUN([AC_FUNC_VSNPRINTF_C99], +[AC_CACHE_CHECK(for C99 vsnprintf, + ac_cv_func_vsnprintf_c99, +[AC_TRY_RUN( +[#include +#include + +int +doit(char * s, ...) +{ + char buffer[32]; + va_list args; + int r; + + va_start(args, s); + r = vsnprintf(buffer, 5, s, args); + va_end(args); + + if (r != 7) + exit(1); + + /* AIX 5.1 and Solaris seems to have a half-baked vsnprintf() + implementation. The above will return 7 but if you replace + the size of the buffer with 0, it borks! */ + va_start(args, s); + r = vsnprintf(buffer, 0, s, args); + va_end(args); + + if (r != 7) + exit(1); + + exit(0); +} + +int +main(void) +{ + doit("1234567"); + exit(1); +}], ac_cv_func_vsnprintf_c99=yes, ac_cv_func_vsnprintf_c99=no, ac_cv_func_vsnprintf_c99=no)]) +dnl Note that the default is to be pessimistic in the case of cross compilation. +dnl If you know that the target has a C99 vsnprintf(), you can get around this +dnl by setting ac_func_vsnprintf_c99 to yes, as described in the Autoconf manual. +if test $ac_cv_func_vsnprintf_c99 = yes; then + AC_DEFINE(HAVE_C99_VSNPRINTF, 1, + [Define if you have a version of the vsnprintf function + with semantics as specified by the ISO C99 standard.]) +fi +])# AC_FUNC_VSNPRINTF_C99 + + +dnl @synopsis AC_FUNC_SNPRINTF_C99 +dnl +dnl Check whether there is a snprintf() function with C99 semantics installed. +dnl +AC_DEFUN([AC_FUNC_SNPRINTF_C99], +[AC_CACHE_CHECK(for C99 snprintf, + ac_cv_func_snprintf_c99, +[AC_TRY_RUN( +[#include +#include + +int +doit() +{ + char buffer[32]; + va_list args; + int r; + + r = snprintf(buffer, 5, "1234567"); + + if (r != 7) + exit(1); + + r = snprintf(buffer, 0, "1234567"); + + if (r != 7) + exit(1); + + r = snprintf(NULL, 0, "1234567"); + + if (r != 7) + exit(1); + + exit(0); +} + +int +main(void) +{ + doit(); + exit(1); +}], ac_cv_func_snprintf_c99=yes, ac_cv_func_snprintf_c99=no, ac_cv_func_snprintf_c99=no)]) +dnl Note that the default is to be pessimistic in the case of cross compilation. +dnl If you know that the target has a C99 snprintf(), you can get around this +dnl by setting ac_func_snprintf_c99 to yes, as described in the Autoconf manual. +if test $ac_cv_func_snprintf_c99 = yes; then + AC_DEFINE(HAVE_C99_SNPRINTF, 1, + [Define if you have a version of the snprintf function + with semantics as specified by the ISO C99 standard.]) +fi +])# AC_FUNC_SNPRINTF_C99 + + +dnl @synopsis AC_FUNC_PRINTF_UNIX98 +dnl +dnl Check whether the printf() family supports Unix98 %n$ positional parameters +dnl +AC_DEFUN([AC_FUNC_PRINTF_UNIX98], +[AC_CACHE_CHECK(whether printf supports positional parameters, + ac_cv_func_printf_unix98, +[AC_TRY_RUN( +[#include + +int +main (void) +{ + char buffer[128]; + + sprintf (buffer, "%2\$d %3\$d %1\$d", 1, 2, 3); + if (strcmp ("2 3 1", buffer) == 0) + exit (0); + exit (1); +}], ac_cv_func_printf_unix98=yes, ac_cv_func_printf_unix98=no, ac_cv_func_printf_unix98=no)]) +dnl Note that the default is to be pessimistic in the case of cross compilation. +dnl If you know that the target printf() supports positional parameters, you can get around +dnl this by setting ac_func_printf_unix98 to yes, as described in the Autoconf manual. +if test $ac_cv_func_printf_unix98 = yes; then + AC_DEFINE(HAVE_UNIX98_PRINTF, 1, + [Define if your printf function family supports positional parameters + as specified by Unix98.]) +fi +])# AC_FUNC_PRINTF_UNIX98 + +# Checks the location of the XML Catalog +# Usage: +# JH_PATH_XML_CATALOG([ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +# Defines XMLCATALOG and XML_CATALOG_FILE substitutions +AC_DEFUN([JH_PATH_XML_CATALOG], +[ + # check for the presence of the XML catalog + AC_ARG_WITH([xml-catalog], + AC_HELP_STRING([--with-xml-catalog=CATALOG], + [path to xml catalog to use]),, + [with_xml_catalog=/etc/xml/catalog]) + jh_found_xmlcatalog=true + XML_CATALOG_FILE="$with_xml_catalog" + AC_SUBST([XML_CATALOG_FILE]) + AC_MSG_CHECKING([for XML catalog ($XML_CATALOG_FILE)]) + if test -f "$XML_CATALOG_FILE"; then + AC_MSG_RESULT([found]) + else + jh_found_xmlcatalog=false + AC_MSG_RESULT([not found]) + fi + + # check for the xmlcatalog program + AC_PATH_PROG(XMLCATALOG, xmlcatalog, no) + if test "x$XMLCATALOG" = xno; then + jh_found_xmlcatalog=false + fi + + if $jh_found_xmlcatalog; then + ifelse([$1],,[:],[$1]) + else + ifelse([$2],,[AC_MSG_ERROR([could not find XML catalog])],[$2]) + fi +]) + +# Checks if a particular URI appears in the XML catalog +# Usage: +# JH_CHECK_XML_CATALOG(URI, [FRIENDLY-NAME], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND]) +AC_DEFUN([JH_CHECK_XML_CATALOG], +[ + AC_REQUIRE([JH_PATH_XML_CATALOG],[JH_PATH_XML_CATALOG(,[:])])dnl + AC_MSG_CHECKING([for ifelse([$2],,[$1],[$2]) in XML catalog]) + if $jh_found_xmlcatalog && \ + AC_RUN_LOG([$XMLCATALOG --noout "$XML_CATALOG_FILE" "$1" >&2]); then + AC_MSG_RESULT([found]) + ifelse([$3],,,[$3 +])dnl + else + AC_MSG_RESULT([not found]) + ifelse([$4],, + [AC_MSG_ERROR([could not find ifelse([$2],,[$1],[$2]) in XML catalog])], + [$4]) + fi +]) + + +# signed.m4 serial 1 (gettext-0.10.40) +dnl Copyright (C) 2001-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. + +AC_DEFUN([bh_C_SIGNED], +[ + AC_CACHE_CHECK([for signed], bh_cv_c_signed, + [AC_TRY_COMPILE(, [signed char x;], bh_cv_c_signed=yes, bh_cv_c_signed=no)]) + if test $bh_cv_c_signed = no; then + AC_DEFINE(signed, , + [Define to empty if the C compiler doesn't support this keyword.]) + fi +]) + + +# longlong.m4 serial 4 +dnl Copyright (C) 1999-2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_LONG_LONG if 'long long' works. + +AC_DEFUN([jm_AC_TYPE_LONG_LONG], +[ + AC_CACHE_CHECK([for long long], ac_cv_type_long_long, + [AC_TRY_LINK([long long ll = 1LL; int i = 63;], + [long long llmax = (long long) -1; + return ll << i | ll >> i | llmax / ll | llmax % ll;], + ac_cv_type_long_long=yes, + ac_cv_type_long_long=no)]) + if test $ac_cv_type_long_long = yes; then + AC_DEFINE(HAVE_LONG_LONG, 1, + [Define if you have the 'long long' type.]) + fi +]) + + +# longdouble.m4 serial 1 (gettext-0.11.6) +dnl Copyright (C) 2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. +dnl Test whether the compiler supports the 'long double' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_LONGDOUBLE], +[ + AC_CACHE_CHECK([for long double], gt_cv_c_long_double, + [if test "$GCC" = yes; then + gt_cv_c_long_double=yes + else + AC_TRY_COMPILE([ + /* The Stardent Vistra knows sizeof(long double), but does not support it. */ + long double foo = 0.0; + /* On Ultrix 4.3 cc, long double is 4 and double is 8. */ + int array [2*(sizeof(long double) >= sizeof(double)) - 1]; + ], , + gt_cv_c_long_double=yes, gt_cv_c_long_double=no) + fi]) + if test $gt_cv_c_long_double = yes; then + AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have the 'long double' type.]) + fi +]) + + + +# wchar_t.m4 serial 1 (gettext-0.11.6) +dnl Copyright (C) 2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. +dnl Test whether has the 'wchar_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WCHAR_T], +[ + AC_CACHE_CHECK([for wchar_t], gt_cv_c_wchar_t, + [AC_TRY_COMPILE([#include + wchar_t foo = (wchar_t)'\0';], , + gt_cv_c_wchar_t=yes, gt_cv_c_wchar_t=no)]) + if test $gt_cv_c_wchar_t = yes; then + AC_DEFINE(HAVE_WCHAR_T, 1, [Define if you have the 'wchar_t' type.]) + fi +]) + + +# wint_t.m4 serial 1 +dnl Copyright (C) 2003 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Bruno Haible. +dnl Test whether has the 'wint_t' type. +dnl Prerequisite: AC_PROG_CC + +AC_DEFUN([gt_TYPE_WINT_T], +[ + AC_CACHE_CHECK([for wint_t], gt_cv_c_wint_t, + [AC_TRY_COMPILE([#include + wint_t foo = (wchar_t)'\0';], , + gt_cv_c_wint_t=yes, gt_cv_c_wint_t=no)]) + if test $gt_cv_c_wint_t = yes; then + AC_DEFINE(HAVE_WINT_T, 1, [Define if you have the 'wint_t' type.]) + fi +]) + + +# intmax_t.m4 serial 1 +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +AC_PREREQ(2.13) + +# Define intmax_t to 'long' or 'long long' +# if it is not already defined in or . + +AC_DEFUN([jm_AC_TYPE_INTMAX_T], +[ + dnl For simplicity, we assume that a header file defines 'intmax_t' if and + dnl only if it defines 'uintmax_t'. + AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([jm_AC_HEADER_STDINT_H]) + if test $jm_ac_cv_header_inttypes_h = no && test $jm_ac_cv_header_stdint_h = no; then + AC_REQUIRE([jm_AC_TYPE_LONG_LONG]) + test $ac_cv_type_long_long = yes \ + && ac_type='long long' \ + || ac_type='long' + AC_DEFINE_UNQUOTED(intmax_t, $ac_type, + [Define to long or long long if and don't define.]) + else + AC_DEFINE(HAVE_INTMAX_T, 1, + [Define if you have the 'intmax_t' type in or .]) + fi +]) + +dnl An alternative would be to explicitly test for 'intmax_t'. + +AC_DEFUN([gt_AC_TYPE_INTMAX_T], +[ + AC_REQUIRE([jm_AC_HEADER_INTTYPES_H]) + AC_REQUIRE([jm_AC_HEADER_STDINT_H]) + AC_CACHE_CHECK(for intmax_t, gt_cv_c_intmax_t, + [AC_TRY_COMPILE([ +#include +#include +#if HAVE_STDINT_H_WITH_UINTMAX +#include +#endif +#if HAVE_INTTYPES_H_WITH_UINTMAX +#include +#endif +], [intmax_t x = -1;], gt_cv_c_intmax_t=yes, gt_cv_c_intmax_t=no)]) + if test $gt_cv_c_intmax_t = yes; then + AC_DEFINE(HAVE_INTMAX_T, 1, + [Define if you have the 'intmax_t' type in or .]) + else + AC_REQUIRE([jm_AC_TYPE_LONG_LONG]) + test $ac_cv_type_long_long = yes \ + && ac_type='long long' \ + || ac_type='long' + AC_DEFINE_UNQUOTED(intmax_t, $ac_type, + [Define to long or long long if and don't define.]) + fi +]) + + +# stdint_h.m4 serial 3 (gettext-0.11.6) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_STDINT_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([jm_AC_HEADER_STDINT_H], +[ + AC_CACHE_CHECK([for stdint.h], jm_ac_cv_header_stdint_h, + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_stdint_h=yes, + jm_ac_cv_header_stdint_h=no)]) + if test $jm_ac_cv_header_stdint_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_STDINT_H_WITH_UINTMAX, 1, + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) + + +# inttypes_h.m4 serial 5 (gettext-0.11.6) +dnl Copyright (C) 1997-2002 Free Software Foundation, Inc. +dnl This file is free software, distributed under the terms of the GNU +dnl General Public License. As a special exception to the GNU General +dnl Public License, this file may be distributed as part of a program +dnl that contains a configuration script generated by Autoconf, under +dnl the same distribution terms as the rest of that program. + +dnl From Paul Eggert. + +# Define HAVE_INTTYPES_H_WITH_UINTMAX if exists, +# doesn't clash with , and declares uintmax_t. + +AC_DEFUN([jm_AC_HEADER_INTTYPES_H], +[ + AC_CACHE_CHECK([for inttypes.h], jm_ac_cv_header_inttypes_h, + [AC_TRY_COMPILE( + [#include +#include ], + [uintmax_t i = (uintmax_t) -1;], + jm_ac_cv_header_inttypes_h=yes, + jm_ac_cv_header_inttypes_h=no)]) + if test $jm_ac_cv_header_inttypes_h = yes; then + AC_DEFINE_UNQUOTED(HAVE_INTTYPES_H_WITH_UINTMAX, 1, + [Define if exists, doesn't clash with , + and declares uintmax_t. ]) + fi +]) + + +m4_include(acglib.m4)dnl +m4_include(glib/libcharset/codeset.m4)dnl +m4_include(glib/libcharset/glibc21.m4)dnl +m4_include(m4macros/glib-gettext.m4)dnl diff --git a/glib/configure.ac b/glib/configure.ac new file mode 100644 index 0000000..48868d2 --- /dev/null +++ b/glib/configure.ac @@ -0,0 +1,3571 @@ +# Process this file with autoconf to produce a configure script. +AC_PREREQ([2.62]) + +dnl *********************************** +dnl *** include special GLib macros *** +dnl *********************************** + +m4_define(glib_configure_ac) + +# +# The following version number definitions apply to GLib, GModule, GObject, +# GThread and GIO as a whole, so if changes occurred in any of them, they are +# all treated with the same interface and binary age. +# +# Making releases: +# glib_micro_version += 1; +# glib_interface_age += 1; +# glib_binary_age += 1; +# if any functions have been added, set glib_interface_age to 0. +# if backwards compatibility has been broken, +# set glib_binary_age _and_ glib_interface_age to 0. +# +# remember to add a GLIB_VERSION_2_xx macro every time the minor version is +# bumped, as well as the GLIB_DEPRECATED_IN and GLIB_AVAILABLE_IN macros +# for that version - see gversion.h for further information. +# +# in easier to understand terms: +# +# on the stable branch, interface age == micro +# on the unstable (ie master), interface age = 0 + +m4_define([glib_major_version], [2]) +m4_define([glib_minor_version], [32]) +m4_define([glib_micro_version], [0]) +m4_define([glib_interface_age], [0]) +m4_define([glib_binary_age], + [m4_eval(100 * glib_minor_version + glib_micro_version)]) +m4_define([glib_version], + [glib_major_version.glib_minor_version.glib_micro_version]) + +# libtool version related macros +m4_define([glib_lt_release], [glib_major_version.glib_minor_version]) +m4_define([glib_lt_current], + [m4_eval(100 * glib_minor_version + glib_micro_version - glib_interface_age)]) +m4_define([glib_lt_revision], [glib_interface_age]) +m4_define([glib_lt_age], [m4_eval(glib_binary_age - glib_interface_age)]) +m4_define([glib_lt_current_minus_age], + [m4_eval(glib_lt_current - glib_lt_age)]) + +# if the minor version number is odd, then we want debugging. Otherwise +# we only want minimal debugging support. +m4_define([glib_debug_default], + [m4_if(m4_eval(glib_minor_version % 2), [1], [yes], [minimum])])dnl + + +AC_INIT(glib, [glib_version], + [http://bugzilla.gnome.org/enter_bug.cgi?product=glib]) + +AC_CONFIG_HEADER([config.h]) +AC_CONFIG_SRCDIR([glib/glib.h]) +AC_CONFIG_MACRO_DIR([m4macros]) + +# Save this value here, since automake will set cflags later +cflags_set=${CFLAGS+set} + +AM_INIT_AUTOMAKE([1.11 no-define no-dist-gzip dist-xz tar-ustar]) +AM_MAINTAINER_MODE([enable]) + +# Support silent build rules. Disable +# by either passing --disable-silent-rules to configure or passing V=1 +# to make +AM_SILENT_RULES([yes]) + +GLIB_MAJOR_VERSION=glib_major_version +GLIB_MINOR_VERSION=glib_minor_version +GLIB_MICRO_VERSION=glib_micro_version +GLIB_INTERFACE_AGE=glib_interface_age +GLIB_BINARY_AGE=glib_binary_age +GLIB_VERSION=glib_version + +AC_SUBST(GLIB_MAJOR_VERSION) +AC_SUBST(GLIB_MINOR_VERSION) +AC_SUBST(GLIB_MICRO_VERSION) +AC_SUBST(GLIB_VERSION) +AC_SUBST(GLIB_INTERFACE_AGE) +AC_SUBST(GLIB_BINARY_AGE) + +AC_DEFINE(GLIB_MAJOR_VERSION, [glib_major_version], + [Define to the GLIB major version]) +AC_DEFINE(GLIB_MINOR_VERSION, [glib_minor_version], + [Define to the GLIB minor version]) +AC_DEFINE(GLIB_MICRO_VERSION, [glib_micro_version], + [Define to the GLIB micro version]) +AC_DEFINE(GLIB_INTERFACE_AGE, [glib_interface_age], + [Define to the GLIB interface age]) +AC_DEFINE(GLIB_BINARY_AGE, [glib_binary_age], + [Define to the GLIB binary age]) + +# libtool versioning +LT_RELEASE=glib_lt_release +LT_CURRENT=glib_lt_current +LT_REVISION=glib_lt_revision +LT_AGE=glib_lt_age +LT_CURRENT_MINUS_AGE=glib_lt_current_minus_age +AC_SUBST(LT_RELEASE) +AC_SUBST(LT_CURRENT) +AC_SUBST(LT_REVISION) +AC_SUBST(LT_AGE) +AC_SUBST(LT_CURRENT_MINUS_AGE) + +dnl Checks for programs. +AC_PROG_CC +AC_PROG_CPP + +AM_CONDITIONAL(HAVE_GCC, [test "$GCC" = "yes"]) + +AC_CANONICAL_HOST + +AC_MSG_CHECKING([for the BeOS]) +case $host in + *-*-beos*) + glib_native_beos="yes" + ;; + *) + glib_native_beos="no" + ;; +esac +AC_MSG_RESULT([$glib_native_beos]) + +dnl + +AC_MSG_CHECKING([for Win32]) +LIB_EXE_MACHINE_FLAG=X86 +case "$host" in + *-*-mingw*) + glib_native_win32=yes + glib_pid_type='void *' + glib_cv_stack_grows=no + # Unfortunately the mingw implementations of C99-style snprintf and vsnprintf + # don't seem to be quite good enough, at least not in mingw-runtime-3.14. + # (Sorry, I don't know exactly what is the problem, but it is related to + # floating point formatting and decimal point vs. comma.) + # The simple tests in AC_FUNC_VSNPRINTF_C99 and AC_FUNC_SNPRINTF_C99 aren't + # rigorous enough to notice, though. + # So preset the autoconf cache variables. + ac_cv_func_vsnprintf_c99=no + ac_cv_func_snprintf_c99=no + case "$host" in + x86_64-*-*) + LIB_EXE_MACHINE_FLAG=X64 + ;; + esac + ;; + *) + glib_native_win32=no + glib_pid_type=int + ;; +esac +case $host in + *-*-linux*) + glib_os_linux=yes + ;; +esac + +AC_MSG_RESULT([$glib_native_win32]) + +AC_SUBST(LIB_EXE_MACHINE_FLAG) + +glib_have_carbon=no +AC_MSG_CHECKING([for Mac OS X Carbon support]) +AC_TRY_CPP([ +#include +#include +], glib_have_carbon=yes) + +AC_MSG_RESULT([$glib_have_carbon]) + +AM_CONDITIONAL(OS_WIN32, [test "$glib_native_win32" = "yes"]) +AM_CONDITIONAL(OS_WIN32_X64, [test "$LIB_EXE_MACHINE_FLAG" = "X64"]) +AM_CONDITIONAL(OS_UNIX, [test "$glib_native_win32" != "yes"]) +AM_CONDITIONAL(OS_LINUX, [test "$glib_os_linux" = "yes"]) +AM_CONDITIONAL(OS_CARBON, [test "$glib_have_carbon" = "yes"]) + +if test "$glib_native_win32" = "yes"; then + AC_CHECK_TOOL(WINDRES, windres, no) + if test "$WINDRES" = no; then + AC_MSG_ERROR([*** Could not find an implementation of windres in your PATH.]) + fi + AC_CHECK_TOOL(NM, nm, no) + if test "$NM" = no; then + AC_MSG_ERROR([*** Could not find an implementation of nm in your PATH.]) + fi + AC_CHECK_TOOL(RANLIB, ranlib, :) + AC_CHECK_PROG(ms_librarian, [lib.exe], [yes], [no]) +fi +AM_CONDITIONAL(MS_LIB_AVAILABLE, [test x$ms_librarian = xyes]) + +if test "$glib_native_win32" != yes; then + # libtool option to control which symbols are exported + # right now, symbols starting with _ are not exported + LIBTOOL_EXPORT_OPTIONS='-export-symbols-regex "^g.*"' +else + # We currently use .def files on Windows + LIBTOOL_EXPORT_OPTIONS= +fi +AC_SUBST(LIBTOOL_EXPORT_OPTIONS) + +if test "x$glib_have_carbon" = "xyes"; then + AC_DEFINE(HAVE_CARBON, 1, [define to 1 if Carbon is available]) + LDFLAGS="$LDFLAGS -framework Carbon" +fi + +gl_GLIBC21 +if test "x$GLIBC21" = "xyes"; then + AC_DEFINE([_GNU_SOURCE], 1, [Make all glibc extensions visible]) +fi + +dnl declare --enable-* args and collect ac_help strings +AC_ARG_ENABLE(debug, + AC_HELP_STRING([--enable-debug=@<:@no/minimum/yes@:>@], + [turn on debugging @<:@default=glib_debug_default@:>@]),, + enable_debug=glib_debug_default) + +AC_ARG_ENABLE(gc_friendly, + [AC_HELP_STRING([--enable-gc-friendly], + [turn on garbage collector friendliness [default=no]])],, + [enable_gc_friendly=no]) +AC_ARG_ENABLE(mem_pools, + [AC_HELP_STRING([--disable-mem-pools], + [disable all glib memory pools])],, + [disable_mem_pools=no]) +AC_ARG_ENABLE(rebuilds, + [AC_HELP_STRING([--disable-rebuilds], + [disable all source autogeneration rules])],, + [enable_rebuilds=yes]) + +AC_MSG_CHECKING([whether to enable garbage collector friendliness]) +if test "x$enable_gc_friendly" = "xyes"; then + AC_DEFINE(ENABLE_GC_FRIENDLY_DEFAULT, 1, [Whether to enable GC friendliness by default]) + AC_MSG_RESULT([yes]) +else + AC_MSG_RESULT([no]) +fi + +AC_MSG_CHECKING([whether to disable memory pools]) +if test "x$disable_mem_pools" = "xno"; then + AC_MSG_RESULT([no]) +else + AC_DEFINE(DISABLE_MEM_POOLS, [1], [Whether to disable memory pools]) + AC_MSG_RESULT([yes]) +fi + +dnl location to install runtime libraries, e.g. ../../lib to install +dnl to /lib if libdir is /usr/lib +AC_ARG_WITH(runtime-libdir, + [AC_HELP_STRING([--with-runtime-libdir=RELPATH], + [install runtime libraries relative to libdir])], + [], + [with_runtime_libdir=""]) +GLIB_RUNTIME_LIBDIR="$with_runtime_libdir" +ABS_GLIB_RUNTIME_LIBDIR="`readlink -f $libdir/$with_runtime_libdir`" +AC_SUBST(GLIB_RUNTIME_LIBDIR) +AC_SUBST(ABS_GLIB_RUNTIME_LIBDIR) +AM_CONDITIONAL(HAVE_GLIB_RUNTIME_LIBDIR, [test "x$with_runtime_libdir" != "x"]) + +dnl Check for a working C++ compiler, but do not bail out, if none is found. +AC_CHECK_TOOLS(CXX, [$CCC c++ g++ gcc CC cxx cc++ cl], [gcc]) +AC_LANG_SAVE +AC_LANG_CPLUSPLUS +AC_TRY_COMPILE(,[class a { int b; } c;], ,CXX=) +AM_CONDITIONAL(HAVE_CXX, [test "$CXX" != ""]) +AC_LANG_RESTORE + +AM_PROG_CC_STDC +AM_PROG_CC_C_O +AC_PROG_INSTALL + +AC_SYS_LARGEFILE + +PKG_PROG_PKG_CONFIG(0.16) + +if test "x$enable_debug" = "xyes"; then + if test x$cflags_set != xset ; then + case " $CFLAGS " in + *[[\ \ ]]-g[[\ \ ]]*) ;; + *) CFLAGS="$CFLAGS -g" ;; + esac + fi + GLIB_DEBUG_FLAGS="-DG_ENABLE_DEBUG" +else + GLIB_DEBUG_FLAGS="-DG_DISABLE_CAST_CHECKS" + + if test "x$enable_debug" = "xno"; then + GLIB_DEBUG_FLAGS="$GLIB_DEBUG_FLAGS -DG_DISABLE_ASSERT -DG_DISABLE_CHECKS" + fi +fi + +# Ensure MSVC-compatible struct packing convention is used when +# compiling for Win32 with gcc. +# What flag to depends on gcc version: gcc3 uses "-mms-bitfields", while +# gcc2 uses "-fnative-struct". +if test x"$glib_native_win32" = xyes; then + if test x"$GCC" = xyes; then + msnative_struct='' + AC_MSG_CHECKING([how to get MSVC-compatible struct packing]) + if test -z "$ac_cv_prog_CC"; then + our_gcc="$CC" + else + our_gcc="$ac_cv_prog_CC" + fi + case `$our_gcc --version | sed -e 's,\..*,.,' -e q` in + 2.) + if $our_gcc -v --help 2>/dev/null | grep fnative-struct >/dev/null; then + msnative_struct='-fnative-struct' + fi + ;; + *) + if $our_gcc -v --help 2>/dev/null | grep ms-bitfields >/dev/null; then + msnative_struct='-mms-bitfields' + fi + ;; + esac + if test x"$msnative_struct" = x ; then + AC_MSG_RESULT([no way]) + AC_MSG_WARN([produced libraries might be incompatible with MSVC-compiled code]) + else + CFLAGS="$CFLAGS $msnative_struct" + AC_MSG_RESULT([${msnative_struct}]) + fi + fi +fi +GLIB_EXTRA_CFLAGS="${msnative_struct}" +AC_SUBST(GLIB_EXTRA_CFLAGS) + +AC_EXEEXT + +# define a MAINT-like variable REBUILD which is set if Perl +# and awk are found, so autogenerated sources can be rebuilt +AC_PROG_AWK +AC_CHECK_PROGS(PERL, [perl5 perl]) +# We would like indent, but don't require it. +AC_CHECK_PROG(INDENT, indent, indent) +REBUILD=\# +if test "x$enable_rebuilds" = "xyes" && \ + test -n "$PERL" && \ + $PERL -e 'exit !($] >= 5.002)' > /dev/null 2>&1 && \ + test -n "$AWK" ; then + REBUILD= +fi +AC_SUBST(REBUILD) + +# Need full path to Perl for glib-mkenums +# +if test "x$PERL" != x ; then + AC_PATH_PROG(PERL_PATH, [$PERL]) +fi +if test "x$PERL_PATH" = x ; then + PERL_PATH="/usr/bin/env perl" +fi +AC_SUBST(PERL_PATH) + +# Need suitable python path for greport +AM_PATH_PYTHON(2.5,,PYTHON="/usr/bin/env python2.5") + + +dnl *********************** +dnl *** Tests for iconv *** +dnl *********************** +dnl +dnl We do this before the gettext checks, to avoid distortion + +dnl On Windows we use a native implementation + +if test x"$glib_native_win32" = xyes; then + with_libiconv=native +else + AC_ARG_WITH(libiconv, + [AC_HELP_STRING([--with-libiconv=@<:@no/gnu/native@:>@], + [use the libiconv library])],, + [with_libiconv=maybe]) + + found_iconv=no + case $with_libiconv in + maybe) + # Check in the C library first + AC_CHECK_FUNC(iconv_open, [with_libiconv=no; found_iconv=yes]) + # Check if we have GNU libiconv + if test $found_iconv = "no"; then + AC_CHECK_LIB(iconv, libiconv_open, [with_libiconv=gnu; found_iconv=yes]) + fi + # Check if we have a iconv in -liconv, possibly from vendor + if test $found_iconv = "no"; then + AC_CHECK_LIB(iconv, iconv_open, [with_libiconv=native; found_iconv=yes]) + fi + ;; + no) + AC_CHECK_FUNC(iconv_open, [with_libiconv=no; found_iconv=yes]) + ;; + gnu|yes) + AC_CHECK_LIB(iconv, libiconv_open, [with_libiconv=gnu; found_iconv=yes]) + ;; + native) + AC_CHECK_LIB(iconv, iconv_open, [with_libiconv=native; found_iconv=yes]) + ;; + esac + + if test "x$found_iconv" = "xno" ; then + AC_MSG_ERROR([*** No iconv() implementation found in C library or libiconv]) + fi +fi + +AC_ARG_ENABLE(iconv-cache, + [AC_HELP_STRING([--enable-iconv-cache=@<:@yes/no/auto@:>@], + [cache iconv descriptors [default=auto]])],, + [enable_iconv_cache=auto]) + +AC_MSG_CHECKING([whether to cache iconv descriptors]) +case $enable_iconv_cache in + auto) + if test $ac_cv_gnu_library_2_1 = yes; then + enable_iconv_cache=no + else + enable_iconv_cache=yes + fi + ;; + yes|no) + ;; + *) AC_MSG_ERROR([Value given to --enable-iconv-cache must be one of yes, no or auto]) + ;; +esac + +if test $enable_iconv_cache = yes; then + AC_DEFINE(NEED_ICONV_CACHE,1,[Do we cache iconv descriptors]) +fi + +AC_MSG_RESULT($enable_iconv_cache) + + +dnl +dnl zlib support +dnl +PKG_CHECK_MODULES([ZLIB], [zlib], [found_zlib=yes], [found_zlib=no]) +if test "x$found_zlib" = "xno" ; then + AC_CHECK_LIB(z, inflate, [AC_CHECK_HEADER(zlib.h, found_zlib=yes)]) + if test "x$found_zlib" = "xno" ; then + AC_MSG_ERROR([*** Working zlib library and headers not found ***]) + fi + ZLIB_LIBS='-lz' + AC_SUBST(ZLIB_LIBS) +fi + +PKG_CHECK_MODULES(LIBFFI, [libffi >= 3.0.0]) +AC_SUBST(LIBFFI_CFLAGS) +AC_SUBST(LIBFFI_LIBS) + +dnl +dnl gettext support +dnl + +ALL_LINGUAS="`grep -v '^#' "$srcdir/po/LINGUAS" | tr '\n' ' '`" +AC_SUBST([CONFIG_STATUS_DEPENDENCIES],['$(top_srcdir)/po/LINGUAS']) +GLIB_GNU_GETTEXT + +if test "$gt_cv_have_gettext" != "yes" ; then + AC_MSG_ERROR([ +*** You must have either have gettext support in your C library, or use the +*** GNU gettext library. (http://www.gnu.org/software/gettext/gettext.html +]) +fi + +LIBS="$INTLLIBS $LIBS" + +GETTEXT_PACKAGE=glib20 +AC_SUBST(GETTEXT_PACKAGE) +AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, ["$GETTEXT_PACKAGE"], + [Define the gettext package to be used]) + +GLIB_DEFINE_LOCALEDIR(GLIB_LOCALE_DIR) + +dnl +dnl Now we are done with gettext checks, figure out ICONV_LIBS +dnl + +if test x"$glib_native_win32" != xyes; then + if test x$with_libiconv != xno ; then + case " $INTLLIBS " in + *[[\ \ ]]-liconv[[\ \ ]]*) ;; + *) ICONV_LIBS="-liconv" ;; + esac + fi +fi +AC_SUBST(ICONV_LIBS) + +case $with_libiconv in + gnu) + AC_DEFINE(USE_LIBICONV_GNU, 1, [Using GNU libiconv]) + ;; + native) + AC_DEFINE(USE_LIBICONV_NATIVE, 1, [Using a native implementation of iconv in a separate library]) + ;; +esac + +dnl Initialize libtool +LT_PREREQ([2.2]) +LT_INIT([disable-static win32-dll]) +dnl when using libtool 2.x create libtool early, because it's used in configure +m4_ifdef([LT_OUTPUT], [LT_OUTPUT]) + + +if test "x$GCC" = "xyes"; then + case " $CFLAGS " in + *[[\ \ ]]-Wall[[\ \ ]]*) ;; + *) CFLAGS="$CFLAGS -Wall" ;; + esac +fi + +if test "$glib_native_win32" = "yes"; then + if test x$enable_static = xyes -a x$enable_shared = xyes; then + AC_MSG_ERROR([Can not build both shared and static at the same time on Windows.]) + fi + if test x$enable_static = xyes; then + glib_win32_static_compilation=yes + GLIB_WIN32_STATIC_COMPILATION_DEFINE="#define GLIB_STATIC_COMPILATION 1 +#define GOBJECT_STATIC_COMPILATION 1" + AC_SUBST(GLIB_WIN32_STATIC_COMPILATION_DEFINE) + fi +fi +AM_CONDITIONAL(OS_WIN32_AND_DLL_COMPILATION, [test x$glib_native_win32 = xyes -a x$glib_win32_static_compilation != xyes]) + +dnl +dnl DU4 native cc currently needs -std1 for ANSI mode (instead of K&R) +dnl +if test $cross_compiling != yes ; then + AC_MSG_CHECKING([for extra flags to get ANSI library prototypes]) + glib_save_LIBS=$LIBS + LIBS="$LIBS -lm" + AC_TRY_RUN([#include + int main (void) { return (log(1) != log(1.)); }], + AC_MSG_RESULT(none needed), + glib_save_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -std1" + AC_TRY_RUN([#include + int main (void) { return (log(1) != log(1.)); }], + AC_MSG_RESULT(-std1), + AC_MSG_RESULT() + CFLAGS=$glib_save_CFLAGS + AC_MSG_WARN( + [No ANSI prototypes found in library. (-std1 didn't work.)]) + ) + ) + LIBS=$glib_save_LIBS +fi + +dnl NeXTStep cc seems to need this +AC_MSG_CHECKING([for extra flags for POSIX compliance]) +AC_TRY_COMPILE([#include ], [DIR *dir;], + AC_MSG_RESULT(none needed), + glib_save_CFLAGS=$CFLAGS + CFLAGS="$CFLAGS -posix" + AC_TRY_COMPILE([#include ], [DIR *dir;], + AC_MSG_RESULT(-posix), + AC_MSG_RESULT() + CFLAGS=$glib_save_CFLAGS + AC_MSG_WARN([Could not determine POSIX flag. (-posix didn't work.)]))) + +# Checks for library functions. +AC_FUNC_VPRINTF +AC_FUNC_ALLOCA +AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2) +AC_CHECK_FUNCS(atexit on_exit timegm gmtime_r) + +AC_CHECK_SIZEOF(char) +AC_CHECK_SIZEOF(short) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(void *) +AC_CHECK_SIZEOF(long long) +AC_CHECK_SIZEOF(__int64) + +AC_CACHE_CHECK([for sig_atomic_t], ac_cv_type_sig_atomic_t, + [AC_TRY_LINK([#include + #include + sig_atomic_t val = 42;], + [return val == 42 ? 0 : 1], + ac_cv_type_sig_atomic_t=yes, + ac_cv_type_sig_atomic_t=no)]) +if test x$ac_cv_type_sig_atomic_t = xyes; then + AC_DEFINE(HAVE_SIG_ATOMIC_T, 1, + [Define if you have the 'sig_atomic_t' type.]) +fi + +if test x$ac_cv_sizeof_long = x8 || test x$ac_cv_sizeof_long_long = x8 || test x$ac_cv_sizeof___int64 = x8 ; then + : +else + AC_MSG_ERROR([ +*** GLib requires a 64 bit type. You might want to consider +*** using the GNU C compiler. +]) +fi + +if test x$glib_native_win32 != xyes && test x$ac_cv_sizeof_long_long = x8; then + # long long is a 64 bit integer. + AC_MSG_CHECKING(for format to printf and scanf a guint64) + AC_CACHE_VAL(glib_cv_long_long_format,[ + for format in ll q I64; do + AC_TRY_RUN([#include + int main() + { + long long b, a = -0x3AFAFAFAFAFAFAFALL; + char buffer[1000]; + sprintf (buffer, "%${format}u", a); + sscanf (buffer, "%${format}u", &b); + exit (b!=a); + } + ], + [glib_cv_long_long_format=${format} + break], + [],[:]) + done]) + if test -n "$glib_cv_long_long_format"; then + AC_MSG_RESULT(%${glib_cv_long_long_format}u) + AC_DEFINE(HAVE_LONG_LONG_FORMAT,1,[define if system printf can print long long]) + if test x"$glib_cv_long_long_format" = xI64; then + AC_DEFINE(HAVE_INT64_AND_I64,1,[define to support printing 64-bit integers with format I64]) + fi + else + AC_MSG_RESULT(none) + fi +elif test x$ac_cv_sizeof___int64 = x8; then + # __int64 is a 64 bit integer. + AC_MSG_CHECKING(for format to printf and scanf a guint64) + # We know this is MSVCRT.DLL, and what the formats are + glib_cv_long_long_format=I64 + AC_MSG_RESULT(%${glib_cv_long_long_format}u) + AC_DEFINE(HAVE_LONG_LONG_FORMAT,1,[define if system printf can print long long]) + AC_DEFINE(HAVE_INT64_AND_I64,1,[define to support printing 64-bit integers with format I64]) +fi + +AC_C_CONST + +dnl ok, here we try to check whether the systems prototypes for +dnl malloc and friends actually match the prototypes provided +dnl by gmem.h (keep in sync). i currently only know how to check +dnl this reliably with gcc (-Werror), improvements for other +dnl compilers are apprechiated. +SANE_MALLOC_PROTOS=no +AC_MSG_CHECKING([if malloc() and friends prototypes are gmem.h compatible]) +glib_save_CFLAGS=$CFLAGS +if test "x$GCC" = "xyes"; then + CFLAGS="$CFLAGS -Werror" + AC_TRY_COMPILE([#include ], [ + void* (*my_calloc_p) (size_t, size_t) = calloc; + void* (*my_malloc_p) (size_t) = malloc; + void (*my_free_p) (void*) = free; + void* (*my_realloc_p) (void*, size_t) = realloc; + my_calloc_p = 0; + my_malloc_p = 0; + my_free_p = 0; + my_realloc_p = 0; + ], + AC_DEFINE(SANE_MALLOC_PROTOS, 1, + [Define if you have correct malloc prototypes]) + SANE_MALLOC_PROTOS=yes) +fi +AC_MSG_RESULT($SANE_MALLOC_PROTOS) +CFLAGS=$glib_save_CFLAGS + +dnl +dnl check in which direction the stack grows +dnl +AC_CACHE_CHECK([for growing stack pointer],glib_cv_stack_grows,[ + AC_TRY_RUN([ + volatile int *a = 0, *b = 0; + void foo (void); + int main () { volatile int y = 7; a = &y; foo (); return b > a; } + void foo (void) { volatile int x = 5; b = &x; } + ], + glib_cv_stack_grows=no + , + glib_cv_stack_grows=yes + ,) +]) + +dnl AC_C_INLINE is useless to us since it bails out too early, we need to +dnl truely know which ones of `inline', `__inline' and `__inline__' are +dnl actually supported. +AC_CACHE_CHECK([for __inline],glib_cv_has__inline,[ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + __inline int foo () { return 0; } + int main () { return foo (); } + ]])], + glib_cv_has__inline=yes + , + glib_cv_has__inline=no + ,) +]) +case x$glib_cv_has__inline in +xyes) AC_DEFINE(G_HAVE___INLINE,1,[Have __inline keyword]) +esac +AC_CACHE_CHECK([for __inline__],glib_cv_has__inline__,[ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + __inline__ int foo () { return 0; } + int main () { return foo (); } + ]])], + glib_cv_has__inline__=yes + , + glib_cv_has__inline__=no + ,) +]) +case x$glib_cv_has__inline__ in +xyes) AC_DEFINE(G_HAVE___INLINE__,1,[Have __inline__ keyword]) +esac +AC_CACHE_CHECK([for inline], glib_cv_hasinline,[ + AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ + #undef inline + inline int foo () { return 0; } + int main () { return foo (); } + ]])], + glib_cv_hasinline=yes + , + glib_cv_hasinline=no + ,) +]) +case x$glib_cv_hasinline in +xyes) AC_DEFINE(G_HAVE_INLINE,1,[Have inline keyword]) +esac + +# if we can use inline functions in headers +AC_MSG_CHECKING(if inline functions in headers work) +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#if defined (G_HAVE_INLINE) && defined (__GNUC__) && defined (__STRICT_ANSI__) +# undef inline +# define inline __inline__ +#elif !defined (G_HAVE_INLINE) +# undef inline +# if defined (G_HAVE___INLINE__) +# define inline __inline__ +# elif defined (G_HAVE___INLINE) +# define inline __inline +# endif +#endif + +int glib_test_func2 (int); + +static inline int +glib_test_func1 (void) { + return glib_test_func2 (1); +} + +int +main (void) { + int i = 1; +}]])],[g_can_inline=yes],[g_can_inline=no]) +AC_MSG_RESULT($g_can_inline) + +dnl *** check for working do while(0) macros *** +AC_CACHE_CHECK([for working do while(0) macros], g_cv_support_dowhile_macros, [ + AC_TRY_COMPILE([],[ + #define STMT_START do + #define STMT_END while(0) + #define STMT_TEST STMT_START { i = 0; } STMT_END + int main(void) { int i = 1; STMT_TEST; return i; }], + [g_cv_support_dowhile_macros=yes], + [g_cv_support_dowhile_macros=no], + [g_cv_support_dowhile_macros=yes]) +]) +if test x$g_cv_support_dowhile_macros = xyes; then + AC_DEFINE(HAVE_DOWHILE_MACROS, 1, [define for working do while(0) macros]) +fi + +# check for flavours of varargs macros +AC_MSG_CHECKING(for ISO C99 varargs macros in C) +AC_TRY_COMPILE([],[ +int a(int p1, int p2, int p3); +#define call_a(...) a(1,__VA_ARGS__) +call_a(2,3); +],g_have_iso_c_varargs=yes,g_have_iso_c_varargs=no) +AC_MSG_RESULT($g_have_iso_c_varargs) + +AC_MSG_CHECKING(for ISO C99 varargs macros in C++) +if test "$CXX" = ""; then +dnl No C++ compiler + g_have_iso_cxx_varargs=no +else + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([],[ +int a(int p1, int p2, int p3); +#define call_a(...) a(1,__VA_ARGS__) +call_a(2,3); +],g_have_iso_cxx_varargs=yes,g_have_iso_cxx_varargs=no) + AC_LANG_C +fi +AC_MSG_RESULT($g_have_iso_cxx_varargs) + +AC_MSG_CHECKING(for GNUC varargs macros) +AC_TRY_COMPILE([],[ +int a(int p1, int p2, int p3); +#define call_a(params...) a(1,params) +call_a(2,3); +],g_have_gnuc_varargs=yes,g_have_gnuc_varargs=no) +AC_MSG_RESULT($g_have_gnuc_varargs) + +# check for GNUC visibility support +AC_MSG_CHECKING(for GNUC visibility attribute) +GLIB_CHECK_COMPILE_WARNINGS([AC_LANG_SOURCE([[ +void +__attribute__ ((visibility ("hidden"))) + f_hidden (void) +{ +} +void +__attribute__ ((visibility ("internal"))) + f_internal (void) +{ +} +void +__attribute__ ((visibility ("protected"))) + f_protected (void) +{ +} +void +__attribute__ ((visibility ("default"))) + f_default (void) +{ +} +int main (int argc, char **argv) +{ + f_hidden(); + f_internal(); + f_protected(); + f_default(); + return 0; +} +]])],g_have_gnuc_visibility=yes,g_have_gnuc_visibility=no) +AC_MSG_RESULT($g_have_gnuc_visibility) +AM_CONDITIONAL(HAVE_GNUC_VISIBILITY, [test x$g_have_gnuc_visibility = xyes]) + +AC_MSG_CHECKING([whether using Sun Studio C compiler]) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#if defined(__SUNPRO_C) || (__SUNPRO_C >= 0x550) +#else +# include "error: this is not Sun Studio." +#endif +]], [[]])], [ g_have_sunstudio_visibility=yes ], [ g_have_sunstudio_visibility=no ]) +AC_MSG_RESULT($g_have_sunstudio_visibility) +AM_CONDITIONAL(HAVE_SUNSTUDIO_VISIBILITY, [test x$g_have_sunstudio_visibility = xyes]) + +# check for bytesex stuff +AC_C_BIGENDIAN +if test x$ac_cv_c_bigendian = xuniversal ; then +AC_TRY_COMPILE([#include ], [#if __BYTE_ORDER == __BIG_ENDIAN +#else +#error Not a big endian. +#endif], + ac_cv_c_bigendian=yes + ,AC_TRY_COMPILE([#include ], [#if __BYTE_ORDER == __LITTLE_ENDIAN +#else +#error Not a little endian. +#endif], + ac_cv_c_bigendian=no + ,AC_MSG_WARN([Could not determine endianness.]))) +fi + + +# check for header files +AC_CHECK_HEADERS([dirent.h float.h limits.h pwd.h grp.h sys/param.h sys/poll.h sys/resource.h]) +AC_CHECK_HEADERS([sys/time.h sys/times.h sys/wait.h unistd.h values.h]) +AC_CHECK_HEADERS([sys/select.h sys/types.h stdint.h inttypes.h sched.h malloc.h]) +AC_CHECK_HEADERS([sys/vfs.h sys/vmount.h sys/statfs.h sys/statvfs.h]) +AC_CHECK_HEADERS([mntent.h sys/mnttab.h sys/vfstab.h sys/mntctl.h fstab.h]) +AC_CHECK_HEADERS([sys/uio.h sys/mkdev.h]) +AC_CHECK_HEADERS([linux/magic.h]) +AC_CHECK_HEADERS([sys/prctl.h]) + +AC_CHECK_HEADERS([sys/mount.h sys/sysctl.h], [], [], +[#if HAVE_SYS_PARAM_H + #include + #endif +]) + +AC_CHECK_HEADERS([xlocale.h]) + +# check for structure fields +AC_CHECK_MEMBERS([struct stat.st_mtimensec, struct stat.st_mtim.tv_nsec, struct stat.st_atimensec, struct stat.st_atim.tv_nsec, struct stat.st_ctimensec, struct stat.st_ctim.tv_nsec]) +AC_CHECK_MEMBERS([struct stat.st_blksize, struct stat.st_blocks, struct statfs.f_fstypename, struct statfs.f_bavail],,, [#include +#include +#include +#ifdef HAVE_SYS_STATFS_H +#include +#endif +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_SYS_MOUNT_H +#include +#endif]) +# struct statvfs.f_basetype is available on Solaris but not for Linux. +AC_CHECK_MEMBERS([struct statvfs.f_basetype],,, [#include ]) +AC_CHECK_MEMBERS([struct statvfs.f_fstypename],,, [#include ]) +AC_CHECK_MEMBERS([struct tm.tm_gmtoff, struct tm.__tm_gmtoff],,,[#include ]) + +AC_STRUCT_DIRENT_D_TYPE + +# Checks for libcharset +AM_LANGINFO_CODESET +AC_CHECK_HEADERS([stddef.h stdlib.h string.h]) +AC_CHECK_FUNCS(setlocale) + +# check additional type sizes +AC_CHECK_SIZEOF(size_t) + +dnl Try to figure out whether gsize, gssize should be long or int +AC_MSG_CHECKING([for the appropriate definition for size_t]) + +case $ac_cv_sizeof_size_t in + $ac_cv_sizeof_short) + glib_size_type=short + ;; + $ac_cv_sizeof_int) + glib_size_type=int + ;; + $ac_cv_sizeof_long) + glib_size_type=long + ;; + $ac_cv_sizeof_long_long) + glib_size_type='long long' + ;; + $ac_cv_sizeof__int64) + glib_size_type='__int64' + ;; + *) AC_MSG_ERROR([No type matching size_t in size]) + ;; +esac + +dnl If int/long are the same size, we see which one produces +dnl warnings when used in the location as size_t. (This matters +dnl on AIX with xlc) +dnl +if test $ac_cv_sizeof_size_t = $ac_cv_sizeof_int && + test $ac_cv_sizeof_size_t = $ac_cv_sizeof_long ; then + GLIB_CHECK_COMPILE_WARNINGS([AC_LANG_SOURCE([[ +#if defined(_AIX) && !defined(__GNUC__) +#pragma options langlvl=stdc89 +#endif +#include +int main () +{ + size_t s = 1; + unsigned int *size_int = &s; + return (int)*size_int; +} + ]])],glib_size_type=int, + [GLIB_CHECK_COMPILE_WARNINGS([AC_LANG_SOURCE([[ +#if defined(_AIX) && !defined(__GNUC__) +#pragma options langlvl=stdc89 +#endif +#include +int main () +{ + size_t s = 1; + unsigned long *size_long = &s; + return (int)*size_long; +} + ]])],glib_size_type=long)]) +fi + +AC_MSG_RESULT(unsigned $glib_size_type) + +# Check for some functions +AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk memmem) +AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid) +AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getfsstat getvfsstat) +# Check for high-resolution sleep functions +AC_CHECK_FUNCS(splice) +AC_CHECK_FUNCS(prlimit) + +# To avoid finding a compatibility unusable statfs, which typically +# successfully compiles, but warns to use the newer statvfs interface: +AS_IF([test $ac_cv_header_sys_statvfs_h = yes], [AC_CHECK_FUNCS([statvfs])]) +AS_IF([test $ac_cv_header_sys_statfs_h = yes -o $ac_cv_header_sys_mount_h = yes], [AC_CHECK_FUNCS([statfs])]) + +AC_MSG_CHECKING([whether to use statfs or statvfs]) +# Some systems have both statfs and statvfs, pick the most "native" for these +AS_IF([test x$ac_cv_func_statfs = xyes && test x$ac_cv_func_statvfs = xyes], + [ + # on solaris and irix, statfs doesn't even have the f_bavail field + AS_IF([test x$ac_cv_member_struct_statfs_f_bavail = xno], + [ac_cv_func_statfs=no], + # else, at least on linux, statfs is the actual syscall + [ac_cv_func_statvfs=no]) + ]) + +AS_IF([test x$ac_cv_func_statfs = xyes], + [ + AC_DEFINE([USE_STATFS], [1], [Define to use statfs()]) + AC_MSG_RESULT([statfs]) + ], + [test x$ac_cv_func_statvfs = xyes], + [ + AC_DEFINE([USE_STATVFS], [1], [Define to use statvfs()]) + AC_MSG_RESULT([statvfs]) + ], + [ AC_MSG_RESULT([neither])]) + +AC_CHECK_HEADERS(crt_externs.h) +AC_CHECK_FUNCS(_NSGetEnviron) + +AC_CHECK_FUNCS(newlocale uselocale strtod_l strtoll_l strtoull_l) + +AC_FUNC_VSNPRINTF_C99 +AC_FUNC_PRINTF_UNIX98 + +# Internet address families +if test $glib_native_win32 = yes; then + glib_inet_includes=[" +#include + "] +else + glib_inet_includes=[" +#include +#include + "] +fi + +glib_failed=false +GLIB_CHECK_VALUE(AF_INET, $glib_inet_includes, glib_failed=true) +GLIB_CHECK_VALUE(AF_INET6, $glib_inet_includes, glib_failed=true) +# winsock defines this even though it doesn't support it +GLIB_CHECK_VALUE(AF_UNIX, $glib_inet_includes, glib_failed=true) +if $glib_failed ; then + AC_MSG_ERROR([Could not determine values for AF_INET* constants]) +fi + +glib_failed=false +GLIB_CHECK_VALUE(MSG_PEEK, $glib_inet_includes, glib_failed=true) +GLIB_CHECK_VALUE(MSG_OOB, $glib_inet_includes, glib_failed=true) +GLIB_CHECK_VALUE(MSG_DONTROUTE, $glib_inet_includes, glib_failed=true) +if $glib_failed ; then + AC_MSG_ERROR([Could not determine values for MSG_* constants]) +fi + +AC_CHECK_FUNCS(getprotobyname_r endservent if_nametoindex) +AC_CHECK_HEADERS([netdb.h wspiapi.h arpa/nameser_compat.h]) + +if test $glib_native_win32 = no; then + # We can't just use AC_CHECK_FUNC/AC_CHECK_LIB here. Bug 586150 + NETWORK_LIBS="" + AC_MSG_CHECKING([for res_query]) + AC_TRY_LINK([#include + #include + #include + #include + ],[ + res_query("test", 0, 0, (void *)0, 0); + ],[AC_MSG_RESULT([yes])], + [save_libs="$LIBS" + LIBS="-lresolv $LIBS" + AC_TRY_LINK([#include + #include + #include + #include + ],[ + res_query("test", 0, 0, (void *)0, 0); + ],[AC_MSG_RESULT([in -lresolv]) + NETWORK_LIBS="-lresolv $NETWORK_LIBS"], + [LIBS="-lbind $save_libs" + AC_TRY_LINK([#include ], + [res_query("test", 0, 0, (void *)0, 0);], + [AC_MSG_RESULT([in -lbind]) + NETWORK_LIBS="-lbind $NETWORK_LIBS"], + [AC_MSG_ERROR(not found)])]) + LIBS="$save_libs"]) + AC_CHECK_FUNC(socket, :, AC_CHECK_LIB(socket, socket, + [NETWORK_LIBS="-lsocket $NETWORK_LIBS"], + [AC_MSG_ERROR(Could not find socket())])) +fi +AC_SUBST(NETWORK_LIBS) + +AC_CHECK_HEADER([linux/netlink.h], + [AC_DEFINE(HAVE_NETLINK, 1, [We have AF_NETLINK sockets])],, + [#include ]) +AM_CONDITIONAL(HAVE_NETLINK, [test "$ac_cv_header_linux_netlink_h" = "yes"]) + +AC_CHECK_TYPE([struct ip_mreqn], [ + AC_DEFINE(HAVE_IP_MREQN,, [Define if we have struct ip_mreqn])],, + [#include ]) + +case $host in + *-*-solaris* ) + AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, Needed to get declarations for msg_control and msg_controllen on Solaris) + AC_DEFINE(_XOPEN_SOURCE, 2, Needed to get declarations for msg_control and msg_controllen on Solaris) + AC_DEFINE(__EXTENSIONS__, 1, Needed to get declarations for msg_control and msg_controllen on Solaris) + ;; +esac + +dnl +dnl if statfs() takes 2 arguments (Posix) or 4 (Solaris) +dnl +if test "$ac_cv_func_statfs" = yes ; then + AC_MSG_CHECKING([number of arguments to statfs()]) + AC_TRY_COMPILE([#include + #ifdef HAVE_SYS_PARAM_H + #include + #endif + #ifdef HAVE_SYS_VFS_H + #include + #endif + #ifdef HAVE_SYS_MOUNT_H + #include + #endif + #ifdef HAVE_SYS_STATFS_H + #include + #endif], [struct statfs st; + statfs(NULL, &st);],[ + AC_MSG_RESULT([2]) + AC_DEFINE(STATFS_ARGS, 2, [Number of arguments to statfs()])],[ + AC_TRY_COMPILE([#include + #ifdef HAVE_SYS_PARAM_H + #include + #endif + #ifdef HAVE_SYS_VFS_H + #include + #endif + #ifdef HAVE_SYS_MOUNT_H + #include + #endif + #ifdef HAVE_SYS_STATFS_H + #include + #endif], [struct statfs st; + statfs(NULL, &st, sizeof (st), 0);],[ + AC_MSG_RESULT([4]) + AC_DEFINE(STATFS_ARGS, 4, [Number of arguments to statfs()])],[ + AC_MSG_RESULT(unknown) + AC_MSG_ERROR([unable to determine number of arguments to statfs()])])]) +fi + +# +# Check whether to use an included printf +# + +AC_ARG_ENABLE(included-printf, + [AC_HELP_STRING([--enable-included-printf], + [use included printf [default=auto]])], + enable_included_printf="$enableval") + +need_included_printf=no +if test "x$enable_included_printf" = "xyes" ; then + need_included_printf=yes +fi +if test "$ac_cv_func_vsnprintf_c99" != "yes" ; then + need_included_printf=yes +fi +if test "$ac_cv_func_printf_unix98" != "yes" ; then + need_included_printf=yes +fi +if test "x$ac_cv_sizeof_long_long" = "x8" && + test -z "$glib_cv_long_long_format" ; then + need_included_printf=yes +fi + +if test "x$enable_included_printf" = "xno" && + test "x$need_included_printf" = "xyes" ; then + AC_MSG_ERROR([ +*** Your C library's printf doesn't appear to have the features that +*** GLib needs, but you specified --enable-included-printf=no.]) +fi + +enable_included_printf=$need_included_printf + +AM_CONDITIONAL(HAVE_GOOD_PRINTF, test "$enable_included_printf" != "yes") +if test "$enable_included_printf" != "yes" ; then + AC_DEFINE(HAVE_GOOD_PRINTF,1,[define to use system printf]) +else + if test -z "$glib_cv_long_long_format" ; then + glib_cv_long_long_format="ll" + fi + AC_DEFINE(HAVE_VASPRINTF,1) +fi + +# Checks needed for gnulib vasnprintf +bh_C_SIGNED +jm_AC_TYPE_LONG_LONG +gt_TYPE_LONGDOUBLE +gt_TYPE_WCHAR_T +gt_TYPE_WINT_T +AC_TYPE_SIZE_T +AC_CHECK_TYPES(ptrdiff_t) +jm_AC_TYPE_INTMAX_T +AC_CHECK_FUNCS([snprintf wcslen]) +AC_FUNC_SNPRINTF_C99 + +# Check if bcopy can be used for overlapping copies, if memmove isn't found. +# The check is borrowed from the PERL Configure script. +if test "$ac_cv_func_memmove" != "yes"; then + AC_CACHE_CHECK(whether bcopy can handle overlapping copies, + glib_cv_working_bcopy,[AC_TRY_RUN([ + int main() { + char buf[128], abc[128], *b; + int len, off, align; + bcopy("abcdefghijklmnopqrstuvwxyz0123456789", abc, 36); + for (align = 7; align >= 0; align--) { + for (len = 36; len; len--) { + b = buf+align; bcopy(abc, b, len); + for (off = 1; off <= len; off++) { + bcopy(b, b+off, len); bcopy(b+off, b, len); + if (bcmp(b, abc, len)) return(1); + } + } + } + return(0); + }],glib_cv_working_bcopy=yes,glib_cv_working_bcopy=no)]) + + GLIB_ASSERT_SET(glib_cv_working_bcopy) + if test "$glib_cv_working_bcopy" = "yes"; then + AC_DEFINE(HAVE_WORKING_BCOPY,1,[Have a working bcopy]) + fi +fi + +# Check if needs to be included for fd_set +AC_MSG_CHECKING([for fd_set]) +AC_TRY_COMPILE([#include ], + [fd_set readMask, writeMask;], gtk_ok=yes, gtk_ok=no) +if test "$gtk_ok" = "yes"; then + AC_MSG_RESULT([yes, found in sys/types.h]) +else + AC_EGREP_HEADER(fd_set, sys/select.h, gtk_ok=yes) + if test "$gtk_ok" = "yes"; then + # *** FIXME: give it a different name + AC_DEFINE(HAVE_SYS_SELECT_H,1,[found fd_set in sys/select.h]) + AC_MSG_RESULT([yes, found in sys/select.h]) + else + AC_DEFINE(NO_FD_SET,1,[didn't find fd_set]) + AC_MSG_RESULT(no) + fi +fi + +dnl *** check for sane realloc() *** +AC_CACHE_CHECK([whether realloc (NULL,) will work],glib_cv_sane_realloc,[ + AC_TRY_RUN([#include + int main() { + return realloc (0, sizeof (int)) == 0; + }], + [glib_cv_sane_realloc=yes], + [glib_cv_sane_realloc=no], + [glib_cv_sane_realloc=yes]) +]) +if test x$glib_cv_sane_realloc = xyes; then + AC_DEFINE(REALLOC_0_WORKS,1,[whether realloc (NULL,) works]) +fi + +dnl Check for nl_langinfo and CODESET +AC_CACHE_CHECK([for nl_langinfo (CODESET)],glib_cv_langinfo_codeset,[ + AC_TRY_COMPILE([#include ], + [char *codeset = nl_langinfo (CODESET);], + [glib_cv_langinfo_codeset=yes], + [glib_cv_langinfo_codeset=no])]) +if test x$glib_cv_langinfo_codeset = xyes; then + AC_DEFINE(HAVE_CODESET,1,[Have nl_langinfo (CODESET)]) +fi + +dnl Check for nl_langinfo and LC_TIME parts that are needed in gdatetime.c +AC_CACHE_CHECK([for nl_langinfo (PM_STR)],glib_cv_langinfo_time,[ + AC_TRY_COMPILE([#include ], + [char *str; + str = nl_langinfo (PM_STR); + str = nl_langinfo (D_T_FMT); + str = nl_langinfo (D_FMT); + str = nl_langinfo (T_FMT); + str = nl_langinfo (T_FMT_AMPM); + str = nl_langinfo (MON_1); + str = nl_langinfo (ABMON_12); + str = nl_langinfo (DAY_1); + str = nl_langinfo (ABDAY_7);], + [glib_cv_langinfo_time=yes], + [glib_cv_langinfo_time=no])]) +if test x$glib_cv_langinfo_time = xyes; then + AC_DEFINE(HAVE_LANGINFO_TIME,1,[Have nl_langinfo (PM_STR)]) +fi + +dnl Check for nl_langinfo and _NL_CTYPE_OUTDIGITn_MB +AC_CACHE_CHECK([for nl_langinfo (_NL_CTYPE_OUTDIGITn_MB)], glib_cv_langinfo_outdigit,[ + AC_TRY_COMPILE([#include ], + [char *str; + str = nl_langinfo (_NL_CTYPE_OUTDIGIT0_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT1_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT2_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT3_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT4_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT5_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT6_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT7_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT8_MB); + str = nl_langinfo (_NL_CTYPE_OUTDIGIT9_MB);], + [glib_cv_langinfo_outdigit=yes], + [glib_cv_langinfo_outdigit=no])]) +if test x$glib_cv_langinfo_outdigit = xyes; then + AC_DEFINE(HAVE_LANGINFO_OUTDIGIT,1,[Have nl_langinfo (_NL_CTYPE_OUTDIGITn_MB)]) +fi + +dnl **************************************** +dnl *** posix_memalign *** +dnl **************************************** +AC_MSG_CHECKING(for a compliant posix_memalign() implementation) +AC_CACHE_VAL(glib_cv_compliant_posix_memalign,[ + glib_cv_compliant_posix_memalign=0 + if test "$ac_cv_func_posix_memalign" = "yes" ; then + AC_TRY_RUN([ + #define _XOPEN_SOURCE 600 + #include /* posix_memalign() should be defined here */ + /* some systems break if #include used */ + static void test_memalign (size_t boundary, size_t size) { + void *mem = 0; + if (posix_memalign (&mem, boundary, size) != 0 || !mem) + exit (1); + else + free (mem); + } + int main() { + test_memalign ( 128, 128 - 2 * sizeof (void*)); + test_memalign ( 256, 256 - 2 * sizeof (void*)); + test_memalign ( 512, 512 - 2 * sizeof (void*)); + test_memalign ( 1024, 1024 - 2 * sizeof (void*)); + test_memalign ( 2048, 2048 - 2 * sizeof (void*)); + test_memalign ( 4096, 4096 - 2 * sizeof (void*)); + test_memalign ( 8192, 8192 - 2 * sizeof (void*)); + test_memalign (16384, 16384 - 2 * sizeof (void*)); + test_memalign (32768, 32768 - 2 * sizeof (void*)); + exit (0); /* success */ + } + ], + [glib_cv_compliant_posix_memalign=1], [], [:]) + : + fi + ]) +if test "$glib_cv_compliant_posix_memalign" = "1"; then + AC_MSG_RESULT(yes) + AC_DEFINE(POSIX_MEMALIGN_WITH_COMPLIANT_ALLOCS, 1, [define if posix_memalign() can allocate any size]) +else + AC_MSG_RESULT(no) +fi + + +dnl **************************************** +dnl *** strlcpy/strlcat *** +dnl **************************************** +# Check for strlcpy +AC_CACHE_CHECK([for OpenBSD strlcpy/strlcat],glib_cv_have_strlcpy,[ +AC_TRY_RUN([#include +#include +int main() { + char p[10]; + (void) strlcpy (p, "hi", 10); + if (strlcat (p, "bye", 0) != 3) + return 1; + return 0; +}], glib_cv_have_strlcpy=yes, + glib_cv_have_strlcpy=no, + glib_cv_have_strlcpy=no)]) +if test "$glib_cv_have_strlcpy" = "yes"; then + AC_DEFINE(HAVE_STRLCPY,1,[Have functions strlcpy and strlcat]) +fi + + +dnl ********************** +dnl *** va_copy checks *** +dnl ********************** +dnl we currently check for all three va_copy possibilities, so we get +dnl all results in config.log for bug reports. +AC_CACHE_CHECK([for an implementation of va_copy()],glib_cv_va_copy,[ + AC_LINK_IFELSE([AC_LANG_SOURCE([[#include +#include + void f (int i, ...) { + va_list args1, args2; + va_start (args1, i); + va_copy (args2, args1); + if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42) + exit (1); + va_end (args1); va_end (args2); + } + int main() { + f (0, 42); + return 0; + }]])], + [glib_cv_va_copy=yes], + [glib_cv_va_copy=no]) +]) +AC_CACHE_CHECK([for an implementation of __va_copy()],glib_cv___va_copy,[ + AC_LINK_IFELSE([AC_LANG_SOURCE([[#include +#include + void f (int i, ...) { + va_list args1, args2; + va_start (args1, i); + __va_copy (args2, args1); + if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42) + exit (1); + va_end (args1); va_end (args2); + } + int main() { + f (0, 42); + return 0; + }]])], + [glib_cv___va_copy=yes], + [glib_cv___va_copy=no]) +]) + +if test "x$glib_cv_va_copy" = "xyes"; then + g_va_copy_func=va_copy +else if test "x$glib_cv___va_copy" = "xyes"; then + g_va_copy_func=__va_copy +fi +fi + +if test -n "$g_va_copy_func"; then + AC_DEFINE_UNQUOTED(G_VA_COPY,$g_va_copy_func,[A 'va_copy' style function]) +fi + +AC_CACHE_CHECK([whether va_lists can be copied by value],glib_cv_va_val_copy,[ + AC_TRY_RUN([#include +#include + void f (int i, ...) { + va_list args1, args2; + va_start (args1, i); + args2 = args1; + if (va_arg (args2, int) != 42 || va_arg (args1, int) != 42) + exit (1); + va_end (args1); va_end (args2); + } + int main() { + f (0, 42); + return 0; + }], + [glib_cv_va_val_copy=yes], + [glib_cv_va_val_copy=no], + [glib_cv_va_val_copy=yes]) +]) + +if test "x$glib_cv_va_val_copy" = "xno"; then + AC_DEFINE(G_VA_COPY_AS_ARRAY,1, ['va_lists' cannot be copies as values]) +fi + +dnl *********************** +dnl *** g_module checks *** +dnl *********************** +G_MODULE_LIBS= +G_MODULE_LIBS_EXTRA= +G_MODULE_PLUGIN_LIBS= +if test x"$glib_native_win32" = xyes; then + dnl No use for this on Win32 + G_MODULE_LDFLAGS= +else + export SED + G_MODULE_LDFLAGS=`(./libtool --config; echo eval echo \\$export_dynamic_flag_spec) | sh` +fi +dnl G_MODULE_IMPL= don't reset, so cmd-line can override +G_MODULE_NEED_USCORE=0 +G_MODULE_BROKEN_RTLD_GLOBAL=0 +G_MODULE_HAVE_DLERROR=0 +dnl *** force native WIN32 shared lib loader +if test -z "$G_MODULE_IMPL"; then + case "$host" in + *-*-mingw*|*-*-cygwin*) G_MODULE_IMPL=G_MODULE_IMPL_WIN32 ;; + esac +fi +dnl *** force native AIX library loader +dnl *** dlopen() filepath must be of the form /path/libname.a(libname.so) +if test -z "$G_MODULE_IMPL"; then + case "$host" in + *-*-aix*) G_MODULE_IMPL=G_MODULE_IMPL_AR ;; + esac +fi +dnl *** dlopen() and dlsym() in system libraries +if test -z "$G_MODULE_IMPL"; then + AC_CHECK_FUNC(dlopen, + [AC_CHECK_FUNC(dlsym, + [G_MODULE_IMPL=G_MODULE_IMPL_DL],[])], + []) +fi +dnl *** load_image (BeOS) +if test -z "$G_MODULE_IMPL" && test "x$glib_native_beos" = "xyes"; then + AC_CHECK_LIB(root, load_image, + [G_MODULE_LIBS="-lbe -lroot -lglib-2.0 " + G_MODULE_LIBS_EXTRA="-L\$(top_builddir_full)/.libs" + G_MODULE_PLUGIN_LIBS="-L\$(top_builddir_full)/gmodule/.libs -lgmodule" + G_MODULE_IMPL=G_MODULE_IMPL_BEOS], + []) +fi +dnl *** NSLinkModule (dyld) in system libraries (Darwin) +if test -z "$G_MODULE_IMPL"; then + AC_CHECK_FUNC(NSLinkModule, + [G_MODULE_IMPL=G_MODULE_IMPL_DYLD + G_MODULE_NEED_USCORE=1], + []) +fi +dnl *** dlopen() and dlsym() in libdl +if test -z "$G_MODULE_IMPL"; then + AC_CHECK_LIB(dl, dlopen, + [AC_CHECK_LIB(dl, dlsym, + [G_MODULE_LIBS=-ldl + G_MODULE_IMPL=G_MODULE_IMPL_DL],[])], + []) +fi +dnl *** shl_load() in libdld (HP-UX) +if test -z "$G_MODULE_IMPL"; then + AC_CHECK_LIB(dld, shl_load, + [G_MODULE_LIBS=-ldld + G_MODULE_IMPL=G_MODULE_IMPL_DLD], + []) +fi +dnl *** additional checks for G_MODULE_IMPL_DL +if test "$G_MODULE_IMPL" = "G_MODULE_IMPL_DL"; then + LIBS_orig="$LIBS" + LDFLAGS_orig="$LDFLAGS" + LIBS="$G_MODULE_LIBS $LIBS" + LDFLAGS="$LDFLAGS $G_MODULE_LDFLAGS" +dnl *** check for OSF1/5.0 RTLD_GLOBAL brokenness + echo "void glib_plugin_test(void) { }" > plugin.c + ${SHELL} ./libtool --mode=compile --tag=CC ${CC} ${CFLAGS} \ + ${CPPFLAGS} -c -o plugin.lo plugin.c >/dev/null 2>&1 + ${SHELL} ./libtool --mode=link --tag=CC ${CC} ${CFLAGS} \ + ${LDFLAGS} -module -o plugin.la -export-dynamic \ + -shrext ".o" -avoid-version plugin.lo \ + -rpath /dont/care >/dev/null 2>&1 + eval `./libtool --config | grep ^objdir` + AC_CACHE_CHECK([for RTLD_GLOBAL brokenness], + glib_cv_rtldglobal_broken,[ + AC_TRY_RUN([ +#include +#ifndef RTLD_GLOBAL +# define RTLD_GLOBAL 0 +#endif +#ifndef RTLD_LAZY +# define RTLD_LAZY 0 +#endif +int glib_plugin_test; +int main () { + void *handle, *global, *local; + global = &glib_plugin_test; + handle = dlopen ("./$objdir/plugin.o", RTLD_GLOBAL | RTLD_LAZY); + if (!handle) return 0; + local = dlsym (handle, "glib_plugin_test"); + return global == local; +} ], + [glib_cv_rtldglobal_broken=no], + [glib_cv_rtldglobal_broken=yes], + [glib_cv_rtldglobal_broken=no]) + rm -f plugin.c plugin.o plugin.lo plugin.la ${objdir}/plugin.* + rmdir ${objdir} 2>/dev/null + ]) + if test "x$glib_cv_rtldglobal_broken" = "xyes"; then + G_MODULE_BROKEN_RTLD_GLOBAL=1 + else + G_MODULE_BROKEN_RTLD_GLOBAL=0 + fi +dnl *** check whether we need preceeding underscores + AC_CACHE_CHECK([for preceeding underscore in symbols], + glib_cv_uscore,[ + AC_TRY_RUN([#include + int glib_underscore_test (void) { return 42; } + int main() { + void *f1 = (void*)0, *f2 = (void*)0, *handle; + handle = dlopen ((void*)0, 0); + if (handle) { + f1 = dlsym (handle, "glib_underscore_test"); + f2 = dlsym (handle, "_glib_underscore_test"); + } return (!f2 || f1); + }], + [glib_cv_uscore=yes], + [glib_cv_uscore=no], + []) + rm -f plugin.c plugin.$ac_objext plugin.lo + ]) + GLIB_ASSERT_SET(glib_cv_uscore) + if test "x$glib_cv_uscore" = "xyes"; then + G_MODULE_NEED_USCORE=1 + else + G_MODULE_NEED_USCORE=0 + fi + + LDFLAGS="$LDFLAGS_orig" +dnl *** check for having dlerror() + AC_CHECK_FUNC(dlerror, + [G_MODULE_HAVE_DLERROR=1], + [G_MODULE_HAVE_DLERROR=0]) + LIBS="$LIBS_orig" +fi +dnl *** done, have we got an implementation? +if test -z "$G_MODULE_IMPL"; then + G_MODULE_IMPL=0 + G_MODULE_SUPPORTED=false +else + G_MODULE_SUPPORTED=true +fi + +AC_MSG_CHECKING(for the suffix of module shared libraries) +export SED +shrext_cmds=`./libtool --config | grep '^shrext_cmds='` +eval $shrext_cmds +module=yes eval std_shrext=$shrext_cmds +# chop the initial dot +glib_gmodule_suffix=`echo $std_shrext | sed 's/^\.//'` +AC_MSG_RESULT(.$glib_gmodule_suffix) +# any reason it may fail? +if test "x$glib_gmodule_suffix" = x; then + AC_MSG_ERROR(Cannot determine shared library suffix from libtool) +fi + +AC_SUBST(G_MODULE_SUPPORTED) +AC_SUBST(G_MODULE_IMPL) +AC_SUBST(G_MODULE_LIBS) +AC_SUBST(G_MODULE_LIBS_EXTRA) +AC_SUBST(G_MODULE_PLUGIN_LIBS) +AC_SUBST(G_MODULE_LDFLAGS) +AC_SUBST(G_MODULE_HAVE_DLERROR) +AC_SUBST(G_MODULE_BROKEN_RTLD_GLOBAL) +AC_SUBST(G_MODULE_NEED_USCORE) +AC_SUBST(GLIB_DEBUG_FLAGS) + +dnl ********************** +dnl *** g_spawn checks *** +dnl ********************** + +AC_MSG_CHECKING(for gspawn implementation) +case "$host" in + *-*-mingw*) + GSPAWN=gspawn-win32.lo + ;; + *) + GSPAWN=gspawn.lo + ;; +esac +AC_MSG_RESULT($GSPAWN) +AC_SUBST(GSPAWN) + +dnl ************************* +dnl *** GIOChannel checks *** +dnl ************************* + +AC_MSG_CHECKING(for GIOChannel implementation) +case "$host" in + *-*-mingw*) + GIO=giowin32.lo + ;; + *) + GIO=giounix.lo + ;; +esac +AC_MSG_RESULT($GIO) +AC_SUBST(GIO) + +dnl ********************************* +dnl *** Directory for GIO modules *** +dnl ********************************* + +AC_ARG_WITH(gio-module-dir, + [AC_HELP_STRING([--with-gio-module-dir=DIR], + [load gio modules from this directory [LIBDIR/gio/modules]])], + [], + [with_gio_module_dir='${libdir}/gio/modules']) +GIO_MODULE_DIR=$with_gio_module_dir +AC_SUBST(GIO_MODULE_DIR) + +dnl ********************************** +dnl *** Check for libselinux (GIO) *** +dnl ********************************** +AC_ARG_ENABLE(selinux, + AC_HELP_STRING([--disable-selinux], + [build without selinux support])) +msg_selinux=no +SELINUX_LIBS= +if test "x$enable_selinux" != "xno"; then + + AC_CHECK_LIB(selinux, is_selinux_enabled, + [AC_CHECK_HEADERS(selinux/selinux.h, + [AC_CHECK_LIB(selinux, lgetfilecon_raw, + [AC_DEFINE(HAVE_SELINUX, 1, [Define to 1 if libselinux is available]) + SELINUX_LIBS="-lselinux" + msg_selinux=yes]) + ]) + ]) +fi +AC_SUBST(SELINUX_LIBS) + +dnl ***************************** +dnl ** Check for inotify (GIO) ** +dnl ***************************** +inotify_support=no +AC_CHECK_HEADERS([sys/inotify.h], +[ + inotify_support=yes + AC_CHECK_FUNCS(inotify_init1) +]) + +AM_CONDITIONAL(HAVE_INOTIFY, [test "$inotify_support" = "yes"]) + +dnl ********************************* +dnl ** Check for Solaris FEN (GIO) ** +dnl ********************************* +fen_support=no +AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ +#include +#ifndef PORT_SOURCE_FILE +#error "Please upgrade to Nevada 72 or above to suppoert FEN" +#endif +int main() { return 0; } ]])], +[ + fen_support=yes +],) + +AM_CONDITIONAL(HAVE_FEN, [test "$fen_support" = "yes"]) + +dnl **************************** +dnl *** Checks for FAM (GIO) *** +dnl **************************** + +should_disable_fam=no + +AC_ARG_ENABLE(fam, + AC_HELP_STRING([--disable-fam], + [don't use fam for file system monitoring]), + [ + if test "x$enable_fam" = "xno"; then + should_disable_fam=yes + fi + ] + ) +fam_support=no +FAM_LIBS= +if test "x$should_disable_fam" = "xno"; then +AC_CHECK_LIB(fam, FAMOpen, + [AC_CHECK_HEADERS(fam.h, + [AC_DEFINE(HAVE_FAM, [], [Define if we have FAM]) + AC_CHECK_LIB(fam, FAMNoExists, + AC_DEFINE(HAVE_FAM_NO_EXISTS, [], [Define if we have FAMNoExists in fam])) + FAM_LIBS="-lfam"] + fam_support=yes, + AC_MSG_WARN(*** FAM support will not be built (header files not found) ***))], + AC_MSG_WARN(*** FAM support will not be built (FAM library not found) ***)) +AC_SUBST(FAM_LIBS) +fi +AM_CONDITIONAL(HAVE_FAM, [test "$fam_support" = "yes"]) + + +dnl ***************************** +dnl *** Check for xattr (GIO) *** +dnl ***************************** +AC_ARG_ENABLE(xattr, + AC_HELP_STRING([--disable-xattr], [build without xattr support])) +msg_xattr=no +XATTR_LIBS= +if test "x$enable_xattr" != "xno"; then + +dnl either glibc or libattr can provide xattr support + +dnl for both of them, we check for getxattr being in +dnl the library and a valid xattr header. + +dnl try glibc + AC_CHECK_LIB(c, getxattr, + [AC_CHECK_HEADERS(sys/xattr.h, + [AC_DEFINE(HAVE_XATTR, 1, [Define to 1 if xattr is available]) + msg_xattr=yes]) + ]) + + if test "x$msg_xattr" != "xyes"; then +dnl failure. try libattr + AC_CHECK_LIB(attr, getxattr, + [AC_CHECK_HEADERS(attr/xattr.h, + [AC_DEFINE(HAVE_XATTR, 1, [Define to 1 if xattr is available]) + XATTR_LIBS="-lattr" + msg_xattr=yes]) + ]) + fi + + if test "x$msg_xattr" = "xyes"; then + AC_MSG_CHECKING([for XATTR_NOFOLLOW]) + AC_TRY_COMPILE([ + #include + #ifdef HAVE_SYS_TYPES_H + #include + #endif + #ifdef HAVE_SYS_XATTR_H + #include + #elif HAVE_ATTR_XATTR_H + #include + #endif + ], + [ssize_t len = getxattr("", "", NULL, 0, 0, XATTR_NOFOLLOW);], + [ + AC_DEFINE([HAVE_XATTR_NOFOLLOW], [1], [Define to 1 if xattr API uses XATTR_NOFOLLOW]) + AC_MSG_RESULT([yes]) + ], + [AC_MSG_RESULT([no])] + ) + fi + +fi +AC_SUBST(XATTR_LIBS) + +dnl ************************ +dnl *** check for libelf *** +dnl ************************ + +AC_CHECK_LIB([elf], [elf_begin], have_libelf=yes, have_libelf=no) +if test $have_libelf = yes; then + AC_DEFINE(HAVE_LIBELF, 1, [Define if libelf is available]) + ELF_LIBS=-lelf +fi +AC_SUBST(ELF_LIBS) + +dnl **************************************** +dnl *** platform dependent source checks *** +dnl **************************************** + +AC_MSG_CHECKING(for platform-dependent source) +case "$host" in + *-*-cygwin*|*-*-mingw*) + PLATFORMDEP=gwin32.lo + ;; + *) + PLATFORMDEP= + ;; +esac +AC_MSG_RESULT($PLATFORMDEP) +AC_SUBST(PLATFORMDEP) + +AC_MSG_CHECKING([whether to compile timeloop]) +case "$host" in + *-*-cygwin*|*-*-mingw*|*-*-minix) + enable_timeloop=no + ;; + *) + enable_timeloop=yes + ;; +esac +AC_MSG_RESULT($enable_timeloop) +AM_CONDITIONAL(ENABLE_TIMELOOP, test x$enable_timeloop = xyes) + +AC_MSG_CHECKING([if building for some Win32 platform]) +case "$host" in + *-*-mingw*|*-*-cygwin*) + platform_win32=yes + ;; + *) + platform_win32=no + ;; +esac +AC_MSG_RESULT($platform_win32) +AM_CONDITIONAL(PLATFORM_WIN32, test x$platform_win32 = xyes) + +dnl *********************** +dnl *** g_thread checks *** +dnl *********************** + +AC_ARG_WITH(threads, + [AC_HELP_STRING([--with-threads=@<:@posix/win32@:>@], + [specify a thread implementation to use])], + [], + [with_threads=yes]) + +dnl error and warning message +dnl ************************* + +THREAD_NO_IMPLEMENTATION="No thread implementation found." + +FLAG_DOES_NOT_WORK="I can't find the MACRO to enable thread safety on your + platform (normally it's "_REENTRANT"). I'll not use any flag on + compilation now, but then your programs might not work. + Please provide information on how it is done on your system." + +LIBS_NOT_FOUND_1="I can't find the libraries for the thread implementation + " + +LIBS_NOT_FOUND_2=". Please choose another thread implementation or + provide information on your thread implementation." + +FUNC_NO_GETPWUID_R="the 'g_get_(user_name|real_name|home_dir|tmp_dir)' + functions will not be MT-safe during their first call because + there is no working 'getpwuid_r' on your system." + +FUNC_NO_LOCALTIME_R="the 'g_date_set_time' function will not be MT-safe + because there is no 'localtime_r' on your system." + +AIX_COMPILE_INFO="AIX's C compiler needs to be called by a different name, when + linking threaded applications. As GLib cannot do that + automatically, you will get an linkg error everytime you are + not using the right compiler. In that case you have to relink + with the right compiler. Ususally just '_r' is appended + to the compiler name." + +dnl determination of thread implementation +dnl *************************************** + +AC_MSG_CHECKING(for thread implementation) + +have_threads=no +if test "x$with_threads" = xyes || test "x$with_threads" = xposix; then + # -D_POSIX4_DRAFT_SOURCE -D_POSIX4A_DRAFT10_SOURCE is for DG/UX + # -U_OSF_SOURCE is for Digital UNIX 4.0d + GTHREAD_COMPILE_IMPL_DEFINES="-D_POSIX4_DRAFT_SOURCE -D_POSIX4A_DRAFT10_SOURCE -U_OSF_SOURCE" + glib_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GTHREAD_COMPILE_IMPL_DEFINES" + if test "x$have_threads" = xno; then + AC_TRY_COMPILE([#include ], + [pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;], + have_threads=posix) + fi + # Tru64Unix requires -pthread to find pthread.h. See #103020 + CPPFLAGS="$CPPFLAGS -pthread" + if test "x$have_threads" = xno; then + AC_TRY_COMPILE([#include ], + [pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;], + have_threads=posix) + fi + CPPFLAGS="$glib_save_CPPFLAGS" +fi +if test "x$with_threads" = xyes || test "x$with_threads" = xwin32; then + case $host in + *-*-mingw*) + have_threads=win32 + ;; + esac +fi + +if test "x$have_threads" = xno; then + AC_MSG_RESULT(none available) + AC_MSG_ERROR($THREAD_NO_IMPLEMENTATION) +else + AC_MSG_RESULT($have_threads) +fi + + +dnl determination of G_THREAD_CFLAGS +dnl ******************************** + +G_THREAD_LIBS= +G_THREAD_LIBS_EXTRA= +G_THREAD_CFLAGS= + +dnl +dnl Test program for basic POSIX threads functionality +dnl +m4_define([glib_thread_test],[ +#include +int check_me = 0; +void* func(void* data) {check_me = 42; return &check_me;} +int main() + { pthread_t t; + void *ret; + pthread_create (&t, $1, func, 0); + pthread_join (t, &ret); + return (check_me != 42 || ret != &check_me); +}]) + +if test x"$have_threads" = xposix; then + # First we test for posix, whether -pthread or -pthreads do the trick as + # both CPPFLAG and LIBS. + # One of them does for most gcc versions and some other platforms/compilers + # too and could be considered as the canonical way to go. + case $host in + *-*-cygwin*|*-*-darwin*) + # skip cygwin and darwin -pthread or -pthreads test + ;; + *-solaris*) + # These compiler/linker flags work with both Sun Studio and gcc + # Sun Studio expands -mt to -D_REENTRANT and -lthread + # gcc expands -pthreads to -D_REENTRANT -D_PTHREADS -lpthread + G_THREAD_CFLAGS="-D_REENTRANT -D_PTHREADS" + G_THREAD_LIBS="-lpthread -lthread" + ;; + *) + for flag in pthread pthreads mt; do + glib_save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -$flag" + AC_TRY_RUN(glib_thread_test(0), + glib_flag_works=yes, + glib_flag_works=no, + [AC_LINK_IFELSE([AC_LANG_SOURCE(glib_thread_test(0))], + glib_flag_works=yes, + glib_flag_works=no)]) + CFLAGS="$glib_save_CFLAGS" + if test $glib_flag_works = yes ; then + G_THREAD_CFLAGS=-$flag + G_THREAD_LIBS=-$flag + break; + fi + done + ;; + esac +fi + +if test x"$G_THREAD_CFLAGS" = x; then + + # The canonical -pthread[s] does not work. Try something different. + + case $host in + *-aix*) + if test x"$GCC" = xyes; then + # GCC 3.0 and above needs -pthread. + # Should be coverd by the case above. + # GCC 2.x and below needs -mthreads + G_THREAD_CFLAGS="-mthreads" + G_THREAD_LIBS=$G_THREAD_CFLAGS + else + # We are probably using the aix compiler. Normaly a + # program would have to be compiled with the _r variant + # of the corresponding compiler, but we as GLib cannot + # do that: but the good news is that for compiling the + # only difference is the added -D_THREAD_SAFE compile + # option. This is according to the "C for AIX User's + # Guide". + G_THREAD_CFLAGS="-D_THREAD_SAFE" + fi + ;; + *-dg-dgux*) # DG/UX + G_THREAD_CFLAGS="-D_REENTRANT -D_POSIX4A_DRAFT10_SOURCE" + ;; + *-sysv5uw7*) # UnixWare 7 + # We are not using gcc with -pthread. Catched above. + G_THREAD_CFLAGS="-Kthread" + G_THREAD_LIBS=$G_THREAD_CFLAGS + ;; + *-mingw*) + # No flag needed when using MSVCRT.DLL + G_THREAD_CFLAGS="" + ;; + *) + G_THREAD_CFLAGS="-D_REENTRANT" # good default guess otherwise + ;; + esac + +fi + +# if we are not finding the localtime_r function, then we probably are +# not using the proper multithread flag + +glib_save_CPPFLAGS="$CPPFLAGS" +CPPFLAGS="$CPPFLAGS $G_THREAD_CFLAGS" + +# First we test, whether localtime_r is declared in time.h +# directly. Then we test whether a macro localtime_r exists, in +# which case localtime_r in the test program is replaced and thus +# if we still find localtime_r in the output, it is not defined as +# a macro. + +AC_EGREP_CPP([[^a-zA-Z1-9_]localtime_r[^a-zA-Z1-9_]], [#include ], , + [AC_EGREP_CPP([[^a-zA-Z1-9_]localtime_r[^a-zA-Z1-9_]], [#include + localtime_r(a,b)], + AC_MSG_WARN($FLAG_DOES_NOT_WORK))]) + +CPPFLAGS="$glib_save_CPPFLAGS" + +AC_MSG_CHECKING(thread related cflags) +AC_MSG_RESULT($G_THREAD_CFLAGS) +CPPFLAGS="$CPPFLAGS $G_THREAD_CFLAGS" + +dnl determination of G_THREAD_LIBS +dnl ****************************** + +case $have_threads in + posix) + glib_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GTHREAD_COMPILE_IMPL_DEFINES" + if test x"$G_THREAD_LIBS" = x; then + case $host in + *-aix*) + # We are not using gcc (would have set G_THREAD_LIBS) and thus + # probably using the aix compiler. + AC_MSG_WARN($AIX_COMPILE_INFO) + ;; + *) + G_THREAD_LIBS=error + glib_save_LIBS="$LIBS" + for thread_lib in "" pthread pthread32 pthreads thread; do + if test x"$thread_lib" = x; then + add_thread_lib="" + IN="" + else + add_thread_lib="-l$thread_lib" + IN=" in -l$thread_lib" + fi + if test x"$have_threads" = xposix; then + defattr=0 + else + defattr=pthread_attr_default + fi + + LIBS="$add_thread_lib $glib_save_LIBS" + + AC_MSG_CHECKING(for pthread_create/pthread_join$IN) + AC_TRY_RUN(glib_thread_test($defattr), + glib_result=yes, + glib_result=no, + [AC_LINK_IFELSE([AC_LANG_SOURCE(glib_thread_test($defattr))], + glib_result=yes, + glib_result=no)]) + AC_MSG_RESULT($glib_result) + + if test "$glib_result" = "yes" ; then + G_THREAD_LIBS="$add_thread_lib" + break + fi + done + if test "x$G_THREAD_LIBS" = xerror; then + AC_MSG_ERROR($LIBS_NOT_FOUND_1$have_threads$LIBS_NOT_FOUND_2) + fi + LIBS="$glib_save_LIBS" + ;; + esac + fi + + g_threads_impl="POSIX" + AC_SUBST(GTHREAD_COMPILE_IMPL_DEFINES) + CPPFLAGS="$glib_save_CPPFLAGS" + ;; + win32) + g_threads_impl="WIN32" + ;; + *) + g_threads_impl="NONE" + G_THREAD_LIBS=error + ;; +esac + +if test "x$G_THREAD_LIBS" = xerror; then + AC_MSG_ERROR($LIBS_NOT_FOUND_1$have_threads$LIBS_NOT_FOUND_2) +fi + +case $host in + *-*-beos*) + G_THREAD_LIBS="-lbe -lroot -lglib-2.0 " + G_THREAD_LIBS_EXTRA="-L\$(top_builddir_full)/.libs" + ;; + *) + ;; +esac + +AC_MSG_CHECKING(thread related libraries) +AC_MSG_RESULT($G_THREAD_LIBS) + +dnl check for mt safe function variants and some posix functions +dnl ************************************************************ + +glib_save_LIBS="$LIBS" +# we are not doing the following for now, as this might require glib +# to always be linked with the thread libs on some platforms. +# LIBS="$LIBS $G_THREAD_LIBS" +AC_CHECK_FUNCS(localtime_r gmtime_r) +if test "$ac_cv_header_pwd_h" = "yes"; then + AC_CACHE_CHECK([for posix getpwuid_r], + ac_cv_func_posix_getpwuid_r, + [AC_TRY_RUN([ +#include +#include +int main () { + char buffer[10000]; + struct passwd pwd, *pwptr = &pwd; + int error; + errno = 0; + error = getpwuid_r (0, &pwd, buffer, + sizeof (buffer), &pwptr); + return (error < 0 && errno == ENOSYS) + || error == ENOSYS; +} ], + [ac_cv_func_posix_getpwuid_r=yes], + [ac_cv_func_posix_getpwuid_r=no])]) + GLIB_ASSERT_SET(ac_cv_func_posix_getpwuid_r) + if test "$ac_cv_func_posix_getpwuid_r" = yes; then + AC_DEFINE(HAVE_POSIX_GETPWUID_R,1, + [Have POSIX function getpwuid_r]) + else + AC_CACHE_CHECK([for nonposix getpwuid_r], + ac_cv_func_nonposix_getpwuid_r, + [AC_TRY_LINK([#include ], + [char buffer[10000]; + struct passwd pwd; + getpwuid_r (0, &pwd, buffer, + sizeof (buffer));], + [ac_cv_func_nonposix_getpwuid_r=yes], + [ac_cv_func_nonposix_getpwuid_r=no])]) + GLIB_ASSERT_SET(ac_cv_func_nonposix_getpwuid_r) + if test "$ac_cv_func_nonposix_getpwuid_r" = yes; then + AC_DEFINE(HAVE_NONPOSIX_GETPWUID_R,1, + [Have non-POSIX function getpwuid_r]) + fi + fi +fi +if test "$ac_cv_header_grp_h" = "yes"; then + AC_CACHE_CHECK([for posix getgrgid_r], + ac_cv_func_posix_getgrgid_r, + [AC_TRY_RUN([ +#include +#include +int main () { + char buffer[10000]; + struct group grp, *grpptr = &grp; + int error; + errno = 0; + error = getgrgid_r (0, &grp, buffer, + sizeof (buffer), &grpptr); + return (error < 0 && errno == ENOSYS) + || error == ENOSYS; +} ], + [ac_cv_func_posix_getgrgid_r=yes], + [ac_cv_func_posix_getgrgid_r=no])]) + GLIB_ASSERT_SET(ac_cv_func_posix_getgrgid_r) + if test "$ac_cv_func_posix_getgrgid_r" = yes; then + AC_DEFINE(HAVE_POSIX_GETGRGID_R,1, + [Have POSIX function getgrgid_r]) + else + AC_CACHE_CHECK([for nonposix getgrgid_r], + ac_cv_func_nonposix_getgrgid_r, + [AC_TRY_LINK([#include ], + [char buffer[10000]; + struct group grp; + getgrgid_r (0, &grp, buffer, + sizeof (buffer));], + [ac_cv_func_nonposix_getgrgid_r=yes], + [ac_cv_func_nonposix_getgrgid_r=no])]) + GLIB_ASSERT_SET(ac_cv_func_nonposix_getgrgid_r) + if test "$ac_cv_func_nonposix_getgrgid_r" = yes; then + AC_DEFINE(HAVE_NONPOSIX_GETGRGID_R,1, + [Have non-POSIX function getgrgid_r]) + fi + fi +fi +LIBS="$G_THREAD_LIBS $LIBS" +if test x"$have_threads" = xposix; then + glib_save_CPPFLAGS="$CPPFLAGS" + CPPFLAGS="$CPPFLAGS $GTHREAD_COMPILE_IMPL_DEFINES" + # This is not AC_CHECK_FUNC to also work with function + # name mangling in header files. + AC_MSG_CHECKING(for pthread_attr_setstacksize) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include ], + [pthread_attr_t t; pthread_attr_setstacksize(&t,0)])], + [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PTHREAD_ATTR_SETSTACKSIZE,1, + [Have function pthread_attr_setstacksize])], + [AC_MSG_RESULT(no)]) + AC_MSG_CHECKING(for pthread_condattr_setclock) + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [#include ], + [pthread_condattr_t a; pthread_condattr_setclock(&a,0)])], + [AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PTHREAD_CONDATTR_SETCLOCK,1, + [Have function pthread_condattr_setclock])], + [AC_MSG_RESULT(no)]) + CPPFLAGS="$glib_save_CPPFLAGS" +fi + +LIBS="$glib_save_LIBS" + +# now spit out all the warnings. +if test "$ac_cv_func_posix_getpwuid_r" != "yes" && + test "$ac_cv_func_nonposix_getpwuid_r" != "yes"; then + AC_MSG_WARN($FUNC_NO_GETPWUID_R) +fi +if test "$ac_cv_func_localtime_r" != "yes"; then + AC_MSG_WARN($FUNC_NO_LOCALTIME_R) +fi + +# +# Hack to deal with: +# +# a) GCC < 3.3 for Linux doesn't include -lpthread when +# building shared libraries with linux. +# b) FreeBSD doesn't do this either. +# +case $host in + *-*-freebsd*|*-*-linux*) + G_THREAD_LIBS_FOR_GTHREAD="`echo $G_THREAD_LIBS | sed s/-pthread/-lpthread/`" + ;; + *-*-openbsd*) + LDFLAGS="$LDFLAGS -pthread" + ;; + *) + G_THREAD_LIBS_FOR_GTHREAD="$G_THREAD_LIBS" + ;; +esac + +AC_SUBST(G_THREAD_CFLAGS) +AC_SUBST(G_THREAD_LIBS) +AC_SUBST(G_THREAD_LIBS_FOR_GTHREAD) +AC_SUBST(G_THREAD_LIBS_EXTRA) + +AC_CHECK_FUNCS(clock_gettime, [], [ + AC_CHECK_LIB(rt, clock_gettime, [ + AC_DEFINE(HAVE_CLOCK_GETTIME, 1) + G_THREAD_LIBS="$G_THREAD_LIBS -lrt" + G_THREAD_LIBS_FOR_GTHREAD="$G_THREAD_LIBS_FOR_GTHREAD -lrt" + ]) +]) + + +dnl ************************ +dnl *** g_atomic_* tests *** +dnl ************************ + +dnl We need to decide at configure time if GLib will use real atomic +dnl operations ("lock free") or emulated ones with a mutex. This is +dnl because we must put this information in glibconfig.h so we know if +dnl it is safe or not to inline using compiler intrinsics directly from +dnl the header. +dnl +dnl We also publish the information via G_ATOMIC_LOCK_FREE in case the +dnl user is interested in knowing if they can use the atomic ops across +dnl processes. +dnl +dnl We can currently support the atomic ops natively when building GLib +dnl with recent versions of GCC or MSVC. MSVC doesn't run ./configure, +dnl so we skip that case here and define G_ATOMIC_LOCK_FREE exactly when +dnl we are using GCC. +dnl +dnl Note that the atomic ops are only available with GCC on x86 when +dnl using -march=i486 or higher. If we detect that the atomic ops are +dnl not available but would be available given the right flags, we want +dnl to abort and advise the user to fix their CFLAGS. It's better to do +dnl that then to silently fall back on emulated atomic ops just because +dnl the user had the wrong build environment. + +dnl We may add other compilers here in the future... + +AC_CACHE_CHECK([for lock-free atomic intrinsics], glib_cv_g_atomic_lock_free, [ + AC_TRY_COMPILE([], + [__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;], + [glib_cv_g_atomic_lock_free=yes], + [glib_cv_g_atomic_lock_free=no])]) + +if test "$glib_cv_g_atomic_lock_free" = "no"; then + SAVE_CFLAGS="${CFLAGS}" + CFLAGS="-march=i486" + AC_TRY_COMPILE([], + [__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;], + [AC_MSG_ERROR([GLib must be build with -march=i486 or later.])], + []) + CFLAGS="${SAVE_CFLAGS}" +fi + +dnl We need a more robust approach here... +case $host_cpu in + i?86|x86_64|s390|s390x|arm*|crisv32*|etrax*) + glib_memory_barrier_needed=no + ;; + sparc*|alpha*|powerpc*|ia64) + glib_memory_barrier_needed=yes + ;; + *) + glib_memory_barrier_needed=yes + ;; +esac + +dnl ************************ +dnl ** Check for futex(2) ** +dnl ************************ +AC_CACHE_CHECK(for futex(2) system call, + glib_cv_futex,AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ +#include +#include +#include +],[ +int +main (void) +{ + /* it is not like this actually runs or anything... */ + syscall (__NR_futex, NULL, FUTEX_WAKE, FUTEX_WAIT); + return 0; +} +])],glib_cv_futex=yes,glib_cv_futex=no)) +if test x"$glib_cv_futex" = xyes; then + AC_DEFINE(HAVE_FUTEX, 1, [we have the futex(2) system call]) +fi + +AC_CACHE_CHECK(for eventfd(2) system call, + glib_cv_eventfd,AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ +#include +#include +],[ +int +main (void) +{ + eventfd (0, EFD_CLOEXEC); + return 0; +} +])],glib_cv_eventfd=yes,glib_cv_eventfd=no)) +if test x"$glib_cv_eventfd" = x"yes"; then + AC_DEFINE(HAVE_EVENTFD, 1, [we have the eventfd(2) system call]) +fi +AM_CONDITIONAL(HAVE_EVENTFD, [test "$glib_cv_eventfd" = "yes"]) + +dnl **************************************** +dnl *** GLib POLL* compatibility defines *** +dnl **************************************** + +glib_poll_includes=[" +#include +#include +"] + +if test $ac_cv_header_sys_types_h = yes && + test $ac_cv_header_sys_poll_h = yes ; then + glib_failed=false + GLIB_CHECK_VALUE(POLLIN, $glib_poll_includes, glib_failed=true) + GLIB_CHECK_VALUE(POLLOUT, $glib_poll_includes, glib_failed=true) + GLIB_CHECK_VALUE(POLLPRI, $glib_poll_includes, glib_failed=true) + GLIB_CHECK_VALUE(POLLERR, $glib_poll_includes, glib_failed=true) + GLIB_CHECK_VALUE(POLLHUP, $glib_poll_includes, glib_failed=true) + GLIB_CHECK_VALUE(POLLNVAL, $glib_poll_includes, glib_failed=true) + if $glib_failed ; then + AC_MSG_ERROR([Could not determine values for POLL* constants]) + fi +else + glib_cv_value_POLLIN=1 + glib_cv_value_POLLOUT=4 + glib_cv_value_POLLPRI=2 + glib_cv_value_POLLERR=8 + glib_cv_value_POLLHUP=16 + glib_cv_value_POLLNVAL=32 +fi + +AC_MSG_CHECKING([for broken poll]) +AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include + #include + #include + #ifdef HAVE_SYS_POLL_H + #include + #endif + int main(void) { + struct pollfd fds[1]; + int fd; + fd = open("/dev/null", 1); + fds[0].fd = fd; + fds[0].events = POLLIN; + fds[0].revents = 0; + if (poll(fds, 1, 0) < 0 || (fds[0].revents & POLLNVAL) != 0) { + exit(1); /* Does not work for devices -- fail */ + } + exit(0); + }]])], + [broken_poll=no], + [broken_poll=yes + AC_DEFINE(BROKEN_POLL,1,[poll doesn't work on devices])], + [broken_poll="no (cross compiling)"]) +AC_MSG_RESULT($broken_poll) + +dnl ********************* +dnl *** GRegex checks *** +dnl ********************* + +PCRE_REQUIRED_VERSION=8.11 + +# Check if we should use the internal or the system-supplied pcre +AC_ARG_WITH(pcre, + [AC_HELP_STRING([--with-pcre=@<:@internal/system@:>@], + [whether to use system PCRE [default=internal]])]) + +AM_CONDITIONAL(USE_SYSTEM_PCRE, [test "x$with_pcre" = xsystem]) + +if test "x$with_pcre" = xsystem; then + PKG_CHECK_MODULES(PCRE, + libpcre >= $PCRE_REQUIRED_VERSION) + AC_CACHE_CHECK([for Unicode support in PCRE],glib_cv_pcre_has_unicode,[ + glib_save_CFLAGS="$CFLAGS" + glib_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $PCRE_CFLAGS" LIBS="$PCRE_LIBS" + AC_TRY_RUN([#include + int main () { + int support; + pcre_config (PCRE_CONFIG_UTF8, &support); + if (!support) + return 1; + pcre_config (PCRE_CONFIG_UNICODE_PROPERTIES, &support); + if (!support) + return 1; + return 0; + }], + glib_cv_pcre_has_unicode=yes, + glib_cv_pcre_has_unicode=no, + glib_cv_pcre_has_unicode=yes) + CFLAGS="$glib_save_CFLAGS" + LIBS="$glib_save_LIBS" + ]) + if test "$glib_cv_pcre_has_unicode" = "no"; then + AC_MSG_ERROR([*** The system-supplied PCRE does not support Unicode properties or UTF-8.]) + fi + AC_SUBST(PCRE_CFLAGS) + AC_SUBST(PCRE_LIBS) + AC_DEFINE(USE_SYSTEM_PCRE, [], [using the system-supplied PCRE library]) + PCRE_REQUIRES=libpcre + AC_SUBST(PCRE_REQUIRES) +else + # If using gcc 4 pass -Wno-pointer-sign when compiling the internal PCRE + if test x"$GCC" = xyes; then + AC_MSG_CHECKING([whether compiler understands -Wno-pointer-sign]) + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wno-pointer-sign" + AC_TRY_COMPILE([],[],[PCRE_WARN_CFLAGS="$PCRE_WARN_CFLAGS -Wno-pointer-sign" + AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)]) + CFLAGS="$save_CFLAGS" + fi +fi +AC_SUBST(PCRE_WARN_CFLAGS) + +dnl ********************** +dnl *** Win32 API libs *** +dnl ********************** + +case $host in + *-*-cygwin*) + G_LIBS_EXTRA="-luser32 -lkernel32" + ;; + *-*-mingw*) + G_LIBS_EXTRA="-lws2_32 -lole32 -lwinmm -lshlwapi" + ;; + *) + G_LIBS_EXTRA="" + ;; +esac +AC_SUBST(G_LIBS_EXTRA) + +dnl If the system doesn't define EILSEQ, we should define EILSEQ ourselves +dnl since we need it for g_iconv() + +AC_MSG_CHECKING([for EILSEQ]) +AC_TRY_COMPILE([ +#include +], +[ +int error = EILSEQ; +], have_eilseq=yes, have_eilseq=no); +AC_MSG_RESULT($have_eilseq) + +dnl ****************************************************************** +dnl *** If we are cross-compiling, look for glib-genmarshal and *** +dnl *** glib-compile-schemas in PATH *** +dnl ****************************************************************** + +AM_CONDITIONAL(CROSS_COMPILING, test $cross_compiling = yes) + +if test $cross_compiling = yes; then + AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal, no) + if test x$GLIB_GENMARSHAL = xno; then + AC_MSG_ERROR(Could not find a glib-genmarshal in your PATH) + fi + + AC_PATH_PROG(GLIB_COMPILE_SCHEMAS, glib-compile-schemas, no) + if test x$GLIB_COMPILE_SCHEMAS = xno; then + AC_MSG_ERROR(Could not find a glib-compile-schemas in your PATH) + fi + + AC_PATH_PROG(GLIB_COMPILE_RESOURCES, glib-compile-resources, no) + if test x$GLIB_COMPILE_RESOURCES = xno; then + AC_MSG_ERROR(Could not find a glib-compile-resources in your PATH) + fi +fi + +dnl ************************** +dnl *** Checks for gtk-doc *** +dnl ************************** + +GTK_DOC_CHECK([1.15], [--flavour no-tmpl]) + +AC_ARG_ENABLE(man, + [AC_HELP_STRING([--enable-man], + [regenerate man pages from Docbook [default=no]])],enable_man=yes, + enable_man=no) + +if test "${enable_man}" != no; then +dnl +dnl Check for xsltproc +dnl +AC_PATH_PROG([XSLTPROC], [xsltproc]) + if test -z "$XSLTPROC"; then + enable_man=no + fi + + dnl check for DocBook DTD and stylesheets in the local catalog. + JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.1.2//EN], + [DocBook XML DTD V4.1.2],,enable_man=no) + JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl], + [DocBook XSL Stylesheets],,enable_man=no) +fi + +AM_CONDITIONAL(ENABLE_MAN, test x$enable_man != xno) + +dnl +dnl Tracing +dnl + +AC_ARG_ENABLE([dtrace], + [AS_HELP_STRING([--enable-dtrace], + [include tracing support for dtrace])]) +have_dtrace=no +AC_MSG_CHECKING([whether to include dtrace tracing support]) +if test "x$enable_dtrace" != xno; then + if test x$glib_have_carbon = xyes; then + AC_MSG_RESULT([no (not yet compatible with MacOS dtrace)]) + else + AC_MSG_RESULT([yes]) + AC_CHECK_PROGS(DTRACE, dtrace) + if test -z "$DTRACE"; then + if test "x$enable_dtrace" = xyes; then + AC_MSG_ERROR([dtrace not found]) + fi + else + AC_CHECK_HEADER([sys/sdt.h],have_dtrace=yes, + [if test "x$enable_dtrace" = xyes; then + AC_MSG_ERROR([dtrace support needs sys/sdt.h header]) + fi]) + fi + fi +else + AC_MSG_RESULT([no]) +fi +if test "x$have_dtrace" = xyes; then + AC_DEFINE([HAVE_DTRACE], [1], [Define to 1 if using dtrace probes.]) +fi +AM_CONDITIONAL([ENABLE_DTRACE], [test x$have_dtrace = xyes ]) + +AC_MSG_CHECKING([whether to include systemtap tracing support]) +AC_ARG_ENABLE([systemtap], + [AS_HELP_STRING([--enable-systemtap], + [include tracing support for systemtap])]) +have_systemtap=no +if test "x$enable_systemtap" != xno -a "x$have_dtrace" = xyes; then + have_systemtap=yes +fi +AC_MSG_RESULT(${have_systemtap}) + +AM_CONDITIONAL([ENABLE_SYSTEMTAP], [test x$have_systemtap = xyes]) + +AC_ARG_WITH([tapset-install-dir], + AS_HELP_STRING([--with-tapset-install-dir=DIR], + [path where systemtap tapsets are installed [DATADIR/systemtap/tapset]]), + [if test "x${withval}" = x; then + ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset" + else + ABS_TAPSET_DIR="${withval}" + fi], + [ABS_TAPSET_DIR="\$(datadir)/systemtap/tapset"]) +AC_SUBST(ABS_TAPSET_DIR) + +dnl ************************************ +dnl *** Enable lcov coverage reports *** +dnl ************************************ + +AC_ARG_ENABLE(gcov, + AS_HELP_STRING([--enable-gcov], + [enable coverage testing with gcov]), + [use_gcov=$enableval], [use_gcov=no]) + +if test "x$use_gcov" = "xyes"; then + dnl we need gcc: + if test "$GCC" != "yes"; then + AC_MSG_ERROR([GCC is required for --enable-gcov]) + fi + + dnl Check if ccache is being used + AC_CHECK_PROG(SHTOOL, shtool, shtool) + case `$SHTOOL path $CC` in + *ccache*[)] gcc_ccache=yes;; + *[)] gcc_ccache=no;; + esac + + if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then + AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) + fi + + ltp_version_list="1.6 1.7 1.8 1.9" + AC_CHECK_PROG(LTP, lcov, lcov) + AC_CHECK_PROG(LTP_GENHTML, genhtml, genhtml) + + if test "$LTP"; then + AC_CACHE_CHECK([for ltp version], glib_cv_ltp_version, [ + glib_cv_ltp_version=invalid + ltp_version=`$LTP -v 2>/dev/null | $SED -e 's/^.* //'` + for ltp_check_version in $ltp_version_list; do + if test "$ltp_version" = "$ltp_check_version"; then + glib_cv_ltp_version="$ltp_check_version (ok)" + fi + done + ]) + else + ltp_msg="To enable code coverage reporting you must have one of the following LTP versions installed: $ltp_version_list" + AC_MSG_ERROR([$ltp_msg]) + fi + + case $glib_cv_ltp_version in + ""|invalid[)] + ltp_msg="You must have one of the following versions of LTP: $ltp_version_list (found: $ltp_version)." + AC_MSG_ERROR([$ltp_msg]) + LTP="exit 0;" + ;; + esac + + if test -z "$LTP_GENHTML"; then + AC_MSG_ERROR([Could not find genhtml from the LTP package]) + fi + + dnl Remove all optimization flags from CFLAGS + changequote({,}) + CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` + changequote([,]) + + dnl Add the special gcc flags + CFLAGS="$CFLAGS -O0 -fprofile-arcs -ftest-coverage" + LDFLAGS="$LDFLAGS -lgcov" +fi + +dnl ****************************** +dnl *** output the whole stuff *** +dnl ****************************** + +dnl this section will only be run if config.status is invoked with no +dnl arguments, or with "glib/glibconfig.h" as an argument. +AC_CONFIG_COMMANDS([glib/glibconfig.h], +[ + outfile=glib/glibconfig.h-tmp + cat > $outfile <<\_______EOF +/* glibconfig.h + * + * This is a generated file. Please modify 'configure.ac' + */ + +#ifndef __GLIBCONFIG_H__ +#define __GLIBCONFIG_H__ + +#include + +_______EOF + + if test x$glib_limits_h = xyes; then + echo '#include ' >> $outfile + fi + if test x$glib_float_h = xyes; then + echo '#include ' >> $outfile + fi + if test x$glib_values_h = xyes; then + echo '#include ' >> $outfile + fi + if test "$glib_header_alloca_h" = "yes"; then + echo '#define GLIB_HAVE_ALLOCA_H' >> $outfile + fi + if test x$glib_sys_poll_h = xyes; then + echo '#define GLIB_HAVE_SYS_POLL_H' >> $outfile + fi + if test x$glib_included_printf != xyes; then + echo " +/* Specifies that GLib's g_print*() functions wrap the + * system printf functions. This is useful to know, for example, + * when using glibc's register_printf_function(). + */" >> $outfile + echo '#define GLIB_USING_SYSTEM_PRINTF' >> $outfile + fi + + cat >> $outfile <<_______EOF + +G_BEGIN_DECLS + +#define G_MINFLOAT $glib_mf +#define G_MAXFLOAT $glib_Mf +#define G_MINDOUBLE $glib_md +#define G_MAXDOUBLE $glib_Md +#define G_MINSHORT $glib_ms +#define G_MAXSHORT $glib_Ms +#define G_MAXUSHORT $glib_Mus +#define G_MININT $glib_mi +#define G_MAXINT $glib_Mi +#define G_MAXUINT $glib_Mui +#define G_MINLONG $glib_ml +#define G_MAXLONG $glib_Ml +#define G_MAXULONG $glib_Mul + +_______EOF + + + ### this should always be true in a modern C/C++ compiler + cat >>$outfile <<_______EOF +typedef signed char gint8; +typedef unsigned char guint8; +_______EOF + + + if test -n "$gint16"; then + cat >>$outfile <<_______EOF +typedef signed $gint16 gint16; +typedef unsigned $gint16 guint16; +#define G_GINT16_MODIFIER $gint16_modifier +#define G_GINT16_FORMAT $gint16_format +#define G_GUINT16_FORMAT $guint16_format +_______EOF + fi + + + if test -n "$gint32"; then + cat >>$outfile <<_______EOF +typedef signed $gint32 gint32; +typedef unsigned $gint32 guint32; +#define G_GINT32_MODIFIER $gint32_modifier +#define G_GINT32_FORMAT $gint32_format +#define G_GUINT32_FORMAT $guint32_format +_______EOF + fi + + cat >>$outfile <<_______EOF +#define G_HAVE_GINT64 1 /* deprecated, always true */ + +${glib_extension}typedef signed $gint64 gint64; +${glib_extension}typedef unsigned $gint64 guint64; + +#define G_GINT64_CONSTANT(val) $gint64_constant +#define G_GUINT64_CONSTANT(val) $guint64_constant +_______EOF + + if test x$gint64_format != x ; then + cat >>$outfile <<_______EOF +#define G_GINT64_MODIFIER $gint64_modifier +#define G_GINT64_FORMAT $gint64_format +#define G_GUINT64_FORMAT $guint64_format +_______EOF + else + cat >>$outfile <<_______EOF +#undef G_GINT64_MODIFIER +#undef G_GINT64_FORMAT +#undef G_GUINT64_FORMAT +_______EOF + fi + + cat >>$outfile <<_______EOF + +#define GLIB_SIZEOF_VOID_P $glib_void_p +#define GLIB_SIZEOF_LONG $glib_long +#define GLIB_SIZEOF_SIZE_T $glib_size_t + +_______EOF + + cat >>$outfile <<_______EOF +typedef signed $glib_size_type_define gssize; +typedef unsigned $glib_size_type_define gsize; +#define G_GSIZE_MODIFIER $gsize_modifier +#define G_GSSIZE_FORMAT $gssize_format +#define G_GSIZE_FORMAT $gsize_format + +#define G_MAXSIZE G_MAXU$glib_msize_type +#define G_MINSSIZE G_MIN$glib_msize_type +#define G_MAXSSIZE G_MAX$glib_msize_type + +typedef gint64 goffset; +#define G_MINOFFSET G_MININT64 +#define G_MAXOFFSET G_MAXINT64 + +#define G_GOFFSET_MODIFIER G_GINT64_MODIFIER +#define G_GOFFSET_FORMAT G_GINT64_FORMAT +#define G_GOFFSET_CONSTANT(val) G_GINT64_CONSTANT(val) + +_______EOF + + if test -z "$glib_unknown_void_p"; then + cat >>$outfile <<_______EOF + +#define GPOINTER_TO_INT(p) ((gint) ${glib_gpi_cast} (p)) +#define GPOINTER_TO_UINT(p) ((guint) ${glib_gpui_cast} (p)) + +#define GINT_TO_POINTER(i) ((gpointer) ${glib_gpi_cast} (i)) +#define GUINT_TO_POINTER(u) ((gpointer) ${glib_gpui_cast} (u)) + +typedef signed $glib_intptr_type_define gintptr; +typedef unsigned $glib_intptr_type_define guintptr; + +#define G_GINTPTR_MODIFIER $gintptr_modifier +#define G_GINTPTR_FORMAT $gintptr_format +#define G_GUINTPTR_FORMAT $guintptr_format +_______EOF + else + echo '#error SIZEOF_VOID_P unknown - This should never happen' >>$outfile + fi + + + + cat >>$outfile <<_______EOF +$glib_atexit +$glib_memmove +$glib_defines +$glib_os +$glib_static_compilation + +$glib_vacopy + +#ifdef __cplusplus +#define G_HAVE_INLINE 1 +#else /* !__cplusplus */ +$glib_inline +#endif /* !__cplusplus */ + +#ifdef __cplusplus +#define G_CAN_INLINE 1 +_______EOF + + if test x$g_can_inline = xyes ; then + cat >>$outfile <<_______EOF +#else /* !__cplusplus */ +#define G_CAN_INLINE 1 +_______EOF + fi + + cat >>$outfile <<_______EOF +#endif + +_______EOF + + if test x$g_have_iso_c_varargs = xyes ; then + cat >>$outfile <<_______EOF +#ifndef __cplusplus +# define G_HAVE_ISO_VARARGS 1 +#endif +_______EOF + fi + if test x$g_have_iso_cxx_varargs = xyes ; then + cat >>$outfile <<_______EOF +#ifdef __cplusplus +# define G_HAVE_ISO_VARARGS 1 +#endif +_______EOF + fi + if test x$g_have_gnuc_varargs = xyes ; then + cat >>$outfile <<_______EOF + +/* gcc-2.95.x supports both gnu style and ISO varargs, but if -ansi + * is passed ISO vararg support is turned off, and there is no work + * around to turn it on, so we unconditionally turn it off. + */ +#if __GNUC__ == 2 && __GNUC_MINOR__ == 95 +# undef G_HAVE_ISO_VARARGS +#endif + +#define G_HAVE_GNUC_VARARGS 1 +_______EOF + fi + + case x$g_stack_grows in + xyes) echo "#define G_HAVE_GROWING_STACK 1" >>$outfile ;; + *) echo "#define G_HAVE_GROWING_STACK 0" >>$outfile ;; + esac + + + echo >>$outfile + if test x$g_have_eilseq = xno; then + cat >>$outfile <<_______EOF +#ifndef EILSEQ +/* On some systems, like SunOS and NetBSD, EILSEQ is not defined. + * The correspondence between this and the corresponding definition + * in libiconv is essential. + */ +# define EILSEQ ENOENT +#endif +_______EOF + + fi + + if test x$g_have_gnuc_visibility = xyes; then + cat >>$outfile <<_______EOF +#define G_HAVE_GNUC_VISIBILITY 1 +_______EOF + fi + cat >>$outfile <<_______EOF +#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590) +#define G_GNUC_INTERNAL __attribute__((visibility("hidden"))) +#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) +#define G_GNUC_INTERNAL __hidden +#elif defined (__GNUC__) && defined (G_HAVE_GNUC_VISIBILITY) +#define G_GNUC_INTERNAL __attribute__((visibility("hidden"))) +#else +#define G_GNUC_INTERNAL +#endif +_______EOF + + echo >>$outfile + cat >>$outfile <<_______EOF +#define G_THREADS_ENABLED +#define G_THREADS_IMPL_$g_threads_impl_def +_______EOF + + if test x"$g_memory_barrier_needed" != xno; then + echo >>$outfile + echo "#define G_ATOMIC_OP_MEMORY_BARRIER_NEEDED 1" >>$outfile + fi + if test x"$g_atomic_lock_free" = xyes; then + echo >>$outfile + echo "#define G_ATOMIC_LOCK_FREE" >>$outfile + fi + echo >>$outfile + g_bit_sizes="16 32 64" + for bits in $g_bit_sizes; do + cat >>$outfile <<_______EOF +#define GINT${bits}_TO_${g_bs_native}(val) ((gint${bits}) (val)) +#define GUINT${bits}_TO_${g_bs_native}(val) ((guint${bits}) (val)) +#define GINT${bits}_TO_${g_bs_alien}(val) ((gint${bits}) GUINT${bits}_SWAP_LE_BE (val)) +#define GUINT${bits}_TO_${g_bs_alien}(val) (GUINT${bits}_SWAP_LE_BE (val)) +_______EOF + done + + cat >>$outfile <<_______EOF +#define GLONG_TO_LE(val) ((glong) GINT${glongbits}_TO_LE (val)) +#define GULONG_TO_LE(val) ((gulong) GUINT${glongbits}_TO_LE (val)) +#define GLONG_TO_BE(val) ((glong) GINT${glongbits}_TO_BE (val)) +#define GULONG_TO_BE(val) ((gulong) GUINT${glongbits}_TO_BE (val)) +#define GINT_TO_LE(val) ((gint) GINT${gintbits}_TO_LE (val)) +#define GUINT_TO_LE(val) ((guint) GUINT${gintbits}_TO_LE (val)) +#define GINT_TO_BE(val) ((gint) GINT${gintbits}_TO_BE (val)) +#define GUINT_TO_BE(val) ((guint) GUINT${gintbits}_TO_BE (val)) +#define GSIZE_TO_LE(val) ((gsize) GUINT${gsizebits}_TO_LE (val)) +#define GSSIZE_TO_LE(val) ((gssize) GINT${gsizebits}_TO_LE (val)) +#define GSIZE_TO_BE(val) ((gsize) GUINT${gsizebits}_TO_BE (val)) +#define GSSIZE_TO_BE(val) ((gssize) GINT${gsizebits}_TO_BE (val)) +#define G_BYTE_ORDER $g_byte_order + +#define GLIB_SYSDEF_POLLIN =$g_pollin +#define GLIB_SYSDEF_POLLOUT =$g_pollout +#define GLIB_SYSDEF_POLLPRI =$g_pollpri +#define GLIB_SYSDEF_POLLHUP =$g_pollhup +#define GLIB_SYSDEF_POLLERR =$g_pollerr +#define GLIB_SYSDEF_POLLNVAL =$g_pollnval + +#define G_MODULE_SUFFIX "$g_module_suffix" + +typedef $g_pid_type GPid; + +#define GLIB_SYSDEF_AF_UNIX $g_af_unix +#define GLIB_SYSDEF_AF_INET $g_af_inet +#define GLIB_SYSDEF_AF_INET6 $g_af_inet6 + +#define GLIB_SYSDEF_MSG_OOB $g_msg_oob +#define GLIB_SYSDEF_MSG_PEEK $g_msg_peek +#define GLIB_SYSDEF_MSG_DONTROUTE $g_msg_dontroute + +G_END_DECLS + +#endif /* __GLIBCONFIG_H__ */ +_______EOF + + + if cmp -s $outfile glib/glibconfig.h; then + AC_MSG_NOTICE([glib/glibconfig.h is unchanged]) + rm -f $outfile + else + mv $outfile glib/glibconfig.h + fi +],[ + +# Note that if two cases are the same, case goes with the first one. +# Note also that this is inside an AC_OUTPUT_COMMAND. We do not depend +# on variable expansion in case labels. Look at the generated config.status +# for a hint. + +if test "x${ac_cv_working_alloca_h+set}" = xset ; then + glib_header_alloca_h="$ac_cv_working_alloca_h" +else + glib_header_alloca_h="$ac_cv_header_alloca_h" +fi + +case xyes in +x$ac_cv_header_float_h) + glib_float_h=yes + glib_mf=FLT_MIN glib_Mf=FLT_MAX + glib_md=DBL_MIN glib_Md=DBL_MAX + ;; +x$ac_cv_header_values_h) + glib_values_h=yes + glib_mf=MINFLOAT glib_Mf=MAXFLOAT + glib_md=MINDOUBLE glib_Md=MAXDOUBLE + ;; +esac + +case xyes in +x$ac_cv_header_limits_h) + glib_limits_h=yes + glib_ms=SHRT_MIN glib_Ms=SHRT_MAX glib_Mus=USHRT_MAX + glib_mi=INT_MIN glib_Mi=INT_MAX glib_Mui=UINT_MAX + glib_ml=LONG_MIN glib_Ml=LONG_MAX glib_Mul=ULONG_MAX + ;; +x$ac_cv_header_values_h) + glib_values_h=yes + glib_ms=MINSHORT glib_Ms=MAXSHORT glib_Mus="(((gushort)G_MAXSHORT)*2+1)" + glib_mi=MININT glib_Mi=MAXINT glib_Mui="(((guint)G_MAXINT)*2+1)" + glib_ml=MINLONG glib_Ml=MAXLONG glib_Mul="(((gulong)G_MAXLONG)*2+1)" + ;; +esac + +if test x$ac_cv_header_sys_poll_h = xyes ; then + glib_sys_poll_h=yes +fi + +if test x$enable_included_printf = xyes ; then + glib_included_printf=yes +fi + +case 2 in +$ac_cv_sizeof_short) + gint16=short + gint16_modifier='"h"' + gint16_format='"hi"' + guint16_format='"hu"' + ;; +$ac_cv_sizeof_int) + gint16=int + gint16_modifier='""' + gint16_format='"i"' + guint16_format='"u"' + ;; +esac +case 4 in +$ac_cv_sizeof_short) + gint32=short + gint32_modifier='"h"' + gint32_format='"hi"' + guint32_format='"hu"' + ;; +$ac_cv_sizeof_int) + gint32=int + gint32_modifier='""' + gint32_format='"i"' + guint32_format='"u"' + ;; +$ac_cv_sizeof_long) + gint32=long + gint32_modifier='"l"' + gint32_format='"li"' + guint32_format='"lu"' + ;; +esac +case 8 in +$ac_cv_sizeof_int) + gint64=int + gint64_modifier='""' + gint64_format='"i"' + guint64_format='"u"' + glib_extension= + gint64_constant='(val)' + guint64_constant='(val)' + ;; +$ac_cv_sizeof_long) + gint64=long + gint64_modifier='"l"' + gint64_format='"li"' + guint64_format='"lu"' + glib_extension= + gint64_constant='(val##L)' + guint64_constant='(val##UL)' + ;; +$ac_cv_sizeof_long_long) + gint64='long long' + if test -n "$glib_cv_long_long_format"; then + gint64_modifier='"'$glib_cv_long_long_format'"' + gint64_format='"'$glib_cv_long_long_format'i"' + guint64_format='"'$glib_cv_long_long_format'u"' + fi + glib_extension='G_GNUC_EXTENSION ' + gint64_constant='(G_GNUC_EXTENSION (val##LL))' + guint64_constant='(G_GNUC_EXTENSION (val##ULL))' + ;; +$ac_cv_sizeof___int64) + gint64='__int64' + if test -n "$glib_cv_long_long_format"; then + gint64_modifier='"'$glib_cv_long_long_format'"' + gint64_format='"'$glib_cv_long_long_format'i"' + guint64_format='"'$glib_cv_long_long_format'u"' + fi + glib_extension= + gint64_constant='(val##i64)' + guint64_constant='(val##ui64)' + ;; +esac +glib_size_t=$ac_cv_sizeof_size_t +glib_size_type_define="$glib_size_type" +glib_void_p=$ac_cv_sizeof_void_p +glib_long=$ac_cv_sizeof_long + +case "$glib_size_type" in +short) + gsize_modifier='"h"' + gsize_format='"hu"' + gssize_format='"hi"' + glib_msize_type='SHRT' + ;; +int) + gsize_modifier='""' + gsize_format='"u"' + gssize_format='"i"' + glib_msize_type='INT' + ;; +long) + gsize_modifier='"l"' + gsize_format='"lu"' + gssize_format='"li"' + glib_msize_type='LONG' + ;; +"long long"|__int64) + gsize_modifier='"I64"' + gsize_format='"I64u"' + gssize_format='"I64i"' + glib_msize_type='INT64' + ;; +esac + +gintbits=`expr $ac_cv_sizeof_int \* 8` +glongbits=`expr $ac_cv_sizeof_long \* 8` +gsizebits=`expr $ac_cv_sizeof_size_t \* 8` + +case $ac_cv_sizeof_void_p in +$ac_cv_sizeof_int) + glib_intptr_type_define=int + gintptr_modifier='""' + gintptr_format='"i"' + guintptr_format='"u"' + glib_gpi_cast='(gint)' + glib_gpui_cast='(guint)' + ;; +$ac_cv_sizeof_long) + glib_intptr_type_define=long + gintptr_modifier='"l"' + gintptr_format='"li"' + guintptr_format='"lu"' + glib_gpi_cast='(glong)' + glib_gpui_cast='(gulong)' + ;; +$ac_cv_sizeof_long_long) + glib_intptr_type_define='long long' + gintptr_modifier='"I64"' + gintptr_format='"I64i"' + guintptr_format='"I64u"' + glib_gpi_cast='(gint64)' + glib_gpui_cast='(guint64)' + ;; +$ac_cv_sizeof___int64) + glib_intptr_type_define=__int64 + gintptr_modifier='"I64"' + gintptr_format='"I64i"' + guintptr_format='"I64u"' + glib_gpi_cast='(gint64)' + glib_gpui_cast='(guint64)' + ;; +*) + glib_unknown_void_p=yes + ;; +esac + + +case xyes in +x$ac_cv_func_atexit) + glib_atexit=" +#ifdef NeXT /* @#%@! NeXTStep */ +# define g_ATEXIT(proc) (!atexit (proc)) +#else +# define g_ATEXIT(proc) (atexit (proc)) +#endif" + ;; +x$ac_cv_func_on_exit) + glib_atexit=" +#define g_ATEXIT(proc) (on_exit ((void (*)(int, void*))(proc), NULL))" + ;; +esac + +case xyes in +x$ac_cv_func_memmove) + glib_memmove=' +#define g_memmove(dest,src,len) G_STMT_START { memmove ((dest), (src), (len)); } G_STMT_END' + ;; +x$glib_cv_working_bcopy) + glib_memmove=" +/* memmove isn't available, but bcopy can copy overlapping memory regions */ +#define g_memmove(d,s,n) G_STMT_START { bcopy ((s), (d), (n)); } G_STMT_END" + ;; +*) + glib_memmove=" +/* memmove isn't found and bcopy can't copy overlapping memory regions, + * so we have to roll our own copy routine. */ +void g_memmove (void* dest, const void * src, unsigned long len);" + ;; +esac + +glib_defines=" +#define GLIB_MAJOR_VERSION $GLIB_MAJOR_VERSION +#define GLIB_MINOR_VERSION $GLIB_MINOR_VERSION +#define GLIB_MICRO_VERSION $GLIB_MICRO_VERSION +" + +case xyes in +x$glib_cv_va_copy) glib_vacopy='#define G_VA_COPY va_copy' ;; +x$glib_cv___va_copy) glib_vacopy='#define G_VA_COPY __va_copy' ;; +*) glib_vacopy='' +esac + +if test x$glib_cv_va_val_copy = xno; then + glib_vacopy="\$glib_vacopy +#define G_VA_COPY_AS_ARRAY 1" +fi + +if test x$glib_cv_hasinline = xyes; then + glib_inline='#define G_HAVE_INLINE 1' +fi +if test x$glib_cv_has__inline = xyes; then + glib_inline="\$glib_inline +#define G_HAVE___INLINE 1" +fi +if test x$glib_cv_has__inline__ = xyes; then + glib_inline="\$glib_inline +#define G_HAVE___INLINE__ 1" +fi + +g_have_gnuc_varargs=$g_have_gnuc_varargs +g_have_iso_c_varargs=$g_have_iso_c_varargs +g_have_iso_cxx_varargs=$g_have_iso_cxx_varargs + +g_can_inline=$g_can_inline +g_have_gnuc_visibility=$g_have_gnuc_visibility +g_have_sunstudio_visibility=$g_have_sunstudio_visibility + +if test x$ac_cv_c_bigendian = xyes; then + g_byte_order=G_BIG_ENDIAN + g_bs_native=BE + g_bs_alien=LE +else + g_byte_order=G_LITTLE_ENDIAN + g_bs_native=LE + g_bs_alien=BE +fi + +g_pollin=$glib_cv_value_POLLIN +g_pollout=$glib_cv_value_POLLOUT +g_pollpri=$glib_cv_value_POLLPRI +g_pollhup=$glib_cv_value_POLLHUP +g_pollerr=$glib_cv_value_POLLERR +g_pollnval=$glib_cv_value_POLLNVAL + +g_af_unix=$glib_cv_value_AF_UNIX +g_af_inet=$glib_cv_value_AF_INET +g_af_inet6=$glib_cv_value_AF_INET6 + +g_msg_peek=$glib_cv_value_MSG_PEEK +g_msg_oob=$glib_cv_value_MSG_OOB +g_msg_dontroute=$glib_cv_value_MSG_DONTROUTE + +g_stack_grows=$glib_cv_stack_grows + +g_have_eilseq=$have_eilseq + +g_threads_impl_def=$g_threads_impl + +g_atomic_lock_free="$glib_cv_g_atomic_lock_free" +g_memory_barrier_needed="$glib_memory_barrier_needed" +g_gcc_atomic_ops="$glib_cv_gcc_has_builtin_atomic_operations" + +g_module_suffix="$glib_gmodule_suffix" + +g_pid_type="$glib_pid_type" +case $host in + *-*-beos*) + glib_os="#define G_OS_BEOS" + ;; + *-*-cygwin*) + glib_os="#define G_OS_UNIX +#define G_PLATFORM_WIN32 +#define G_WITH_CYGWIN" + ;; + *-*-mingw*) + glib_os="#define G_OS_WIN32 +#define G_PLATFORM_WIN32" + ;; + *) + glib_os="#define G_OS_UNIX" + ;; +esac +glib_static_compilation="" +if test x$glib_win32_static_compilation = xyes; then + glib_static_compilation="#define GLIB_STATIC_COMPILATION 1 +#define GOBJECT_STATIC_COMPILATION 1" +fi +]) + +# Redo enough to get guint32 and guint64 for the alignment checks below +case 4 in +$ac_cv_sizeof_short) + gint32=short + ;; +$ac_cv_sizeof_int) + gint32=int + ;; +$ac_cv_sizeof_long) + gint32=long + ;; +esac +case 8 in +$ac_cv_sizeof_int) + gint64=int + ;; +$ac_cv_sizeof_long) + gint64=long + ;; +$ac_cv_sizeof_long_long) + gint64='long long' + ;; +$ac_cv_sizeof___int64) + gint64='__int64' + ;; +esac + +AC_CHECK_ALIGNOF([guint32], [typedef unsigned $gint32 guint32;]) +AC_CHECK_ALIGNOF([guint64], typedef unsigned $gint64 guint64;) +AC_CHECK_ALIGNOF([unsigned long]) + +# Check for libdbus1 - Optional - is only used in the GDBus test cases +# +# 1.2.14 required for dbus_message_set_serial +PKG_CHECK_MODULES(DBUS1, + dbus-1 >= 1.2.14, + [AC_DEFINE(HAVE_DBUS1, 1, [Define if dbus-1 is available]) have_dbus1=yes], + have_dbus1=no) +AC_SUBST(DBUS1_CFLAGS) +AC_SUBST(DBUS1_LIBS) +AM_CONDITIONAL(HAVE_DBUS1, [test "x$have_dbus1" = "xyes"]) + +dnl +dnl Check for -Bsymbolic-functions linker flag used to avoid +dnl intra-library PLT jumps, if available. +dnl + +AC_ARG_ENABLE(Bsymbolic, + [AC_HELP_STRING([--disable-Bsymbolic], + [avoid linking with -Bsymbolic])],, + [SAVED_LDFLAGS="${LDFLAGS}" + AC_MSG_CHECKING([for -Bsymbolic-functions linker flag]) + LDFLAGS=-Wl,-Bsymbolic-functions + AC_TRY_LINK([], [int main (void) { return 0; }], + AC_MSG_RESULT(yes) + enable_Bsymbolic=yes, + AC_MSG_RESULT(no) + enable_Bsymbolic=no) + LDFLAGS="${SAVED_LDFLAGS}"]) + +if test "x${enable_Bsymbolic}" = "xyes"; then + GLIB_LINK_FLAGS=-Wl,-Bsymbolic-functions +fi + +AC_SUBST(GLIB_LINK_FLAGS) + +# +# Define variables corresponding to the correct include paths to use for +# in-tree building. +# + +# for config.h: +config_h_INCLUDES='-I$(top_builddir)' +AC_SUBST(config_h_INCLUDES) + +# glib: +# config.h +# $(top_builddir)/glib: for glibconfig.h +# $(top_srcdir)/glib: for glib.h +# $(top_srcdir): for everything +glib_INCLUDES='$(config_h_INCLUDES) -I$(top_builddir)/glib -I$(top_srcdir)/glib -I$(top_srcdir)' +AC_SUBST(glib_INCLUDES) + +# gthread: +# same as glib +gthread_INCLUDES='$(glib_INCLUDES)' +AC_SUBST(gthread_INCLUDES) + +# gobject: +# same as gthread +gobject_INCLUDES='$(gthread_INCLUDES)' +AC_SUBST(gobject_INCLUDES) + +# gmodule: +# glib includes +# $(top_srcdir)/gmodule: for gmodule.h +gmodule_INCLUDES='$(glib_INCLUDES) -I$(top_srcdir)/gmodule' +AC_SUBST(gmodule_INCLUDES) + +# gio: +# same as gmodule +gio_INCLUDES='$(gmodule_INCLUDES)' +AC_SUBST(gio_INCLUDES) + + +AC_CONFIG_FILES([ +glib-2.0.pc +gmodule-2.0.pc +gmodule-export-2.0.pc +gmodule-no-export-2.0.pc +gthread-2.0.pc +gobject-2.0.pc +gio-2.0.pc +gio-unix-2.0.pc +gio-windows-2.0.pc +glib-zip +glib-gettextize +Makefile +build/Makefile +build/win32/Makefile +build/win32/dirent/Makefile +build/win32/vs9/Makefile +build/win32/vs10/Makefile +glib/Makefile +glib/glib.stp +glib/libcharset/Makefile +glib/gnulib/Makefile +glib/pcre/Makefile +glib/update-pcre/Makefile +glib/tests/Makefile +gmodule/Makefile +gmodule/gmoduleconf.h +gobject/Makefile +gobject/gobject.stp +gobject/glib-mkenums +gobject/tests/Makefile +gthread/Makefile +gio/Makefile +gio/gdbus-2.0/codegen/Makefile +gio/gdbus-2.0/codegen/config.py +gio/xdgmime/Makefile +gio/inotify/Makefile +gio/fen/Makefile +gio/fam/Makefile +gio/win32/Makefile +gio/tests/Makefile +gio/tests/gdbus-object-manager-example/Makefile +po/Makefile.in +docs/Makefile +docs/reference/Makefile +docs/reference/glib/Makefile +docs/reference/glib/version.xml +docs/reference/gobject/Makefile +docs/reference/gobject/version.xml +docs/reference/gio/Makefile +docs/reference/gio/gdbus-object-manager-example/Makefile +docs/reference/gio/version.xml +tests/Makefile +tests/gobject/Makefile +tests/refcount/Makefile +m4macros/Makefile +]) + +AC_CONFIG_COMMANDS([chmod-scripts], +[chmod 0755 glib-zip +chmod 0755 glib-gettextize +chmod 0755 gobject/glib-mkenums]) + +# we want to invoke this macro solely so that the config.status script +# and automake generated makefiles know about these generated files. +# They are only needed to distcheck the package +if false; then + AC_CONFIG_FILES([ + INSTALL + README + config.h.win32 + glib/glibconfig.h.win32 + glib/makefile.msc + glib/glib.rc + gmodule/makefile.msc + gmodule/gmodule.rc + gobject/makefile.msc + gobject/gobject.rc + gthread/makefile.msc + gthread/gthread.rc + gio/gio.rc + tests/makefile.msc + ]) +fi + +AC_OUTPUT diff --git a/glib/glib-gettextize.in b/glib/glib-gettextize.in new file mode 100644 index 0000000..35d01c1 --- /dev/null +++ b/glib/glib-gettextize.in @@ -0,0 +1,188 @@ +#! /bin/sh +# +# Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. +# +# This program 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 2, or (at your option) +# any later version. +# +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# + +# - Modified in October 2001 by jacob berkman to +# work with glib's Makefile.in.in and po2tbl.sed.in, to not copy in +# intl/, and to not add ChangeLog entries to po/ChangeLog + +# This file is meant for authors or maintainers which want to +# internationalize their package with the help of GNU gettext. For +# further information how to use it consult the GNU gettext manual. + +echo=echo +progname=$0 +force=0 +configstatus=0 +origdir=`pwd` +usage="\ +Usage: glib-gettextize [OPTION]... [package-dir] + --help print this help and exit + --version print version information and exit + -c, --copy copy files instead of making symlinks + -f, --force force writing of new files even if old exist +Report bugs to http://bugzilla.gnome.org/." +package=@PACKAGE@ +version=@VERSION@ +try_ln_s=: + +# Directory where the sources are stored. +prefix=@prefix@ +case `uname` in +MINGW32*) + prefix="`dirname $0`/.." + ;; +esac + +datadir=@datadir@ +datarootdir=@datarootdir@ + +gettext_dir=$prefix/share/glib-2.0/gettext + +while test $# -gt 0; do + case "$1" in + -c | --copy | --c* ) + shift + try_ln_s=false ;; + -f | --force | --f* ) + shift + force=1 ;; + -r | --run | --r* ) + shift + configstatus=1 ;; + --help | --h* ) + $echo "$usage"; exit 0 ;; + --version | --v* ) + echo "$progname (GNU $package) $version" + $echo "Copyright (C) 1995-1998, 2000, 2001 Free Software Foundation, Inc. +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + $echo "Written by" "Ulrich Drepper" + exit 0 ;; + -- ) # Stop option prcessing + shift; break ;; + -* ) + $echo "glib-gettextize: unknown option $1" + $echo "Try \`glib-gettextize --help' for more information."; exit 1 ;; + * ) + break ;; + esac +done + +if test $# -gt 1; then + $echo "$usage" + exit 1 +fi + +# Fill in the command line options value. +if test $# -eq 1; then + srcdir=$1 + if cd "$srcdir"; then + srcdir=`pwd` + else + $echo "Cannot change directory to \`$srcdir'" + exit 1 + fi +else + srcdir=$origdir +fi + +test -f configure.in || test -f configure.ac || { + $echo "Missing configure.in or configure.ac, please cd to your package first." + exit 1 +} + +configure_in=NONE +if test -f configure.in; then + configure_in=configure.in +else + if test -f configure.ac; then + configure_in=configure.ac + fi +fi +# Check in which directory config.rpath, mkinstalldirs etc. belong. +auxdir=`cat "$configure_in" | grep '^AC_CONFIG_AUX_DIR' | sed -n -e 's/AC_CONFIG_AUX_DIR(\([^()]*\))/\1/p' | sed -e 's/^\[\(.*\)\]$/\1/' | sed -e 1q` +if test -n "$auxdir"; then + auxdir="$auxdir/" +fi + +if test -f po/Makefile.in.in && test $force -eq 0; then + $echo "\ +po/Makefile.in.in exists: use option -f if you really want to delete it." + exit 1 +fi + +test -d po || { + $echo "Creating po/ subdirectory" + mkdir po || { + $echo "failed to create po/ subdirectory" + exit 1 + } +} + +# For simplicity we changed to the gettext source directory. +cd $gettext_dir || { + $echo "gettext source directory '${gettext_dir}' doesn't exist" + exit 1 +} + +# Now copy all files. Take care for the destination directories. +for file in *; do + case $file in + intl | po) + ;; + mkinstalldirs) + rm -f "$srcdir/$auxdir$file" + ($try_ln_s && ln -s $gettext_dir/$file "$srcdir/$auxdir$file" && $echo "Symlinking file $file") 2>/dev/null || + { $echo "Copying file $file"; cp $file "$srcdir/$auxdir$file"; } + ;; + *) + rm -f "$srcdir/$file" + ($try_ln_s && ln -s $gettext_dir/$file "$srcdir/$file" && $echo "Symlinking file $file") 2>/dev/null || + { $echo "Copying file $file"; cp $file "$srcdir/$file"; } + ;; + esac +done + +# Copy files to po/ subdirectory. +cd po +for file in *; do + rm -f "$srcdir/po/$file" + ($try_ln_s && ln -s $gettext_dir/po/$file "$srcdir/po/$file" && $echo "Symlinking file po/$file") 2>/dev/null || + { $echo "Copying file po/$file"; cp $file "$srcdir/po/$file"; } +done +if test -f "$srcdir/po/cat-id-tbl.c"; then + $echo "Removing po/cat-id-tbl.c" + rm -f "$srcdir/po/cat-id-tbl.c" +fi +if test -f "$srcdir/po/stamp-cat-id"; then + $echo "Removing po/stamp-cat-id" + rm -f "$srcdir/po/stamp-cat-id" +fi + +echo +echo "Please add the files" +echo " codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lcmessage.m4" +echo " progtest.m4" +echo "from the $datadir/aclocal directory to your autoconf macro directory" +echo "or directly to your aclocal.m4 file." +echo "You will also need config.guess and config.sub, which you can get from" +echo "ftp://ftp.gnu.org/pub/gnu/config/." +echo + +exit 0 diff --git a/glib/glib.doap b/glib/glib.doap new file mode 100644 index 0000000..f8ff879 --- /dev/null +++ b/glib/glib.doap @@ -0,0 +1,47 @@ + + + + GLib + glib + + Low level core library + + GLib is the low-level core library that forms the basis for projects such as GTK+ and GNOME. It provides data structure handling for C, portability wrappers, and interfaces for such runtime functionality as an event loop, threads, dynamic loading, and an object system. + + + + + + + + + C + + + + Matthias Clasen + + matthiasc + + + + + + Ryan Lortie + + ryanl + + + + + + + + + + + diff --git a/glib/glib/.gitignore b/glib/glib/.gitignore new file mode 100644 index 0000000..bdecc0b --- /dev/null +++ b/glib/glib/.gitignore @@ -0,0 +1,12 @@ +glibconfig.h +glibconfig.h.win32 +glibconfig-stamp + +gtester +libglib-gdb.py +makefile.msc +gspawn-win32-helper-console.c +gspawn-win64-helper-console.c +gspawn-win64-helper.c +glib_probes.h +glib-public-headers.txt diff --git a/glib/glib/Makefile.am b/glib/glib/Makefile.am new file mode 100644 index 0000000..ac73a8c --- /dev/null +++ b/glib/glib/Makefile.am @@ -0,0 +1,526 @@ +## Process this file with automake to produce Makefile.in +include $(top_srcdir)/Makefile.decl + +BUILT_SOURCES = +DISTCLEANFILES = +CLEANFILES = + +# +# Generate glibconfig.h +# +# The timestamp of the stamp file is used to indicate if glibconfig.h is +# up to date with respect to config.status. In the usual case, changes +# to config.status will not result in changes to glibconfig.h so we +# avoid touching its timestamp (in order not to rebuild the whole tree). +# +DISTCLEANFILES += glibconfig-stamp glibconfig.h +BUILT_SOURCES += glibconfig-stamp +configexecincludedir = $(libdir)/glib-2.0/include +nodist_configexecinclude_HEADERS = glibconfig.h +glibconfig-stamp: ../config.status + $(AM_V_GEN) cd $(top_builddir) && \ + $(SHELL) ./config.status glib/glibconfig.h + @touch glibconfig-stamp + + + +if HAVE_GOOD_PRINTF +else +PRINTF_SUBDIR = gnulib +printf_la = gnulib/libgnulib.la +endif + +if USE_SYSTEM_PCRE +else +MAYBE_PCRE = pcre +endif + +SUBDIRS = libcharset $(PRINTF_SUBDIR) $(MAYBE_PCRE) update-pcre . tests + +DIST_SUBDIRS = libcharset gnulib pcre update-pcre tests + +AM_CPPFLAGS = \ + $(glib_INCLUDES) \ + $(pcre_inc) \ + -DG_LOG_DOMAIN=\"GLib\" \ + $(GLIB_DEBUG_FLAGS) \ + -DGLIB_COMPILATION \ + -DPCRE_STATIC + +glib.def: glib.symbols + $(AM_V_GEN) (echo EXPORTS; $(CPP) -P -DG_OS_WIN32 - <$(srcdir)/glib.symbols | sed -e '/^$$/d' -e 's/^/ /') > $(builddir)/glib.def + +if OS_LINUX +if HAVE_GNUC_VISIBILITY +TESTS_ENVIRONMENT = GLIB_DEBUG_FLAGS="$(GLIB_DEBUG_FLAGS)" +TESTS = abicheck.sh +endif +endif + +MIRRORING_TAB_SOURCE = \ + glib-mirroring-tab/Makefile \ + glib-mirroring-tab/gen-mirroring-tab.c \ + glib-mirroring-tab/packtab.h \ + glib-mirroring-tab/packtab.c + +# The compilation of GRegex can be disabled, but the source files must +# be distributed. +EXTRA_DIST += \ + makefile.msc.in \ + glib.rc.in \ + gen-iswide-table.py \ + gen-unicode-tables.pl \ + gen-script-table.pl \ + glibconfig.h.win32.in \ + abicheck.sh \ + glib.symbols \ + gregex.c \ + gregex.h \ + win_iconv.c \ + libglib-gdb.py.in \ + docs.c \ + gconstructor.h \ + $(MIRRORING_TAB_SOURCE) + +CLEANFILES= libglib-gdb.py + +# These may be in the builddir too +BUILT_EXTRA_DIST = \ + makefile.msc \ + glibconfig.h.win32 \ + glib.rc + +lib_LTLIBRARIES = libglib-2.0.la + +if OS_WIN32_AND_DLL_COMPILATION +if MS_LIB_AVAILABLE +noinst_DATA = glib-2.0.lib + +install_ms_lib_cmd = $(INSTALL) glib-2.0.lib $(DESTDIR)$(libdir) +uninstall_ms_lib_cmd = -rm $(DESTDIR)$(libdir)/glib-2.0.lib +endif +endif + +install-ms-lib: + $(install_ms_lib_cmd) + +uninstall-ms-lib: + $(uninstall_ms_lib_cmd) + +deprecated_sources = \ + deprecated/gallocator.c \ + deprecated/gcache.c \ + deprecated/gcompletion.c \ + deprecated/grel.c \ + deprecated/gthread-deprecated.c + +libglib_2_0_la_SOURCES = \ + $(deprecated_sources) \ + glib_probes.d \ + garray.c \ + gasyncqueue.c \ + gasyncqueueprivate.h \ + gatomic.c \ + gbacktrace.c \ + gbase64.c \ + gbitlock.c \ + gbookmarkfile.c \ + gbsearcharray.h \ + gbytes.c \ + gbytes.h \ + gcharset.c \ + gchecksum.c \ + gconvert.c \ + gdataset.c \ + gdatasetprivate.h \ + gdate.c \ + gdatetime.c \ + gdir.c \ + genviron.c \ + gerror.c \ + gfileutils.c \ + ggettext.c \ + ghash.c \ + ghmac.c \ + ghook.c \ + ghostutils.c \ + giochannel.c \ + gkeyfile.c \ + glibintl.h \ + glib_trace.h \ + glib-init.h \ + glib-init.c \ + glib-private.h \ + glib-private.c \ + glist.c \ + gmain-internal.h \ + gmain.c \ + gmappedfile.c \ + gmarkup.c \ + gmem.c \ + gmessages.c \ + gmirroringtable.h \ + gnode.c \ + goption.c \ + gpattern.c \ + gpoll.c \ + gprimes.c \ + gqsort.c \ + gqueue.c \ + grand.c \ + gregex.c \ + gscanner.c \ + gscripttable.h \ + gsequence.c \ + gshell.c \ + gslice.c \ + gslist.c \ + gstdio.c \ + gstrfuncs.c \ + gstring.c \ + gstringchunk.c \ + gtestutils.c \ + gthread.c \ + gthreadprivate.h \ + gthreadpool.c \ + gtimer.c \ + gtimezone.c \ + gtrashstack.c \ + gtree.c \ + guniprop.c \ + gutf8.c \ + gunibreak.h \ + gunibreak.c \ + gunichartables.h \ + gunicollate.c \ + gunicomp.h \ + gunidecomp.h \ + gunidecomp.c \ + gunicodeprivate.h \ + gurifuncs.c \ + gutils.c \ + gvariant.h \ + gvariant.c \ + gvariant-core.h \ + gvariant-core.c \ + gvariant-internal.h \ + gvariant-parser.c \ + gvariant-serialiser.h \ + gvariant-serialiser.c \ + gvarianttypeinfo.h \ + gvarianttypeinfo.c \ + gvarianttype.c \ + gversion.c \ + gwakeup.h \ + gwakeup.c \ + gprintf.c \ + gprintfint.h + +if OS_UNIX +libglib_2_0_la_SOURCES += glib-unix.c +endif + +if OS_WIN32 +libglib_2_0_la_SOURCES += gthread-win32.c +else +libglib_2_0_la_SOURCES += gthread-posix.c +endif + +EXTRA_libglib_2_0_la_SOURCES = \ + giounix.c \ + giowin32.c \ + gspawn.c \ + gspawn-win32.c \ + gwin32.c + +glibincludedir=$(includedir)/glib-2.0 +glibinclude_HEADERS = \ + glib-unix.h \ + glib-object.h \ + glib.h + +deprecatedincludedir=$(includedir)/glib-2.0/glib/deprecated +deprecatedinclude_HEADERS = \ + deprecated/gallocator.h \ + deprecated/gcache.h \ + deprecated/gcompletion.h \ + deprecated/gmain.h \ + deprecated/grel.h \ + deprecated/gthread.h + +glibsubincludedir=$(includedir)/glib-2.0/glib +glibsubinclude_HEADERS = \ + galloca.h \ + garray.h \ + gasyncqueue.h \ + gatomic.h \ + gbacktrace.h \ + gbase64.h \ + gbitlock.h \ + gbookmarkfile.h \ + gbytes.h \ + gcharset.h \ + gchecksum.h \ + gconvert.h \ + gdataset.h \ + gdate.h \ + gdatetime.h \ + gdir.h \ + genviron.h \ + gerror.h \ + gfileutils.h \ + ggettext.h \ + ghash.h \ + ghmac.h \ + ghook.h \ + ghostutils.h \ + gi18n.h \ + gi18n-lib.h \ + giochannel.h \ + gkeyfile.h \ + glist.h \ + gmacros.h \ + gmain.h \ + gmappedfile.h \ + gmarkup.h \ + gmem.h \ + gmessages.h \ + gnode.h \ + goption.h \ + gpattern.h \ + gpoll.h \ + gprimes.h \ + gqsort.h \ + gquark.h \ + gqueue.h \ + grand.h \ + gregex.h \ + gscanner.h \ + gsequence.h \ + gshell.h \ + gslice.h \ + gslist.h \ + gspawn.h \ + gstdio.h \ + gstrfuncs.h \ + gtestutils.h \ + gstring.h \ + gstringchunk.h \ + gthread.h \ + gthreadpool.h \ + gtimer.h \ + gtimezone.h \ + gtrashstack.h \ + gtree.h \ + gtypes.h \ + gunicode.h \ + gurifuncs.h \ + gutils.h \ + gvarianttype.h \ + gvariant.h \ + gversion.h \ + gversionmacros.h \ + gwin32.h \ + gprintf.h + +# This is read by gobject-introspection/misc/ and gtk-doc +glib-public-headers.txt: Makefile + echo $(glibinclude_HEADERS) $(glibsubinclude_HEADERS) > $@.tmp && mv $@.tmp $@ + +CLEANFILES += glib-public-headers.txt + +all-local: glib-public-headers.txt + +install-data-local: install-ms-lib install-def-file + @if test -f $(glibincludedir)/glist.h ; then \ + echo "*** Old headers found in $(glibincludedir). You should remove the" ; \ + echo "*** contents of this directory and type 'make install' again." ; \ + false ; \ + fi + +uninstall-local: uninstall-ms-lib uninstall-def-file uninstall-gdb + +if PLATFORM_WIN32 +no_undefined = -no-undefined +endif + +if OS_WIN32_AND_DLL_COMPILATION +export_symbols = -export-symbols $(builddir)/glib.def + +glib_win32_res = glib-win32-res.o +glib_win32_res_ldflag = -Wl,$(glib_win32_res) + +glib_def = glib.def + +install-def-file: + $(INSTALL) $(builddir)/glib.def $(DESTDIR)$(libdir)/glib-2.0.def + +uninstall-def-file: + -rm $(DESTDIR)$(libdir)/glib-2.0.def +else +install-def-file: +uninstall-def-file: + +export_symbols = $(LIBTOOL_EXPORT_OPTIONS) +endif + +if USE_SYSTEM_PCRE +pcre_lib = $(PCRE_LIBS) +pcre_inc = $(PCRE_CFLAGS) +else +pcre_lib = pcre/libpcre.la +pcre_inc = +endif + +libglib_2_0_la_LIBADD = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ @ICONV_LIBS@ @G_LIBS_EXTRA@ $(pcre_lib) $(G_THREAD_LIBS_EXTRA) $(G_THREAD_LIBS_FOR_GTHREAD) +libglib_2_0_la_DEPENDENCIES = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ $(glib_win32_res) $(glib_def) + +libglib_2_0_la_LDFLAGS = $(GLIB_LINK_FLAGS) \ + $(glib_win32_res_ldflag) \ + -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ + -export-dynamic $(no_undefined) $(export_symbols) + +INSTALL_PROGS= + +if ENABLE_DTRACE +glib_probes.h: glib_probes.d Makefile + $(AM_V_GEN) $(DTRACE) -C -h -s $< -o $@.tmp + @$(SED) -e "s,define STAP_HAS_SEMAPHORES 1,undef STAP_HAS_SEMAPHORES," < $@.tmp > $@ && rm -f $@.tmp +glib_probes.o: glib_probes.d Makefile + $(AM_V_GEN) $(DTRACE) -G -s $< -o $@ +BUILT_SOURCES += glib_probes.h glib_probes.o +CLEANFILES += glib_probes.h glib_probes.h.tmp +libglib_2_0_la_LIBADD += glib_probes.o +endif + +if ENABLE_SYSTEMTAP +tapset_in_files = glib.stp.in +tapsetdir = @ABS_TAPSET_DIR@ +tapset_DATA = $(tapset_in_files:.stp.in=.stp) +EXTRA_DIST += $(tapset_in_files) +endif + +gspawn-win32-helper-console.c: + echo '#define HELPER_CONSOLE' >$@ + echo '#include "gspawn-win32-helper.c"' >>$@ + +gspawn-win64-helper.c: + echo '#include "gspawn-win32-helper.c"' >$@ + +gspawn-win64-helper-console.c: + echo '#define HELPER_CONSOLE' >$@ + echo '#include "gspawn-win32-helper.c"' >>$@ + + +if OS_WIN32 +if OS_WIN32_X64 +INSTALL_PROGS += gspawn-win64-helper gspawn-win64-helper-console +gspawn_win64_helper_LDADD = libglib-2.0.la +gspawn_win64_helper_LDFLAGS = -mwindows +gspawn_win64_helper_console_LDADD = libglib-2.0.la +else +INSTALL_PROGS += gspawn-win32-helper gspawn-win32-helper-console +gspawn_win32_helper_LDADD = libglib-2.0.la +gspawn_win32_helper_LDFLAGS = -mwindows +gspawn_win32_helper_console_LDADD = libglib-2.0.la +endif +endif + +glib-win32-res.o: glib.rc + $(WINDRES) glib.rc $@ + +bin_PROGRAMS = ${INSTALL_PROGS} + +if OS_UNIX + +INSTALL_PROGS += gtester +gtester_SOURCES = gtester.c +gtester_LDADD = libglib-2.0.la + +auto_config_binscripts = gtester-report +bin_SCRIPTS = ${auto_config_binscripts} +EXTRA_DIST += ${auto_config_binscripts} + +CONFIGVARS = \ + "bindir" : "${bindir}", \ + "glib-version" : "${GLIB_VERSION}" + +install-exec-hook: + for sf in ${auto_config_binscripts} ; do \ + mv -f "$(DESTDIR)$(bindir)/$$sf" "$(DESTDIR)$(bindir)/$$sf".tmp \ + && sed < "$(DESTDIR)$(bindir)/$$sf".tmp > "$(DESTDIR)$(bindir)/$$sf" \ + -e '1,24s|^ *#@PKGINSTALL_CONFIGVARS_IN24LINES@| ${CONFIGVARS}|' \ + -e '1,1s|#! /usr/bin/env python\([0-9]\+\(\.[0-9]\+\)\?\)\?|#!${PYTHON}|' \ + || exit $$? ; \ + chmod a+x $(DESTDIR)$(bindir)/$$sf ; \ + rm -f "$(DESTDIR)$(bindir)/$$sf".tmp ; \ + done + +endif + +glib-2.0.lib: libglib-2.0.la glib.def + lib -machine:@LIB_EXE_MACHINE_FLAG@ -name:libglib-2.0-$(LT_CURRENT_MINUS_AGE).dll -def:$(builddir)/glib.def -out:$@ + +dist-hook: $(BUILT_EXTRA_DIST) ../build/win32/vs9/glib.vcproj ../build/win32/vs10/glib.vcxproj ../build/win32/vs10/glib.vcxproj.filters + files='$(BUILT_EXTRA_DIST)'; \ + for f in $$files; do \ + if test -f $$f; then d=.; else d=$(srcdir); fi; \ + cp $$d/$$f $(distdir) || exit 1; done + +../build/win32/vs9/glib.vcproj: $(top_srcdir)/build/win32/vs9/glib.vcprojin + for F in `echo $(libglib_2_0_la_SOURCES) | tr '/' '\\'`; do \ + case $$F in \ + *-unix.c|gthread-*.c) \ + ;; \ + *.c) echo ' ' \ + ;; \ + esac; \ + done >libglib.sourcefiles + $(CPP) -P - <$(top_srcdir)/build/win32/vs9/glib.vcprojin >$@ + rm libglib.sourcefiles + +../build/win32/vs10/glib.vcxproj: $(top_srcdir)/build/win32/vs10/glib.vcxprojin + for F in `echo $(libglib_2_0_la_SOURCES) | tr '/' '\\'`; do \ + case $$F in \ + *-unix.c|gthread-*.c) \ + ;; \ + *.c) echo ' ' \ + ;; \ + esac; \ + done >libglib.vs10.sourcefiles + $(CPP) -P - <$(top_srcdir)/build/win32/vs10/glib.vcxprojin >$@ + rm libglib.vs10.sourcefiles + +../build/win32/vs10/glib.vcxproj.filters: $(top_srcdir)/build/win32/vs10/glib.vcxproj.filtersin + for F in `echo $(libglib_2_0_la_SOURCES) | tr '/' '\\'`; do \ + case $$F in \ + *-unix.c|gthread-*.c) \ + ;; \ + *.c) echo ' Source Files' \ + ;; \ + esac; \ + done >libglib.vs10.sourcefiles.filters + $(CPP) -P - <$(top_srcdir)/build/win32/vs10/glib.vcxproj.filtersin >$@ + rm libglib.vs10.sourcefiles.filters + +# install gdb scripts +gdbdir = $(datadir)/glib-2.0/gdb +dist_gdb_SCRIPTS = glib.py + +libglib-gdb.py: libglib-gdb.py.in + $(AM_V_GEN) $(SED) -e "s|\@datadir\@|$(datadir)|" $(srcdir)/libglib-gdb.py.in > $(builddir)/libglib-gdb.py + + +install-data-hook: libglib-gdb.py + mkdir -p $(DESTDIR)$(datadir)/gdb/auto-load$(ABS_GLIB_RUNTIME_LIBDIR) + $(INSTALL) $(builddir)/libglib-gdb.py $(DESTDIR)$(datadir)/gdb/auto-load$(ABS_GLIB_RUNTIME_LIBDIR)/libglib-2.0.so.0.$(LT_CURRENT).$(LT_REVISION)-gdb.py +if HAVE_GLIB_RUNTIME_LIBDIR + mkdir -p $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR) + mv $(DESTDIR)$(libdir)/libglib-2.0.so.0 $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR) + mv $(DESTDIR)$(libdir)/libglib-2.0.so.0.$(LT_CURRENT).$(LT_REVISION) $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR) + rm -f $(DESTDIR)$(libdir)/libglib-2.0.so + ln -s $(GLIB_RUNTIME_LIBDIR)/libglib-2.0.so.0.$(LT_CURRENT).$(LT_REVISION) $(DESTDIR)$(libdir)/libglib-2.0.so +endif + +uninstall-gdb: + -rm -r $(DESTDIR)$(datadir)/gdb diff --git a/glib/glib/abicheck.sh b/glib/glib/abicheck.sh new file mode 100755 index 0000000..3137794 --- /dev/null +++ b/glib/glib/abicheck.sh @@ -0,0 +1,13 @@ +#! /bin/sh + +egrep '^#([^i]|if).*[^\]$' "${builddir:-.}/glibconfig.h" > glibconfig.cpp + +INCLUDES="-include ${top_builddir:-..}/config.h" +INCLUDES="$INCLUDES -include glibconfig.cpp $GLIB_DEBUG_FLAGS" + +cpp -P -DG_STDIO_NO_WRAP_ON_UNIX $INCLUDES "${srcdir:-.}/glib.symbols" | sed -e '/^$/d' -e 's/ PRIVATE$//' | sort > expected-abi +rm -f glibconfig.cpp + +nm -D -g --defined-only .libs/libglib-2.0.so | cut -d ' ' -f 3 | egrep -v '^(__bss_start|_edata|_end)' | sort > actual-abi + +diff -u expected-abi actual-abi && rm -f expected-abi actual-abi diff --git a/glib/glib/deprecated/gallocator.c b/glib/glib/deprecated/gallocator.c new file mode 100644 index 0000000..a191eb6 --- /dev/null +++ b/glib/glib/deprecated/gallocator.c @@ -0,0 +1,104 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include "gallocator.h" + +#include +#include + +struct _GMemChunk { + guint alloc_size; /* the size of an atom */ +}; + +GMemChunk* +g_mem_chunk_new (const gchar *name, + gint atom_size, + gsize area_size, + gint type) +{ + GMemChunk *mem_chunk; + + g_return_val_if_fail (atom_size > 0, NULL); + + mem_chunk = g_slice_new (GMemChunk); + mem_chunk->alloc_size = atom_size; + + return mem_chunk; +} + +void +g_mem_chunk_destroy (GMemChunk *mem_chunk) +{ + g_return_if_fail (mem_chunk != NULL); + + g_slice_free (GMemChunk, mem_chunk); +} + +gpointer +g_mem_chunk_alloc (GMemChunk *mem_chunk) +{ + g_return_val_if_fail (mem_chunk != NULL, NULL); + + return g_slice_alloc (mem_chunk->alloc_size); +} + +gpointer +g_mem_chunk_alloc0 (GMemChunk *mem_chunk) +{ + g_return_val_if_fail (mem_chunk != NULL, NULL); + + return g_slice_alloc0 (mem_chunk->alloc_size); +} + +void +g_mem_chunk_free (GMemChunk *mem_chunk, + gpointer mem) +{ + g_return_if_fail (mem_chunk != NULL); + + g_slice_free1 (mem_chunk->alloc_size, mem); +} + +GAllocator* +g_allocator_new (const gchar *name, + guint n_preallocs) +{ + /* some (broken) GAllocator uses depend on non-NULL allocators */ + return (void *) 1; +} + +void g_allocator_free (GAllocator *allocator) { } + +void g_mem_chunk_clean (GMemChunk *mem_chunk) { } +void g_mem_chunk_reset (GMemChunk *mem_chunk) { } +void g_mem_chunk_print (GMemChunk *mem_chunk) { } +void g_mem_chunk_info (void) { } +void g_blow_chunks (void) { } + +void g_list_push_allocator (GAllocator *allocator) { } +void g_list_pop_allocator (void) { } + +void g_slist_push_allocator (GAllocator *allocator) { } +void g_slist_pop_allocator (void) { } + +void g_node_push_allocator (GAllocator *allocator) { } +void g_node_pop_allocator (void) { } diff --git a/glib/glib/deprecated/gallocator.h b/glib/glib/deprecated/gallocator.h new file mode 100644 index 0000000..e4990e9 --- /dev/null +++ b/glib/glib/deprecated/gallocator.h @@ -0,0 +1,90 @@ +/* + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_ALLOCATOR_H__ +#define __G_ALLOCATOR_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GAllocator GAllocator; +typedef struct _GMemChunk GMemChunk; + +#define G_ALLOC_ONLY 1 +#define G_ALLOC_AND_FREE 2 +#define G_ALLOCATOR_LIST 1 +#define G_ALLOCATOR_SLIST 2 +#define G_ALLOCATOR_NODE 3 + +#define g_chunk_new(type, chunk) ((type *) g_mem_chunk_alloc (chunk)) +#define g_chunk_new0(type, chunk) ((type *) g_mem_chunk_alloc0 (chunk)) +#define g_chunk_free(mem, mem_chunk) (g_mem_chunk_free (mem_chunk, mem)) +#define g_mem_chunk_create(type, x, y) (g_mem_chunk_new (NULL, sizeof (type), 0, 0)) + + +GLIB_DEPRECATED +GMemChunk * g_mem_chunk_new (const gchar *name, + gint atom_size, + gsize area_size, + gint type); +GLIB_DEPRECATED +void g_mem_chunk_destroy (GMemChunk *mem_chunk); +GLIB_DEPRECATED +gpointer g_mem_chunk_alloc (GMemChunk *mem_chunk); +GLIB_DEPRECATED +gpointer g_mem_chunk_alloc0 (GMemChunk *mem_chunk); +GLIB_DEPRECATED +void g_mem_chunk_free (GMemChunk *mem_chunk, + gpointer mem); +GLIB_DEPRECATED +void g_mem_chunk_clean (GMemChunk *mem_chunk); +GLIB_DEPRECATED +void g_mem_chunk_reset (GMemChunk *mem_chunk); +GLIB_DEPRECATED +void g_mem_chunk_print (GMemChunk *mem_chunk); +GLIB_DEPRECATED +void g_mem_chunk_info (void); +GLIB_DEPRECATED +void g_blow_chunks (void); + + +GLIB_DEPRECATED +GAllocator * g_allocator_new (const gchar *name, + guint n_preallocs); +GLIB_DEPRECATED +void g_allocator_free (GAllocator *allocator); +GLIB_DEPRECATED +void g_list_push_allocator (GAllocator *allocator); +GLIB_DEPRECATED +void g_list_pop_allocator (void); +GLIB_DEPRECATED +void g_slist_push_allocator (GAllocator *allocator); +GLIB_DEPRECATED +void g_slist_pop_allocator (void); +GLIB_DEPRECATED +void g_node_push_allocator (GAllocator *allocator); +GLIB_DEPRECATED +void g_node_pop_allocator (void); + +G_END_DECLS + +#endif /* __G_ALLOCATOR_H__ */ diff --git a/glib/glib/deprecated/gcache.c b/glib/glib/deprecated/gcache.c new file mode 100644 index 0000000..4968c32 --- /dev/null +++ b/glib/glib/deprecated/gcache.c @@ -0,0 +1,345 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "gcache.h" + +#include "gslice.h" +#include "ghash.h" +#include "gtestutils.h" + +/** + * SECTION:caches + * @title: Caches + * @short_description: caches allow sharing of complex data structures + * to save resources + * + * A #GCache allows sharing of complex data structures, in order to + * save system resources. + * + * GCache uses keys and values. A GCache key describes the properties + * of a particular resource. A GCache value is the actual resource. + * + * GCache has been marked as deprecated, since this API is rarely + * used and not very actively maintained. + */ + +typedef struct _GCacheNode GCacheNode; + +struct _GCacheNode +{ + /* A reference counted node */ + gpointer value; + gint ref_count; +}; + +/** + * GCache: + * + * The #GCache struct is an opaque data structure containing + * information about a #GCache. It should only be accessed via the + * following functions. + * + * Deprecated:2.32: Use a #GHashTable instead + */ +struct _GCache +{ + /* Called to create a value from a key */ + GCacheNewFunc value_new_func; + + /* Called to destroy a value */ + GCacheDestroyFunc value_destroy_func; + + /* Called to duplicate a key */ + GCacheDupFunc key_dup_func; + + /* Called to destroy a key */ + GCacheDestroyFunc key_destroy_func; + + /* Associates keys with nodes */ + GHashTable *key_table; + + /* Associates nodes with keys */ + GHashTable *value_table; +}; + +static inline GCacheNode* +g_cache_node_new (gpointer value) +{ + GCacheNode *node = g_slice_new (GCacheNode); + node->value = value; + node->ref_count = 1; + return node; +} + +static inline void +g_cache_node_destroy (GCacheNode *node) +{ + g_slice_free (GCacheNode, node); +} + +/** + * g_cache_new: + * @value_new_func: a function to create a new object given a key. + * This is called by g_cache_insert() if an object + * with the given key does not already exist + * @value_destroy_func: a function to destroy an object. It is called + * by g_cache_remove() when the object is no + * longer needed (i.e. its reference count drops + * to 0) + * @key_dup_func: a function to copy a key. It is called by + * g_cache_insert() if the key does not already exist in + * the #GCache + * @key_destroy_func: a function to destroy a key. It is called by + * g_cache_remove() when the object is no longer + * needed (i.e. its reference count drops to 0) + * @hash_key_func: a function to create a hash value from a key + * @hash_value_func: a function to create a hash value from a value + * @key_equal_func: a function to compare two keys. It should return + * %TRUE if the two keys are equivalent + * + * Creates a new #GCache. + * + * Returns: a new #GCache + * + * Deprecated:2.32: Use a #GHashTable instead + */ + +/** + * GCacheNewFunc: + * @key: a #GCache key + * @Returns: a new #GCache value corresponding to the key. + * + * Specifies the type of the @value_new_func function passed to + * g_cache_new(). It is passed a #GCache key and should create the + * value corresponding to the key. + */ + +/** + * GCacheDestroyFunc: + * @value: the #GCache value to destroy + * + * Specifies the type of the @value_destroy_func and @key_destroy_func + * functions passed to g_cache_new(). The functions are passed a + * pointer to the #GCache key or #GCache value and should free any + * memory and other resources associated with it. + */ + +/** + * GCacheDupFunc: + * @value: the #GCache key to destroy (not a + * #GCache value as it seems) + * @Returns: a copy of the #GCache key + * + * Specifies the type of the @key_dup_func function passed to + * g_cache_new(). The function is passed a key + * (not a value as the prototype implies) and + * should return a duplicate of the key. + */ +GCache* +g_cache_new (GCacheNewFunc value_new_func, + GCacheDestroyFunc value_destroy_func, + GCacheDupFunc key_dup_func, + GCacheDestroyFunc key_destroy_func, + GHashFunc hash_key_func, + GHashFunc hash_value_func, + GEqualFunc key_equal_func) +{ + GCache *cache; + + g_return_val_if_fail (value_new_func != NULL, NULL); + g_return_val_if_fail (value_destroy_func != NULL, NULL); + g_return_val_if_fail (key_dup_func != NULL, NULL); + g_return_val_if_fail (key_destroy_func != NULL, NULL); + g_return_val_if_fail (hash_key_func != NULL, NULL); + g_return_val_if_fail (hash_value_func != NULL, NULL); + g_return_val_if_fail (key_equal_func != NULL, NULL); + + cache = g_slice_new (GCache); + cache->value_new_func = value_new_func; + cache->value_destroy_func = value_destroy_func; + cache->key_dup_func = key_dup_func; + cache->key_destroy_func = key_destroy_func; + cache->key_table = g_hash_table_new (hash_key_func, key_equal_func); + cache->value_table = g_hash_table_new (hash_value_func, NULL); + + return cache; +} + +/** + * g_cache_destroy: + * @cache: a #GCache + * + * Frees the memory allocated for the #GCache. + * + * Note that it does not destroy the keys and values which were + * contained in the #GCache. + * + * Deprecated:2.32: Use a #GHashTable instead + */ +void +g_cache_destroy (GCache *cache) +{ + g_return_if_fail (cache != NULL); + + g_hash_table_destroy (cache->key_table); + g_hash_table_destroy (cache->value_table); + g_slice_free (GCache, cache); +} + +/** + * g_cache_insert: + * @cache: a #GCache + * @key: a key describing a #GCache object + * + * Gets the value corresponding to the given key, creating it if + * necessary. It first checks if the value already exists in the + * #GCache, by using the @key_equal_func function passed to + * g_cache_new(). If it does already exist it is returned, and its + * reference count is increased by one. If the value does not currently + * exist, if is created by calling the @value_new_func. The key is + * duplicated by calling @key_dup_func and the duplicated key and value + * are inserted into the #GCache. + * + * Returns: a pointer to a #GCache value + * + * Deprecated:2.32: Use a #GHashTable instead + */ +gpointer +g_cache_insert (GCache *cache, + gpointer key) +{ + GCacheNode *node; + gpointer value; + + g_return_val_if_fail (cache != NULL, NULL); + + node = g_hash_table_lookup (cache->key_table, key); + if (node) + { + node->ref_count += 1; + return node->value; + } + + key = (* cache->key_dup_func) (key); + value = (* cache->value_new_func) (key); + node = g_cache_node_new (value); + + g_hash_table_insert (cache->key_table, key, node); + g_hash_table_insert (cache->value_table, value, key); + + return node->value; +} + +/** + * g_cache_remove: + * @cache: a #GCache + * @value: the value to remove + * + * Decreases the reference count of the given value. If it drops to 0 + * then the value and its corresponding key are destroyed, using the + * @value_destroy_func and @key_destroy_func passed to g_cache_new(). + * + * Deprecated:2.32: Use a #GHashTable instead + */ +void +g_cache_remove (GCache *cache, + gconstpointer value) +{ + GCacheNode *node; + gpointer key; + + g_return_if_fail (cache != NULL); + + key = g_hash_table_lookup (cache->value_table, value); + node = g_hash_table_lookup (cache->key_table, key); + + g_return_if_fail (node != NULL); + + node->ref_count -= 1; + if (node->ref_count == 0) + { + g_hash_table_remove (cache->value_table, value); + g_hash_table_remove (cache->key_table, key); + + (* cache->key_destroy_func) (key); + (* cache->value_destroy_func) (node->value); + g_cache_node_destroy (node); + } +} + +/** + * g_cache_key_foreach: + * @cache: a #GCache + * @func: the function to call with each #GCache key + * @user_data: user data to pass to the function + * + * Calls the given function for each of the keys in the #GCache. + * + * NOTE @func is passed three parameters, the value and key of a cache + * entry and the @user_data. The order of value and key is different + * from the order in which g_hash_table_foreach() passes key-value + * pairs to its callback function ! + * + * Deprecated:2.32: Use a #GHashTable instead + */ +void +g_cache_key_foreach (GCache *cache, + GHFunc func, + gpointer user_data) +{ + g_return_if_fail (cache != NULL); + g_return_if_fail (func != NULL); + + g_hash_table_foreach (cache->value_table, func, user_data); +} + +/** + * g_cache_value_foreach: + * @cache: a #GCache + * @func: the function to call with each #GCache value + * @user_data: user data to pass to the function + * + * Calls the given function for each of the values in the #GCache. + * + * Deprecated:2.10: The reason is that it passes pointers to internal + * data structures to @func; use g_cache_key_foreach() instead + */ +void +g_cache_value_foreach (GCache *cache, + GHFunc func, + gpointer user_data) +{ + g_return_if_fail (cache != NULL); + g_return_if_fail (func != NULL); + + g_hash_table_foreach (cache->key_table, func, user_data); +} diff --git a/glib/glib/deprecated/gcache.h b/glib/glib/deprecated/gcache.h new file mode 100644 index 0000000..2e5119b --- /dev/null +++ b/glib/glib/deprecated/gcache.h @@ -0,0 +1,73 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_CACHE_H__ +#define __G_CACHE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GCache GCache; + +typedef gpointer (*GCacheNewFunc) (gpointer key); +typedef gpointer (*GCacheDupFunc) (gpointer value); +typedef void (*GCacheDestroyFunc) (gpointer value); + +/* Caches + */ +GLIB_DEPRECATED +GCache* g_cache_new (GCacheNewFunc value_new_func, + GCacheDestroyFunc value_destroy_func, + GCacheDupFunc key_dup_func, + GCacheDestroyFunc key_destroy_func, + GHashFunc hash_key_func, + GHashFunc hash_value_func, + GEqualFunc key_equal_func); +GLIB_DEPRECATED +void g_cache_destroy (GCache *cache); +GLIB_DEPRECATED +gpointer g_cache_insert (GCache *cache, + gpointer key); +GLIB_DEPRECATED +void g_cache_remove (GCache *cache, + gconstpointer value); +GLIB_DEPRECATED +void g_cache_key_foreach (GCache *cache, + GHFunc func, + gpointer user_data); +GLIB_DEPRECATED +void g_cache_value_foreach (GCache *cache, + GHFunc func, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_CACHE_H__ */ diff --git a/glib/glib/deprecated/gcompletion.c b/glib/glib/deprecated/gcompletion.c new file mode 100644 index 0000000..620af0e --- /dev/null +++ b/glib/glib/deprecated/gcompletion.c @@ -0,0 +1,492 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include "gcompletion.h" + +#include +#include +#include + +#include + +/** + * SECTION:completion + * @title: Automatic String Completion + * @short_description: support for automatic completion using a group + * of target strings + * + * #GCompletion provides support for automatic completion of a string + * using any group of target strings. It is typically used for file + * name completion as is common in many UNIX shells. + * + * A #GCompletion is created using g_completion_new(). Target items are + * added and removed with g_completion_add_items(), + * g_completion_remove_items() and g_completion_clear_items(). A + * completion attempt is requested with g_completion_complete() or + * g_completion_complete_utf8(). When no longer needed, the + * #GCompletion is freed with g_completion_free(). + * + * Items in the completion can be simple strings (e.g. filenames), or + * pointers to arbitrary data structures. If data structures are used + * you must provide a #GCompletionFunc in g_completion_new(), which + * retrieves the item's string from the data structure. You can change + * the way in which strings are compared by setting a different + * #GCompletionStrncmpFunc in g_completion_set_compare(). + * + * GCompletion has been marked as deprecated, since this API is rarely + * used and not very actively maintained. + **/ + +/** + * GCompletion: + * @items: list of target items (strings or data structures). + * @func: function which is called to get the string associated with a + * target item. It is %NULL if the target items are strings. + * @prefix: the last prefix passed to g_completion_complete() or + * g_completion_complete_utf8(). + * @cache: the list of items which begin with @prefix. + * @strncmp_func: The function to use when comparing strings. Use + * g_completion_set_compare() to modify this function. + * + * The data structure used for automatic completion. + **/ + +/** + * GCompletionFunc: + * @Param1: the completion item. + * @Returns: the string corresponding to the item. + * + * Specifies the type of the function passed to g_completion_new(). It + * should return the string corresponding to the given target item. + * This is used when you use data structures as #GCompletion items. + **/ + +/** + * GCompletionStrncmpFunc: + * @s1: string to compare with @s2. + * @s2: string to compare with @s1. + * @n: maximal number of bytes to compare. + * @Returns: an integer less than, equal to, or greater than zero if + * the first @n bytes of @s1 is found, respectively, to be + * less than, to match, or to be greater than the first @n + * bytes of @s2. + * + * Specifies the type of the function passed to + * g_completion_set_compare(). This is used when you use strings as + * #GCompletion items. + **/ + +static void completion_check_cache (GCompletion* cmp, + gchar** new_prefix); + +/** + * g_completion_new: + * @func: the function to be called to return the string representing + * an item in the #GCompletion, or %NULL if strings are going to + * be used as the #GCompletion items. + * @Returns: the new #GCompletion. + * + * Creates a new #GCompletion. + **/ +GCompletion* +g_completion_new (GCompletionFunc func) +{ + GCompletion* gcomp; + + gcomp = g_new (GCompletion, 1); + gcomp->items = NULL; + gcomp->cache = NULL; + gcomp->prefix = NULL; + gcomp->func = func; + gcomp->strncmp_func = strncmp; + + return gcomp; +} + +/** + * g_completion_add_items: + * @cmp: the #GCompletion. + * @items: the list of items to add. + * + * Adds items to the #GCompletion. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_add_items (GCompletion* cmp, + GList* items) +{ + GList* it; + + g_return_if_fail (cmp != NULL); + + /* optimize adding to cache? */ + if (cmp->cache) + { + g_list_free (cmp->cache); + cmp->cache = NULL; + } + + if (cmp->prefix) + { + g_free (cmp->prefix); + cmp->prefix = NULL; + } + + it = items; + while (it) + { + cmp->items = g_list_prepend (cmp->items, it->data); + it = it->next; + } +} + +/** + * g_completion_remove_items: + * @cmp: the #GCompletion. + * @items: the items to remove. + * + * Removes items from a #GCompletion. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_remove_items (GCompletion* cmp, + GList* items) +{ + GList* it; + + g_return_if_fail (cmp != NULL); + + it = items; + while (cmp->items && it) + { + cmp->items = g_list_remove (cmp->items, it->data); + it = it->next; + } + + it = items; + while (cmp->cache && it) + { + cmp->cache = g_list_remove(cmp->cache, it->data); + it = it->next; + } +} + +/** + * g_completion_clear_items: + * @cmp: the #GCompletion. + * + * Removes all items from the #GCompletion. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_clear_items (GCompletion* cmp) +{ + g_return_if_fail (cmp != NULL); + + g_list_free (cmp->items); + cmp->items = NULL; + g_list_free (cmp->cache); + cmp->cache = NULL; + g_free (cmp->prefix); + cmp->prefix = NULL; +} + +static void +completion_check_cache (GCompletion* cmp, + gchar** new_prefix) +{ + register GList* list; + register gsize len; + register gsize i; + register gsize plen; + gchar* postfix; + gchar* s; + + if (!new_prefix) + return; + if (!cmp->cache) + { + *new_prefix = NULL; + return; + } + + len = strlen(cmp->prefix); + list = cmp->cache; + s = cmp->func ? cmp->func (list->data) : (gchar*) list->data; + postfix = s + len; + plen = strlen (postfix); + list = list->next; + + while (list && plen) + { + s = cmp->func ? cmp->func (list->data) : (gchar*) list->data; + s += len; + for (i = 0; i < plen; ++i) + { + if (postfix[i] != s[i]) + break; + } + plen = i; + list = list->next; + } + + *new_prefix = g_new0 (gchar, len + plen + 1); + strncpy (*new_prefix, cmp->prefix, len); + strncpy (*new_prefix + len, postfix, plen); +} + +/** + * g_completion_complete_utf8: + * @cmp: the #GCompletion + * @prefix: the prefix string, typically used by the user, which is compared + * with each of the items + * @new_prefix: if non-%NULL, returns the longest prefix which is common to all + * items that matched @prefix, or %NULL if no items matched @prefix. + * This string should be freed when no longer needed. + * + * Attempts to complete the string @prefix using the #GCompletion target items. + * In contrast to g_completion_complete(), this function returns the largest common + * prefix that is a valid UTF-8 string, omitting a possible common partial + * character. + * + * You should use this function instead of g_completion_complete() if your + * items are UTF-8 strings. + * + * Return value: (element-type utf8) (transfer none): the list of items whose strings begin with @prefix. This should + * not be changed. + * + * Since: 2.4 + * + * Deprecated: 2.26: Rarely used API + **/ +GList* +g_completion_complete_utf8 (GCompletion *cmp, + const gchar *prefix, + gchar **new_prefix) +{ + GList *list; + gchar *p, *q; + + list = g_completion_complete (cmp, prefix, new_prefix); + + if (new_prefix && *new_prefix) + { + p = *new_prefix + strlen (*new_prefix); + q = g_utf8_find_prev_char (*new_prefix, p); + + switch (g_utf8_get_char_validated (q, p - q)) + { + case (gunichar)-2: + case (gunichar)-1: + *q = 0; + break; + default: ; + } + + } + + return list; +} + +/** + * g_completion_complete: + * @cmp: the #GCompletion. + * @prefix: the prefix string, typically typed by the user, which is + * compared with each of the items. + * @new_prefix: if non-%NULL, returns the longest prefix which is + * common to all items that matched @prefix, or %NULL if + * no items matched @prefix. This string should be freed + * when no longer needed. + * @Returns: the list of items whose strings begin with @prefix. This + * should not be changed. + * + * Attempts to complete the string @prefix using the #GCompletion + * target items. + * + * Deprecated: 2.26: Rarely used API + **/ +GList* +g_completion_complete (GCompletion* cmp, + const gchar* prefix, + gchar** new_prefix) +{ + gsize plen, len; + gboolean done = FALSE; + GList* list; + + g_return_val_if_fail (cmp != NULL, NULL); + g_return_val_if_fail (prefix != NULL, NULL); + + len = strlen (prefix); + if (cmp->prefix && cmp->cache) + { + plen = strlen (cmp->prefix); + if (plen <= len && ! cmp->strncmp_func (prefix, cmp->prefix, plen)) + { + /* use the cache */ + list = cmp->cache; + while (list) + { + GList *next = list->next; + + if (cmp->strncmp_func (prefix, + cmp->func ? cmp->func (list->data) : (gchar*) list->data, + len)) + cmp->cache = g_list_delete_link (cmp->cache, list); + + list = next; + } + done = TRUE; + } + } + + if (!done) + { + /* normal code */ + g_list_free (cmp->cache); + cmp->cache = NULL; + list = cmp->items; + while (*prefix && list) + { + if (!cmp->strncmp_func (prefix, + cmp->func ? cmp->func (list->data) : (gchar*) list->data, + len)) + cmp->cache = g_list_prepend (cmp->cache, list->data); + list = list->next; + } + } + if (cmp->prefix) + { + g_free (cmp->prefix); + cmp->prefix = NULL; + } + if (cmp->cache) + cmp->prefix = g_strdup (prefix); + completion_check_cache (cmp, new_prefix); + + return *prefix ? cmp->cache : cmp->items; +} + +/** + * g_completion_free: + * @cmp: the #GCompletion. + * + * Frees all memory used by the #GCompletion. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_free (GCompletion* cmp) +{ + g_return_if_fail (cmp != NULL); + + g_completion_clear_items (cmp); + g_free (cmp); +} + +/** + * g_completion_set_compare: + * @cmp: a #GCompletion. + * @strncmp_func: the string comparison function. + * + * Sets the function to use for string comparisons. The default string + * comparison function is strncmp(). + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_completion_set_compare(GCompletion *cmp, + GCompletionStrncmpFunc strncmp_func) +{ + cmp->strncmp_func = strncmp_func; +} + +#ifdef TEST_COMPLETION +#include +int +main (int argc, + char* argv[]) +{ + FILE *file; + gchar buf[1024]; + GList *list; + GList *result; + GList *tmp; + GCompletion *cmp; + gint i; + gchar *longp = NULL; + + if (argc < 3) + { + g_warning ("Usage: %s filename prefix1 [prefix2 ...]\n", argv[0]); + return 1; + } + + file = fopen (argv[1], "r"); + if (!file) + { + g_warning ("Cannot open %s\n", argv[1]); + return 1; + } + + cmp = g_completion_new (NULL); + list = g_list_alloc (); + while (fgets (buf, 1024, file)) + { + list->data = g_strdup (buf); + g_completion_add_items (cmp, list); + } + fclose (file); + + for (i = 2; i < argc; ++i) + { + printf ("COMPLETING: %s\n", argv[i]); + result = g_completion_complete (cmp, argv[i], &longp); + g_list_foreach (result, (GFunc) printf, NULL); + printf ("LONG MATCH: %s\n", longp); + g_free (longp); + longp = NULL; + } + + g_list_foreach (cmp->items, (GFunc) g_free, NULL); + g_completion_free (cmp); + g_list_free (list); + + return 0; +} +#endif diff --git a/glib/glib/deprecated/gcompletion.h b/glib/glib/deprecated/gcompletion.h new file mode 100644 index 0000000..88a0479 --- /dev/null +++ b/glib/glib/deprecated/gcompletion.h @@ -0,0 +1,85 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_COMPLETION_H__ +#define __G_COMPLETION_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GCompletion GCompletion; + +typedef gchar* (*GCompletionFunc) (gpointer); + +/* GCompletion + */ + +typedef gint (*GCompletionStrncmpFunc) (const gchar *s1, + const gchar *s2, + gsize n); + +struct _GCompletion +{ + GList* items; + GCompletionFunc func; + + gchar* prefix; + GList* cache; + GCompletionStrncmpFunc strncmp_func; +}; + +GLIB_DEPRECATED_IN_2_26 +GCompletion* g_completion_new (GCompletionFunc func); +GLIB_DEPRECATED_IN_2_26 +void g_completion_add_items (GCompletion* cmp, + GList* items); +GLIB_DEPRECATED_IN_2_26 +void g_completion_remove_items (GCompletion* cmp, + GList* items); +GLIB_DEPRECATED_IN_2_26 +void g_completion_clear_items (GCompletion* cmp); +GLIB_DEPRECATED_IN_2_26 +GList* g_completion_complete (GCompletion* cmp, + const gchar* prefix, + gchar** new_prefix); +GLIB_DEPRECATED_IN_2_26 +GList* g_completion_complete_utf8 (GCompletion *cmp, + const gchar* prefix, + gchar** new_prefix); +GLIB_DEPRECATED_IN_2_26 +void g_completion_set_compare (GCompletion *cmp, + GCompletionStrncmpFunc strncmp_func); +GLIB_DEPRECATED_IN_2_26 +void g_completion_free (GCompletion* cmp); + +G_END_DECLS + +#endif /* __G_COMPLETION_H__ */ diff --git a/glib/glib/deprecated/gmain.h b/glib/glib/deprecated/gmain.h new file mode 100644 index 0000000..d1ddf19 --- /dev/null +++ b/glib/glib/deprecated/gmain.h @@ -0,0 +1,138 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_DEPRECATED_MAIN_H__ +#define __G_DEPRECATED_MAIN_H__ + +#include + +G_BEGIN_DECLS + +/* ============== Compat main loop stuff ================== */ + +/** + * g_main_new: + * @is_running: set to %TRUE to indicate that the loop is running. This + * is not very important since calling g_main_run() will set this + * to %TRUE anyway. + * + * Creates a new #GMainLoop for th default main context. + * + * Returns: a new #GMainLoop + * + * Deprecated: 2.2: Use g_main_loop_new() instead + */ +#define g_main_new(is_running) g_main_loop_new (NULL, is_running) + +/** + * g_main_run: + * @loop: a #GMainLoop + * + * Runs a main loop until it stops running. + * + * Deprecated: 2.2: Use g_main_loop_run() instead + */ +#define g_main_run(loop) g_main_loop_run(loop) + +/** + * g_main_quit: + * @loop: a #GMainLoop + * + * Stops the #GMainLoop. + * If g_main_run() was called to run the #GMainLoop, it will now return. + * + * Deprecated: 2.2: Use g_main_loop_quit() instead + */ +#define g_main_quit(loop) g_main_loop_quit(loop) + +/** + * g_main_destroy: + * @loop: a #GMainLoop + * + * Frees the memory allocated for the #GMainLoop. + * + * Deprecated: 2.2: Use g_main_loop_unref() instead + */ +#define g_main_destroy(loop) g_main_loop_unref(loop) + +/** + * g_main_is_running: + * @loop: a #GMainLoop + * + * Checks if the main loop is running. + * + * Returns: %TRUE if the main loop is running + * + * Deprecated: 2.2: Use g_main_loop_is_running() instead + */ +#define g_main_is_running(loop) g_main_loop_is_running(loop) + +/** + * g_main_iteration: + * @may_block: set to %TRUE if it should block (i.e. wait) until an event + * source becomes ready. It will return after an event source has been + * processed. If set to %FALSE it will return immediately if no event + * source is ready to be processed. + * + * Runs a single iteration for the default #GMainContext. + * + * Returns: %TRUE if more events are pending. + * + * Deprecated: 2.2: Use g_main_context_iteration() instead. + */ +#define g_main_iteration(may_block) g_main_context_iteration (NULL, may_block) + +/** + * g_main_pending: + * + * Checks if any events are pending for the default #GMainContext + * (i.e. ready to be processed). + * + * Returns: %TRUE if any events are pending. + * + * Deprected: 2.2: Use g_main_context_pending() instead. + */ +#define g_main_pending() g_main_context_pending (NULL) + +/** + * g_main_set_poll_func: + * @func: the function to call to poll all file descriptors + * + * Sets the function to use for the handle polling of file descriptors + * for the default main context. + * + * Deprecated: 2.2: Use g_main_context_set_poll_func() again + */ +#define g_main_set_poll_func(func) g_main_context_set_poll_func (NULL, func) + + +G_END_DECLS + +#endif /* __G_DEPRECATED_MAIN_H__ */ diff --git a/glib/glib/deprecated/grel.c b/glib/glib/deprecated/grel.c new file mode 100644 index 0000000..a8b2c4d --- /dev/null +++ b/glib/glib/deprecated/grel.c @@ -0,0 +1,677 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include "grel.h" + +#include +#include +#include +#include +#include + +#include +#include + +/** + * SECTION:relations + * @title: Relations and Tuples + * @short_description: tables of data which can be indexed on any + * number of fields + * + * A #GRelation is a table of data which can be indexed on any number + * of fields, rather like simple database tables. A #GRelation contains + * a number of records, called tuples. Each record contains a number of + * fields. Records are not ordered, so it is not possible to find the + * record at a particular index. + * + * Note that #GRelation tables are currently limited to 2 fields. + * + * To create a GRelation, use g_relation_new(). + * + * To specify which fields should be indexed, use g_relation_index(). + * Note that this must be called before any tuples are added to the + * #GRelation. + * + * To add records to a #GRelation use g_relation_insert(). + * + * To determine if a given record appears in a #GRelation, use + * g_relation_exists(). Note that fields are compared directly, so + * pointers must point to the exact same position (i.e. different + * copies of the same string will not match.) + * + * To count the number of records which have a particular value in a + * given field, use g_relation_count(). + * + * To get all the records which have a particular value in a given + * field, use g_relation_select(). To access fields of the resulting + * records, use g_tuples_index(). To free the resulting records use + * g_tuples_destroy(). + * + * To delete all records which have a particular value in a given + * field, use g_relation_delete(). + * + * To destroy the #GRelation, use g_relation_destroy(). + * + * To help debug #GRelation objects, use g_relation_print(). + * + * GRelation has been marked as deprecated, since this API has never + * been fully implemented, is not very actively maintained and rarely + * used. + **/ + +typedef struct _GRealTuples GRealTuples; + +/** + * GRelation: + * + * The #GRelation struct is an opaque data structure to represent a + * Relation. It should + * only be accessed via the following functions. + **/ +struct _GRelation +{ + gint fields; + gint current_field; + + GHashTable *all_tuples; + GHashTable **hashed_tuple_tables; + + gint count; +}; + +/** + * GTuples: + * @len: the number of records that matched. + * + * The #GTuples struct is used to return records (or tuples) from the + * #GRelation by g_relation_select(). It only contains one public + * member - the number of records that matched. To access the matched + * records, you must use g_tuples_index(). + **/ +struct _GRealTuples +{ + gint len; + gint width; + gpointer *data; +}; + +static gboolean +tuple_equal_2 (gconstpointer v_a, + gconstpointer v_b) +{ + gpointer* a = (gpointer*) v_a; + gpointer* b = (gpointer*) v_b; + + return a[0] == b[0] && a[1] == b[1]; +} + +static guint +tuple_hash_2 (gconstpointer v_a) +{ +#if GLIB_SIZEOF_VOID_P > GLIB_SIZEOF_LONG + /* In practise this snippet has been written for 64-bit Windows + * where ints are 32 bits, pointers 64 bits. More exotic platforms + * need more tweaks. + */ + guint* a = (guint*) v_a; + + return (a[0] ^ a[1] ^ a[2] ^ a[3]); +#else + gpointer* a = (gpointer*) v_a; + + return (gulong)a[0] ^ (gulong)a[1]; +#endif +} + +static GHashFunc +tuple_hash (gint fields) +{ + switch (fields) + { + case 2: + return tuple_hash_2; + default: + g_error ("no tuple hash for %d", fields); + } + + return NULL; +} + +static GEqualFunc +tuple_equal (gint fields) +{ + switch (fields) + { + case 2: + return tuple_equal_2; + default: + g_error ("no tuple equal for %d", fields); + } + + return NULL; +} + +/** + * g_relation_new: + * @fields: the number of fields. + * @Returns: a new #GRelation. + * + * Creates a new #GRelation with the given number of fields. Note that + * currently the number of fields must be 2. + * + * Deprecated: 2.26: Rarely used API + **/ +GRelation* +g_relation_new (gint fields) +{ + GRelation* rel = g_new0 (GRelation, 1); + + rel->fields = fields; + rel->all_tuples = g_hash_table_new (tuple_hash (fields), tuple_equal (fields)); + rel->hashed_tuple_tables = g_new0 (GHashTable*, fields); + + return rel; +} + +static void +relation_delete_value_tuple (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + GRelation *relation = user_data; + gpointer *tuple = tuple_value; + g_slice_free1 (relation->fields * sizeof (gpointer), tuple); +} + +static void +g_relation_free_array (gpointer key, gpointer value, gpointer user_data) +{ + g_hash_table_destroy ((GHashTable*) value); +} + +/** + * g_relation_destroy: + * @relation: a #GRelation. + * + * Destroys the #GRelation, freeing all memory allocated. However, it + * does not free memory allocated for the tuple data, so you should + * free that first if appropriate. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_relation_destroy (GRelation *relation) +{ + gint i; + + if (relation) + { + for (i = 0; i < relation->fields; i += 1) + { + if (relation->hashed_tuple_tables[i]) + { + g_hash_table_foreach (relation->hashed_tuple_tables[i], g_relation_free_array, NULL); + g_hash_table_destroy (relation->hashed_tuple_tables[i]); + } + } + + g_hash_table_foreach (relation->all_tuples, relation_delete_value_tuple, relation); + g_hash_table_destroy (relation->all_tuples); + + g_free (relation->hashed_tuple_tables); + g_free (relation); + } +} + +/** + * g_relation_index: + * @relation: a #GRelation. + * @field: the field to index, counting from 0. + * @hash_func: a function to produce a hash value from the field data. + * @key_equal_func: a function to compare two values of the given field. + * + * Creates an index on the given field. Note that this must be called + * before any records are added to the #GRelation. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_relation_index (GRelation *relation, + gint field, + GHashFunc hash_func, + GEqualFunc key_equal_func) +{ + g_return_if_fail (relation != NULL); + + g_return_if_fail (relation->count == 0 && relation->hashed_tuple_tables[field] == NULL); + + relation->hashed_tuple_tables[field] = g_hash_table_new (hash_func, key_equal_func); +} + +/** + * g_relation_insert: + * @relation: a #GRelation. + * @...: the fields of the record to add. These must match the + * number of fields in the #GRelation, and of type #gpointer + * or #gconstpointer. + * + * Inserts a record into a #GRelation. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_relation_insert (GRelation *relation, + ...) +{ + gpointer* tuple = g_slice_alloc (relation->fields * sizeof (gpointer)); + va_list args; + gint i; + + va_start (args, relation); + + for (i = 0; i < relation->fields; i += 1) + tuple[i] = va_arg (args, gpointer); + + va_end (args); + + g_hash_table_insert (relation->all_tuples, tuple, tuple); + + relation->count += 1; + + for (i = 0; i < relation->fields; i += 1) + { + GHashTable *table; + gpointer key; + GHashTable *per_key_table; + + table = relation->hashed_tuple_tables[i]; + + if (table == NULL) + continue; + + key = tuple[i]; + per_key_table = g_hash_table_lookup (table, key); + + if (per_key_table == NULL) + { + per_key_table = g_hash_table_new (tuple_hash (relation->fields), tuple_equal (relation->fields)); + g_hash_table_insert (table, key, per_key_table); + } + + g_hash_table_insert (per_key_table, tuple, tuple); + } +} + +static void +g_relation_delete_tuple (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + gpointer *tuple = (gpointer*) tuple_value; + GRelation *relation = (GRelation *) user_data; + gint j; + + g_assert (tuple_key == tuple_value); + + for (j = 0; j < relation->fields; j += 1) + { + GHashTable *one_table = relation->hashed_tuple_tables[j]; + gpointer one_key; + GHashTable *per_key_table; + + if (one_table == NULL) + continue; + + if (j == relation->current_field) + /* can't delete from the table we're foreaching in */ + continue; + + one_key = tuple[j]; + + per_key_table = g_hash_table_lookup (one_table, one_key); + + g_hash_table_remove (per_key_table, tuple); + } + + if (g_hash_table_remove (relation->all_tuples, tuple)) + g_slice_free1 (relation->fields * sizeof (gpointer), tuple); + + relation->count -= 1; +} + +/** + * g_relation_delete: + * @relation: a #GRelation. + * @key: the value to compare with. + * @field: the field of each record to match. + * @Returns: the number of records deleted. + * + * Deletes any records from a #GRelation that have the given key value + * in the given field. + * + * Deprecated: 2.26: Rarely used API + **/ +gint +g_relation_delete (GRelation *relation, + gconstpointer key, + gint field) +{ + GHashTable *table; + GHashTable *key_table; + gint count; + + g_return_val_if_fail (relation != NULL, 0); + + table = relation->hashed_tuple_tables[field]; + count = relation->count; + + g_return_val_if_fail (table != NULL, 0); + + key_table = g_hash_table_lookup (table, key); + + if (!key_table) + return 0; + + relation->current_field = field; + + g_hash_table_foreach (key_table, g_relation_delete_tuple, relation); + + g_hash_table_remove (table, key); + + g_hash_table_destroy (key_table); + + /* @@@ FIXME: Remove empty hash tables. */ + + return count - relation->count; +} + +static void +g_relation_select_tuple (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + gpointer *tuple = (gpointer*) tuple_value; + GRealTuples *tuples = (GRealTuples*) user_data; + gint stride = sizeof (gpointer) * tuples->width; + + g_assert (tuple_key == tuple_value); + + memcpy (tuples->data + (tuples->len * tuples->width), + tuple, + stride); + + tuples->len += 1; +} + +/** + * g_relation_select: + * @relation: a #GRelation. + * @key: the value to compare with. + * @field: the field of each record to match. + * @Returns: the records (tuples) that matched. + * + * Returns all of the tuples which have the given key in the given + * field. Use g_tuples_index() to access the returned records. The + * returned records should be freed with g_tuples_destroy(). + * + * Deprecated: 2.26: Rarely used API + **/ +GTuples* +g_relation_select (GRelation *relation, + gconstpointer key, + gint field) +{ + GHashTable *table; + GHashTable *key_table; + GRealTuples *tuples; + gint count; + + g_return_val_if_fail (relation != NULL, NULL); + + table = relation->hashed_tuple_tables[field]; + + g_return_val_if_fail (table != NULL, NULL); + + tuples = g_new0 (GRealTuples, 1); + key_table = g_hash_table_lookup (table, key); + + if (!key_table) + return (GTuples*)tuples; + + count = g_relation_count (relation, key, field); + + tuples->data = g_malloc (sizeof (gpointer) * relation->fields * count); + tuples->width = relation->fields; + + g_hash_table_foreach (key_table, g_relation_select_tuple, tuples); + + g_assert (count == tuples->len); + + return (GTuples*)tuples; +} + +/** + * g_relation_count: + * @relation: a #GRelation. + * @key: the value to compare with. + * @field: the field of each record to match. + * @Returns: the number of matches. + * + * Returns the number of tuples in a #GRelation that have the given + * value in the given field. + * + * Deprecated: 2.26: Rarely used API + **/ +gint +g_relation_count (GRelation *relation, + gconstpointer key, + gint field) +{ + GHashTable *table; + GHashTable *key_table; + + g_return_val_if_fail (relation != NULL, 0); + + table = relation->hashed_tuple_tables[field]; + + g_return_val_if_fail (table != NULL, 0); + + key_table = g_hash_table_lookup (table, key); + + if (!key_table) + return 0; + + return g_hash_table_size (key_table); +} + +/** + * g_relation_exists: + * @relation: a #GRelation. + * @...: the fields of the record to compare. The number must match + * the number of fields in the #GRelation. + * @Returns: %TRUE if a record matches. + * + * Returns %TRUE if a record with the given values exists in a + * #GRelation. Note that the values are compared directly, so that, for + * example, two copies of the same string will not match. + * + * Deprecated: 2.26: Rarely used API + **/ +gboolean +g_relation_exists (GRelation *relation, ...) +{ + gpointer *tuple = g_slice_alloc (relation->fields * sizeof (gpointer)); + va_list args; + gint i; + gboolean result; + + va_start(args, relation); + + for (i = 0; i < relation->fields; i += 1) + tuple[i] = va_arg(args, gpointer); + + va_end(args); + + result = g_hash_table_lookup (relation->all_tuples, tuple) != NULL; + + g_slice_free1 (relation->fields * sizeof (gpointer), tuple); + + return result; +} + +/** + * g_tuples_destroy: + * @tuples: the tuple data to free. + * + * Frees the records which were returned by g_relation_select(). This + * should always be called after g_relation_select() when you are + * finished with the records. The records are not removed from the + * #GRelation. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_tuples_destroy (GTuples *tuples0) +{ + GRealTuples *tuples = (GRealTuples*) tuples0; + + if (tuples) + { + g_free (tuples->data); + g_free (tuples); + } +} + +/** + * g_tuples_index: + * @tuples: the tuple data, returned by g_relation_select(). + * @index_: the index of the record. + * @field: the field to return. + * @Returns: the field of the record. + * + * Gets a field from the records returned by g_relation_select(). It + * returns the given field of the record at the given index. The + * returned value should not be changed. + * + * Deprecated: 2.26: Rarely used API + **/ +gpointer +g_tuples_index (GTuples *tuples0, + gint index, + gint field) +{ + GRealTuples *tuples = (GRealTuples*) tuples0; + + g_return_val_if_fail (tuples0 != NULL, NULL); + g_return_val_if_fail (field < tuples->width, NULL); + + return tuples->data[index * tuples->width + field]; +} + +/* Print + */ + +static void +g_relation_print_one (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + gint i; + GString *gstring; + GRelation* rel = (GRelation*) user_data; + gpointer* tuples = (gpointer*) tuple_value; + + gstring = g_string_new ("["); + + for (i = 0; i < rel->fields; i += 1) + { + g_string_append_printf (gstring, "%p", tuples[i]); + + if (i < (rel->fields - 1)) + g_string_append (gstring, ","); + } + + g_string_append (gstring, "]"); + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "%s", gstring->str); + g_string_free (gstring, TRUE); +} + +static void +g_relation_print_index (gpointer tuple_key, + gpointer tuple_value, + gpointer user_data) +{ + GRelation* rel = (GRelation*) user_data; + GHashTable* table = (GHashTable*) tuple_value; + + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** key %p", tuple_key); + + g_hash_table_foreach (table, + g_relation_print_one, + rel); +} + +/** + * g_relation_print: + * @relation: a #GRelation. + * + * Outputs information about all records in a #GRelation, as well as + * the indexes. It is for debugging. + * + * Deprecated: 2.26: Rarely used API + **/ +void +g_relation_print (GRelation *relation) +{ + gint i; + + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** all tuples (%d)", relation->count); + + g_hash_table_foreach (relation->all_tuples, + g_relation_print_one, + relation); + + for (i = 0; i < relation->fields; i += 1) + { + if (relation->hashed_tuple_tables[i] == NULL) + continue; + + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** index %d", i); + + g_hash_table_foreach (relation->hashed_tuple_tables[i], + g_relation_print_index, + relation); + } + +} diff --git a/glib/glib/deprecated/grel.h b/glib/glib/deprecated/grel.h new file mode 100644 index 0000000..c9e0996 --- /dev/null +++ b/glib/glib/deprecated/grel.h @@ -0,0 +1,107 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_REL_H__ +#define __G_REL_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GRelation GRelation; +typedef struct _GTuples GTuples; + +struct _GTuples +{ + guint len; +}; + +/* GRelation + * + * Indexed Relations. Imagine a really simple table in a + * database. Relations are not ordered. This data type is meant for + * maintaining a N-way mapping. + * + * g_relation_new() creates a relation with FIELDS fields + * + * g_relation_destroy() frees all resources + * g_tuples_destroy() frees the result of g_relation_select() + * + * g_relation_index() indexes relation FIELD with the provided + * equality and hash functions. this must be done before any + * calls to insert are made. + * + * g_relation_insert() inserts a new tuple. you are expected to + * provide the right number of fields. + * + * g_relation_delete() deletes all relations with KEY in FIELD + * g_relation_select() returns ... + * g_relation_count() counts ... + */ + +GLIB_DEPRECATED_IN_2_26 +GRelation* g_relation_new (gint fields); +GLIB_DEPRECATED_IN_2_26 +void g_relation_destroy (GRelation *relation); +GLIB_DEPRECATED_IN_2_26 +void g_relation_index (GRelation *relation, + gint field, + GHashFunc hash_func, + GEqualFunc key_equal_func); +GLIB_DEPRECATED_IN_2_26 +void g_relation_insert (GRelation *relation, + ...); +GLIB_DEPRECATED_IN_2_26 +gint g_relation_delete (GRelation *relation, + gconstpointer key, + gint field); +GLIB_DEPRECATED_IN_2_26 +GTuples* g_relation_select (GRelation *relation, + gconstpointer key, + gint field); +GLIB_DEPRECATED_IN_2_26 +gint g_relation_count (GRelation *relation, + gconstpointer key, + gint field); +GLIB_DEPRECATED_IN_2_26 +gboolean g_relation_exists (GRelation *relation, + ...); +GLIB_DEPRECATED_IN_2_26 +void g_relation_print (GRelation *relation); +GLIB_DEPRECATED_IN_2_26 +void g_tuples_destroy (GTuples *tuples); +GLIB_DEPRECATED_IN_2_26 +gpointer g_tuples_index (GTuples *tuples, + gint index_, + gint field); + +G_END_DECLS + +#endif /* __G_REL_H__ */ diff --git a/glib/glib/deprecated/gthread-deprecated.c b/glib/glib/deprecated/gthread-deprecated.c new file mode 100644 index 0000000..a3cba18 --- /dev/null +++ b/glib/glib/deprecated/gthread-deprecated.c @@ -0,0 +1,1592 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: MT safety related functions + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * Owen Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +/* we know we are deprecated here, no need for warnings */ +#define GLIB_DISABLE_DEPRECATION_WARNINGS + +#include "gmessages.h" +#include "gslice.h" +#include "gmain.h" +#include "gthread.h" +#include "gthreadprivate.h" +#include "deprecated/gthread.h" +#include "garray.h" + +#include "gutils.h" + +/* {{{1 Documentation */ + +/** + * SECTION:threads-deprecated + * @title: Deprecated thread API + * @short_description: old thread APIs (for reference only) + * @see_also: #GThread + * + * These APIs are deprecated. You should not use them in new code. + * This section remains only to assist with understanding code that was + * written to use these APIs at some point in the past. + **/ + +/** + * GThreadPriority: + * @G_THREAD_PRIORITY_LOW: a priority lower than normal + * @G_THREAD_PRIORITY_NORMAL: the default priority + * @G_THREAD_PRIORITY_HIGH: a priority higher than normal + * @G_THREAD_PRIORITY_URGENT: the highest priority + * + * Deprecated:2.32: Thread priorities no longer have any effect. + */ + +/** + * GThreadFunctions: + * @mutex_new: virtual function pointer for g_mutex_new() + * @mutex_lock: virtual function pointer for g_mutex_lock() + * @mutex_trylock: virtual function pointer for g_mutex_trylock() + * @mutex_unlock: virtual function pointer for g_mutex_unlock() + * @mutex_free: virtual function pointer for g_mutex_free() + * @cond_new: virtual function pointer for g_cond_new() + * @cond_signal: virtual function pointer for g_cond_signal() + * @cond_broadcast: virtual function pointer for g_cond_broadcast() + * @cond_wait: virtual function pointer for g_cond_wait() + * @cond_timed_wait: virtual function pointer for g_cond_timed_wait() + * @cond_free: virtual function pointer for g_cond_free() + * @private_new: virtual function pointer for g_private_new() + * @private_get: virtual function pointer for g_private_get() + * @private_set: virtual function pointer for g_private_set() + * @thread_create: virtual function pointer for g_thread_create() + * @thread_yield: virtual function pointer for g_thread_yield() + * @thread_join: virtual function pointer for g_thread_join() + * @thread_exit: virtual function pointer for g_thread_exit() + * @thread_set_priority: virtual function pointer for + * g_thread_set_priority() + * @thread_self: virtual function pointer for g_thread_self() + * @thread_equal: used internally by recursive mutex locks and by some + * assertion checks + * + * This function table is no longer used by g_thread_init() + * to initialize the thread system. + */ + +/** + * G_THREADS_IMPL_POSIX: + * + * This macro is defined if POSIX style threads are used. + * + * Deprecated:2.32:POSIX threads are in use on all non-Windows systems. + * Use G_OS_WIN32 to detect Windows. + */ + +/** + * G_THREADS_IMPL_WIN32: + * + * This macro is defined if Windows style threads are used. + * + * Deprecated:2.32:Use G_OS_WIN32 to detect Windows. + */ + + +/* {{{1 Exported Variables */ + +/* Set this FALSE to have previously-compiled GStaticMutex code use the + * slow path (ie: call into us) to avoid compatibility problems. + */ +gboolean g_thread_use_default_impl = FALSE; + +GThreadFunctions g_thread_functions_for_glib_use = +{ + g_mutex_new, + g_mutex_lock, + g_mutex_trylock, + g_mutex_unlock, + g_mutex_free, + g_cond_new, + g_cond_signal, + g_cond_broadcast, + g_cond_wait, + g_cond_timed_wait, + g_cond_free, + g_private_new, + g_private_get, + g_private_set, + NULL, + g_thread_yield, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +static guint64 +gettime (void) +{ + return g_get_monotonic_time () * 1000; +} + +guint64 (*g_thread_gettime) (void) = gettime; + +/* Initialisation {{{1 ---------------------------------------------------- */ +gboolean g_threads_got_initialized = TRUE; + +/** + * g_thread_init: + * @vtable: a function table of type #GThreadFunctions, that provides + * the entry points to the thread system to be used. Since 2.32, + * this parameter is ignored and should always be %NULL + * + * If you use GLib from more than one thread, you must initialize the + * thread system by calling g_thread_init(). + * + * Since version 2.24, calling g_thread_init() multiple times is allowed, + * but nothing happens except for the first call. + * + * Since version 2.32, GLib does not support custom thread implementations + * anymore and the @vtable parameter is ignored and you should pass %NULL. + * + * g_thread_init() must not be called directly or indirectly + * in a callback from GLib. Also no mutexes may be currently locked while + * calling g_thread_init(). + * + * To use g_thread_init() in your program, you have to link + * with the libraries that the command pkg-config --libs + * gthread-2.0 outputs. This is not the case for all the + * other thread-related functions of GLib. Those can be used without + * having to link with the thread libraries. + * + * Deprecated:2.32: This function is no longer necessary. The GLib + * threading system is automatically initialized at the start + * of your program. + */ + +/** + * g_thread_get_initialized: + * + * Indicates if g_thread_init() has been called. + * + * Returns: %TRUE if threads have been initialized. + * + * Since: 2.20 + */ +gboolean +g_thread_get_initialized (void) +{ + return g_thread_supported (); +} + +/* We need this for ABI compatibility */ +void g_thread_init_glib (void); +void g_thread_init_glib (void) { } + +/* Internal variables {{{1 */ + +static GSList *g_thread_all_threads = NULL; +static GSList *g_thread_free_indices = NULL; + +/* Protects g_thread_all_threads and g_thread_free_indices */ +G_LOCK_DEFINE_STATIC (g_static_mutex); +G_LOCK_DEFINE_STATIC (g_thread); + +/* Misc. GThread functions {{{1 */ + +/** + * g_thread_set_priority: + * @thread: a #GThread. + * @priority: ignored + * + * This function does nothing. + * + * Deprecated:2.32: Thread priorities no longer have any effect. + */ +void +g_thread_set_priority (GThread *thread, + GThreadPriority priority) +{ +} + +/** + * g_thread_foreach: + * @thread_func: function to call for all #GThread structures + * @user_data: second argument to @thread_func + * + * Call @thread_func on all #GThreads that have been + * created with g_thread_create(). + * + * Note that threads may decide to exit while @thread_func is + * running, so without intimate knowledge about the lifetime of + * foreign threads, @thread_func shouldn't access the GThread* + * pointer passed in as first argument. However, @thread_func will + * not be called for threads which are known to have exited already. + * + * Due to thread lifetime checks, this function has an execution complexity + * which is quadratic in the number of existing threads. + * + * Since: 2.10 + * + * Deprecated:2.32: There aren't many things you can do with a #GThread, + * except comparing it with one that was returned from g_thread_create(). + * There are better ways to find out if your thread is still alive. + */ +void +g_thread_foreach (GFunc thread_func, + gpointer user_data) +{ + GSList *slist = NULL; + GRealThread *thread; + g_return_if_fail (thread_func != NULL); + /* snapshot the list of threads for iteration */ + G_LOCK (g_thread); + slist = g_slist_copy (g_thread_all_threads); + G_UNLOCK (g_thread); + /* walk the list, skipping non-existent threads */ + while (slist) + { + GSList *node = slist; + slist = node->next; + /* check whether the current thread still exists */ + G_LOCK (g_thread); + if (g_slist_find (g_thread_all_threads, node->data)) + thread = node->data; + else + thread = NULL; + G_UNLOCK (g_thread); + if (thread) + thread_func (thread, user_data); + g_slist_free_1 (node); + } +} + +static void +g_enumerable_thread_remove (gpointer data) +{ + GRealThread *thread = data; + + G_LOCK (g_thread); + g_thread_all_threads = g_slist_remove (g_thread_all_threads, thread); + G_UNLOCK (g_thread); +} + +GPrivate enumerable_thread_private = G_PRIVATE_INIT (g_enumerable_thread_remove); + +static void +g_enumerable_thread_add (GRealThread *thread) +{ + G_LOCK (g_thread); + g_thread_all_threads = g_slist_prepend (g_thread_all_threads, thread); + G_UNLOCK (g_thread); + + g_private_set (&enumerable_thread_private, thread); +} + +static gpointer +g_deprecated_thread_proxy (gpointer data) +{ + GRealThread *real = data; + + g_enumerable_thread_add (real); + + return g_thread_proxy (data); +} + +/** + * g_thread_create: + * @func: a function to execute in the new thread + * @data: an argument to supply to the new thread + * @joinable: should this thread be joinable? + * @error: return location for error, or %NULL + * + * This function creates a new thread. + * + * The new thread executes the function @func with the argument @data. + * If the thread was created successfully, it is returned. + * + * @error can be %NULL to ignore errors, or non-%NULL to report errors. + * The error is set, if and only if the function returns %NULL. + * + * This function returns a reference to the created thread only if + * @joinable is %TRUE. In that case, you must free this reference by + * calling g_thread_unref() or g_thread_join(). If @joinable is %FALSE + * then you should probably not touch the return value. + * + * Returns: the new #GThread on success + * + * Deprecated:2.32: Use g_thread_new() instead + */ +GThread * +g_thread_create (GThreadFunc func, + gpointer data, + gboolean joinable, + GError **error) +{ + return g_thread_create_full (func, data, 0, joinable, 0, 0, error); +} + +/** + * g_thread_create_full: + * @func: a function to execute in the new thread. + * @data: an argument to supply to the new thread. + * @stack_size: a stack size for the new thread. + * @joinable: should this thread be joinable? + * @bound: ignored + * @priority: ignored + * @error: return location for error. + * @Returns: the new #GThread on success. + * + * This function creates a new thread. + * + * Deprecated:2.32: The @bound and @priority arguments are now ignored. + * Use g_thread_new(). + */ +GThread * +g_thread_create_full (GThreadFunc func, + gpointer data, + gulong stack_size, + gboolean joinable, + gboolean bound, + GThreadPriority priority, + GError **error) +{ + GThread *thread; + + thread = g_thread_new_internal (NULL, g_deprecated_thread_proxy, + func, data, stack_size, error); + + if (!joinable) + { + thread->joinable = FALSE; + g_thread_unref (thread); + } + + return thread; +} + +/* GOnce {{{1 ------------------------------------------------------------- */ +gboolean +g_once_init_enter_impl (volatile gsize *location) +{ + return (g_once_init_enter) (location); +} + +/* GStaticMutex {{{1 ------------------------------------------------------ */ + +/** + * GStaticMutex: + * + * A #GStaticMutex works like a #GMutex. + * + * Prior to GLib 2.32, GStaticMutex had the significant advantage + * that it doesn't need to be created at run-time, but can be defined + * at compile-time. Since 2.32, #GMutex can be statically allocated + * as well, and GStaticMutex has been deprecated. + * + * Here is a version of our give_me_next_number() example using + * a GStaticMutex. + * + * + * + * Using <structname>GStaticMutex</structname> + * to simplify thread-safe programming + * + * + * int + * give_me_next_number (void) + * { + * static int current_number = 0; + * int ret_val; + * static GStaticMutex mutex = G_STATIC_MUTEX_INIT; + * + * g_static_mutex_lock (&mutex); + * ret_val = current_number = calc_next_number (current_number); + * g_static_mutex_unlock (&mutex); + * + * return ret_val; + * } + * + * + * + * Sometimes you would like to dynamically create a mutex. If you don't + * want to require prior calling to g_thread_init(), because your code + * should also be usable in non-threaded programs, you are not able to + * use g_mutex_new() and thus #GMutex, as that requires a prior call to + * g_thread_init(). In theses cases you can also use a #GStaticMutex. + * It must be initialized with g_static_mutex_init() before using it + * and freed with with g_static_mutex_free() when not needed anymore to + * free up any allocated resources. + * + * Even though #GStaticMutex is not opaque, it should only be used with + * the following functions, as it is defined differently on different + * platforms. + * + * All of the g_static_mutex_* functions apart + * from g_static_mutex_get_mutex can also be used + * even if g_thread_init() has not yet been called. Then they do + * nothing, apart from g_static_mutex_trylock, + * which does nothing but returning %TRUE. + * + * All of the g_static_mutex_* + * functions are actually macros. Apart from taking their addresses, you + * can however use them as if they were functions. + **/ + +/** + * G_STATIC_MUTEX_INIT: + * + * A #GStaticMutex must be initialized with this macro, before it can + * be used. This macro can used be to initialize a variable, but it + * cannot be assigned to a variable. In that case you have to use + * g_static_mutex_init(). + * + * |[ + * GStaticMutex my_mutex = G_STATIC_MUTEX_INIT; + * ]| + **/ + +/** + * g_static_mutex_init: + * @mutex: a #GStaticMutex to be initialized. + * + * Initializes @mutex. + * Alternatively you can initialize it with #G_STATIC_MUTEX_INIT. + * + * Deprecated: 2.32: Use g_mutex_init() + */ +void +g_static_mutex_init (GStaticMutex *mutex) +{ + static const GStaticMutex init_mutex = G_STATIC_MUTEX_INIT; + + g_return_if_fail (mutex); + + *mutex = init_mutex; +} + +/* IMPLEMENTATION NOTE: + * + * On some platforms a GStaticMutex is actually a normal GMutex stored + * inside of a structure instead of being allocated dynamically. We can + * only do this for platforms on which we know, in advance, how to + * allocate (size) and initialise (value) that memory. + * + * On other platforms, a GStaticMutex is nothing more than a pointer to + * a GMutex. In that case, the first access we make to the static mutex + * must first allocate the normal GMutex and store it into the pointer. + * + * configure.ac writes macros into glibconfig.h to determine if + * g_static_mutex_get_mutex() accesses the structure in memory directly + * (on platforms where we are able to do that) or if it ends up here, + * where we may have to allocate the GMutex before returning it. + */ + +/** + * g_static_mutex_get_mutex: + * @mutex: a #GStaticMutex. + * @Returns: the #GMutex corresponding to @mutex. + * + * For some operations (like g_cond_wait()) you must have a #GMutex + * instead of a #GStaticMutex. This function will return the + * corresponding #GMutex for @mutex. + * + * Deprecated: 2.32: Just use a #GMutex + */ +GMutex * +g_static_mutex_get_mutex_impl (GStaticMutex* mutex) +{ + GMutex *result; + + if (!g_thread_supported ()) + return NULL; + + result = g_atomic_pointer_get (&mutex->mutex); + + if (!result) + { + G_LOCK (g_static_mutex); + + result = mutex->mutex; + if (!result) + { + result = g_mutex_new (); + g_atomic_pointer_set (&mutex->mutex, result); + } + + G_UNLOCK (g_static_mutex); + } + + return result; +} + +/* IMPLEMENTATION NOTE: + * + * g_static_mutex_lock(), g_static_mutex_trylock() and + * g_static_mutex_unlock() are all preprocessor macros that wrap the + * corresponding g_mutex_*() function around a call to + * g_static_mutex_get_mutex(). + */ + +/** + * g_static_mutex_lock: + * @mutex: a #GStaticMutex. + * + * Works like g_mutex_lock(), but for a #GStaticMutex. + * + * Deprecated: 2.32: Use g_mutex_lock() + */ + +/** + * g_static_mutex_trylock: + * @mutex: a #GStaticMutex. + * @Returns: %TRUE, if the #GStaticMutex could be locked. + * + * Works like g_mutex_trylock(), but for a #GStaticMutex. + * + * Deprecated: 2.32: Use g_mutex_trylock() + */ + +/** + * g_static_mutex_unlock: + * @mutex: a #GStaticMutex. + * + * Works like g_mutex_unlock(), but for a #GStaticMutex. + * + * Deprecated: 2.32: Use g_mutex_unlock() + */ + +/** + * g_static_mutex_free: + * @mutex: a #GStaticMutex to be freed. + * + * Releases all resources allocated to @mutex. + * + * You don't have to call this functions for a #GStaticMutex with an + * unbounded lifetime, i.e. objects declared 'static', but if you have + * a #GStaticMutex as a member of a structure and the structure is + * freed, you should also free the #GStaticMutex. + * + * Calling g_static_mutex_free() on a locked mutex may + * result in undefined behaviour. + * + * Deprecated: 2.32: Use g_mutex_free() + */ +void +g_static_mutex_free (GStaticMutex* mutex) +{ + GMutex **runtime_mutex; + + g_return_if_fail (mutex); + + /* The runtime_mutex is the first (or only) member of GStaticMutex, + * see both versions (of glibconfig.h) in configure.ac. Note, that + * this variable is NULL, if g_thread_init() hasn't been called or + * if we're using the default thread implementation and it provides + * static mutexes. */ + runtime_mutex = ((GMutex**)mutex); + + if (*runtime_mutex) + g_mutex_free (*runtime_mutex); + + *runtime_mutex = NULL; +} + +/* {{{1 GStaticRecMutex */ + +/** + * GStaticRecMutex: + * + * A #GStaticRecMutex works like a #GStaticMutex, but it can be locked + * multiple times by one thread. If you enter it n times, you have to + * unlock it n times again to let other threads lock it. An exception + * is the function g_static_rec_mutex_unlock_full(): that allows you to + * unlock a #GStaticRecMutex completely returning the depth, (i.e. the + * number of times this mutex was locked). The depth can later be used + * to restore the state of the #GStaticRecMutex by calling + * g_static_rec_mutex_lock_full(). In GLib 2.32, #GStaticRecMutex has + * been deprecated in favor of #GRecMutex. + * + * Even though #GStaticRecMutex is not opaque, it should only be used + * with the following functions. + * + * All of the g_static_rec_mutex_* functions can + * be used even if g_thread_init() has not been called. Then they do + * nothing, apart from g_static_rec_mutex_trylock, + * which does nothing but returning %TRUE. + **/ + +/** + * G_STATIC_REC_MUTEX_INIT: + * + * A #GStaticRecMutex must be initialized with this macro before it can + * be used. This macro can used be to initialize a variable, but it + * cannot be assigned to a variable. In that case you have to use + * g_static_rec_mutex_init(). + * + * |[ + * GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT; + * ]| + */ + +/** + * g_static_rec_mutex_init: + * @mutex: a #GStaticRecMutex to be initialized. + * + * A #GStaticRecMutex must be initialized with this function before it + * can be used. Alternatively you can initialize it with + * #G_STATIC_REC_MUTEX_INIT. + * + * Deprecated: 2.32: Use g_rec_mutex_init() + */ +void +g_static_rec_mutex_init (GStaticRecMutex *mutex) +{ + static const GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT; + + g_return_if_fail (mutex); + + *mutex = init_mutex; +} + +static GRecMutex * +g_static_rec_mutex_get_rec_mutex_impl (GStaticRecMutex* mutex) +{ + GRecMutex *result; + + if (!g_thread_supported ()) + return NULL; + + result = g_atomic_pointer_get (&mutex->mutex.mutex); + + if (!result) + { + G_LOCK (g_static_mutex); + + result = (GRecMutex *) mutex->mutex.mutex; + if (!result) + { + result = g_slice_new (GRecMutex); + g_rec_mutex_init (result); + g_atomic_pointer_set (&mutex->mutex.mutex, result); + } + + G_UNLOCK (g_static_mutex); + } + + return result; +} + +/** + * g_static_rec_mutex_lock: + * @mutex: a #GStaticRecMutex to lock. + * + * Locks @mutex. If @mutex is already locked by another thread, the + * current thread will block until @mutex is unlocked by the other + * thread. If @mutex is already locked by the calling thread, this + * functions increases the depth of @mutex and returns immediately. + * + * Deprecated: 2.32: Use g_rec_mutex_lock() + */ +void +g_static_rec_mutex_lock (GStaticRecMutex* mutex) +{ + GRecMutex *rm; + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + g_rec_mutex_lock (rm); + mutex->depth++; +} + +/** + * g_static_rec_mutex_trylock: + * @mutex: a #GStaticRecMutex to lock. + * @Returns: %TRUE, if @mutex could be locked. + * + * Tries to lock @mutex. If @mutex is already locked by another thread, + * it immediately returns %FALSE. Otherwise it locks @mutex and returns + * %TRUE. If @mutex is already locked by the calling thread, this + * functions increases the depth of @mutex and immediately returns + * %TRUE. + * + * Deprecated: 2.32: Use g_rec_mutex_trylock() + */ +gboolean +g_static_rec_mutex_trylock (GStaticRecMutex* mutex) +{ + GRecMutex *rm; + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + + if (g_rec_mutex_trylock (rm)) + { + mutex->depth++; + return TRUE; + } + else + return FALSE; +} + +/** + * g_static_rec_mutex_unlock: + * @mutex: a #GStaticRecMutex to unlock. + * + * Unlocks @mutex. Another thread will be allowed to lock @mutex only + * when it has been unlocked as many times as it had been locked + * before. If @mutex is completely unlocked and another thread is + * blocked in a g_static_rec_mutex_lock() call for @mutex, it will be + * woken and can lock @mutex itself. + * + * Deprecated: 2.32: Use g_rec_mutex_unlock() + */ +void +g_static_rec_mutex_unlock (GStaticRecMutex* mutex) +{ + GRecMutex *rm; + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + mutex->depth--; + g_rec_mutex_unlock (rm); +} + +/** + * g_static_rec_mutex_lock_full: + * @mutex: a #GStaticRecMutex to lock. + * @depth: number of times this mutex has to be unlocked to be + * completely unlocked. + * + * Works like calling g_static_rec_mutex_lock() for @mutex @depth times. + * + * Deprecated: 2.32: Use g_rec_mutex_lock() + */ +void +g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, + guint depth) +{ + GRecMutex *rm; + + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + while (depth--) + { + g_rec_mutex_lock (rm); + mutex->depth++; + } +} + +/** + * g_static_rec_mutex_unlock_full: + * @mutex: a #GStaticRecMutex to completely unlock. + * @Returns: number of times @mutex has been locked by the current + * thread. + * + * Completely unlocks @mutex. If another thread is blocked in a + * g_static_rec_mutex_lock() call for @mutex, it will be woken and can + * lock @mutex itself. This function returns the number of times that + * @mutex has been locked by the current thread. To restore the state + * before the call to g_static_rec_mutex_unlock_full() you can call + * g_static_rec_mutex_lock_full() with the depth returned by this + * function. + * + * Deprecated: 2.32: Use g_rec_mutex_unlock() + */ +guint +g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex) +{ + GRecMutex *rm; + gint depth; + gint i; + + rm = g_static_rec_mutex_get_rec_mutex_impl (mutex); + + /* all access to mutex->depth done while still holding the lock */ + depth = mutex->depth; + i = mutex->depth; + mutex->depth = 0; + + while (i--) + g_rec_mutex_unlock (rm); + + return depth; +} + +/** + * g_static_rec_mutex_free: + * @mutex: a #GStaticRecMutex to be freed. + * + * Releases all resources allocated to a #GStaticRecMutex. + * + * You don't have to call this functions for a #GStaticRecMutex with an + * unbounded lifetime, i.e. objects declared 'static', but if you have + * a #GStaticRecMutex as a member of a structure and the structure is + * freed, you should also free the #GStaticRecMutex. + * + * Deprecated: 2.32: Use g_rec_mutex_clear() + */ +void +g_static_rec_mutex_free (GStaticRecMutex *mutex) +{ + g_return_if_fail (mutex); + + if (mutex->mutex.mutex) + { + GRecMutex *rm = (GRecMutex *) mutex->mutex.mutex; + + g_rec_mutex_clear (rm); + g_slice_free (GRecMutex, rm); + } +} + +/* GStaticRWLock {{{1 ----------------------------------------------------- */ + +/** + * GStaticRWLock: + * + * The #GStaticRWLock struct represents a read-write lock. A read-write + * lock can be used for protecting data that some portions of code only + * read from, while others also write. In such situations it is + * desirable that several readers can read at once, whereas of course + * only one writer may write at a time. Take a look at the following + * example: + * + * + * An array with access functions + * + * GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT; + * GPtrArray *array; + * + * gpointer + * my_array_get (guint index) + * { + * gpointer retval = NULL; + * + * if (!array) + * return NULL; + * + * g_static_rw_lock_reader_lock (&rwlock); + * if (index < array->len) + * retval = g_ptr_array_index (array, index); + * g_static_rw_lock_reader_unlock (&rwlock); + * + * return retval; + * } + * + * void + * my_array_set (guint index, gpointer data) + * { + * g_static_rw_lock_writer_lock (&rwlock); + * + * if (!array) + * array = g_ptr_array_new (); + * + * if (index >= array->len) + * g_ptr_array_set_size (array, index+1); + * g_ptr_array_index (array, index) = data; + * + * g_static_rw_lock_writer_unlock (&rwlock); + * } + * + * + * + * This example shows an array which can be accessed by many readers + * (the my_array_get() function) simultaneously, + * whereas the writers (the my_array_set() + * function) will only be allowed once at a time and only if no readers + * currently access the array. This is because of the potentially + * dangerous resizing of the array. Using these functions is fully + * multi-thread safe now. + * + * Most of the time, writers should have precedence over readers. That + * means, for this implementation, that as soon as a writer wants to + * lock the data, no other reader is allowed to lock the data, whereas, + * of course, the readers that already have locked the data are allowed + * to finish their operation. As soon as the last reader unlocks the + * data, the writer will lock it. + * + * Even though #GStaticRWLock is not opaque, it should only be used + * with the following functions. + * + * All of the g_static_rw_lock_* functions can be + * used even if g_thread_init() has not been called. Then they do + * nothing, apart from g_static_rw_lock_*_trylock, + * which does nothing but returning %TRUE. + * + * A read-write lock has a higher overhead than a mutex. For + * example, both g_static_rw_lock_reader_lock() and + * g_static_rw_lock_reader_unlock() have to lock and unlock a + * #GStaticMutex, so it takes at least twice the time to lock and unlock + * a #GStaticRWLock that it does to lock and unlock a #GStaticMutex. So + * only data structures that are accessed by multiple readers, and which + * keep the lock for a considerable time justify a #GStaticRWLock. The + * above example most probably would fare better with a + * #GStaticMutex. + * + * Deprecated: 2.32: Use a #GRWLock instead + **/ + +/** + * G_STATIC_RW_LOCK_INIT: + * + * A #GStaticRWLock must be initialized with this macro before it can + * be used. This macro can used be to initialize a variable, but it + * cannot be assigned to a variable. In that case you have to use + * g_static_rw_lock_init(). + * + * |[ + * GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT; + * ]| + */ + +/** + * g_static_rw_lock_init: + * @lock: a #GStaticRWLock to be initialized. + * + * A #GStaticRWLock must be initialized with this function before it + * can be used. Alternatively you can initialize it with + * #G_STATIC_RW_LOCK_INIT. + * + * Deprecated: 2.32: Use g_rw_lock_init() instead + */ +void +g_static_rw_lock_init (GStaticRWLock* lock) +{ + static const GStaticRWLock init_lock = G_STATIC_RW_LOCK_INIT; + + g_return_if_fail (lock); + + *lock = init_lock; +} + +inline static void +g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex) +{ + if (!*cond) + *cond = g_cond_new (); + g_cond_wait (*cond, g_static_mutex_get_mutex (mutex)); +} + +inline static void +g_static_rw_lock_signal (GStaticRWLock* lock) +{ + if (lock->want_to_write && lock->write_cond) + g_cond_signal (lock->write_cond); + else if (lock->want_to_read && lock->read_cond) + g_cond_broadcast (lock->read_cond); +} + +/** + * g_static_rw_lock_reader_lock: + * @lock: a #GStaticRWLock to lock for reading. + * + * Locks @lock for reading. There may be unlimited concurrent locks for + * reading of a #GStaticRWLock at the same time. If @lock is already + * locked for writing by another thread or if another thread is already + * waiting to lock @lock for writing, this function will block until + * @lock is unlocked by the other writing thread and no other writing + * threads want to lock @lock. This lock has to be unlocked by + * g_static_rw_lock_reader_unlock(). + * + * #GStaticRWLock is not recursive. It might seem to be possible to + * recursively lock for reading, but that can result in a deadlock, due + * to writer preference. + * + * Deprecated: 2.32: Use g_rw_lock_reader_lock() instead + */ +void +g_static_rw_lock_reader_lock (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (!g_threads_got_initialized) + return; + + g_static_mutex_lock (&lock->mutex); + lock->want_to_read++; + while (lock->have_writer || lock->want_to_write) + g_static_rw_lock_wait (&lock->read_cond, &lock->mutex); + lock->want_to_read--; + lock->read_counter++; + g_static_mutex_unlock (&lock->mutex); +} + +/** + * g_static_rw_lock_reader_trylock: + * @lock: a #GStaticRWLock to lock for reading. + * @Returns: %TRUE, if @lock could be locked for reading. + * + * Tries to lock @lock for reading. If @lock is already locked for + * writing by another thread or if another thread is already waiting to + * lock @lock for writing, immediately returns %FALSE. Otherwise locks + * @lock for reading and returns %TRUE. This lock has to be unlocked by + * g_static_rw_lock_reader_unlock(). + * + * Deprectated: 2.32: Use g_rw_lock_reader_trylock() instead + */ +gboolean +g_static_rw_lock_reader_trylock (GStaticRWLock* lock) +{ + gboolean ret_val = FALSE; + + g_return_val_if_fail (lock, FALSE); + + if (!g_threads_got_initialized) + return TRUE; + + g_static_mutex_lock (&lock->mutex); + if (!lock->have_writer && !lock->want_to_write) + { + lock->read_counter++; + ret_val = TRUE; + } + g_static_mutex_unlock (&lock->mutex); + return ret_val; +} + +/** + * g_static_rw_lock_reader_unlock: + * @lock: a #GStaticRWLock to unlock after reading. + * + * Unlocks @lock. If a thread waits to lock @lock for writing and all + * locks for reading have been unlocked, the waiting thread is woken up + * and can lock @lock for writing. + * + * Deprectated: 2.32: Use g_rw_lock_reader_unlock() instead + */ +void +g_static_rw_lock_reader_unlock (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (!g_threads_got_initialized) + return; + + g_static_mutex_lock (&lock->mutex); + lock->read_counter--; + if (lock->read_counter == 0) + g_static_rw_lock_signal (lock); + g_static_mutex_unlock (&lock->mutex); +} + +/** + * g_static_rw_lock_writer_lock: + * @lock: a #GStaticRWLock to lock for writing. + * + * Locks @lock for writing. If @lock is already locked for writing or + * reading by other threads, this function will block until @lock is + * completely unlocked and then lock @lock for writing. While this + * functions waits to lock @lock, no other thread can lock @lock for + * reading. When @lock is locked for writing, no other thread can lock + * @lock (neither for reading nor writing). This lock has to be + * unlocked by g_static_rw_lock_writer_unlock(). + * + * Deprectated: 2.32: Use g_rw_lock_writer_lock() instead + */ +void +g_static_rw_lock_writer_lock (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (!g_threads_got_initialized) + return; + + g_static_mutex_lock (&lock->mutex); + lock->want_to_write++; + while (lock->have_writer || lock->read_counter) + g_static_rw_lock_wait (&lock->write_cond, &lock->mutex); + lock->want_to_write--; + lock->have_writer = TRUE; + g_static_mutex_unlock (&lock->mutex); +} + +/** + * g_static_rw_lock_writer_trylock: + * @lock: a #GStaticRWLock to lock for writing. + * @Returns: %TRUE, if @lock could be locked for writing. + * + * Tries to lock @lock for writing. If @lock is already locked (for + * either reading or writing) by another thread, it immediately returns + * %FALSE. Otherwise it locks @lock for writing and returns %TRUE. This + * lock has to be unlocked by g_static_rw_lock_writer_unlock(). + * + * Deprectated: 2.32: Use g_rw_lock_writer_trylock() instead + */ +gboolean +g_static_rw_lock_writer_trylock (GStaticRWLock* lock) +{ + gboolean ret_val = FALSE; + + g_return_val_if_fail (lock, FALSE); + + if (!g_threads_got_initialized) + return TRUE; + + g_static_mutex_lock (&lock->mutex); + if (!lock->have_writer && !lock->read_counter) + { + lock->have_writer = TRUE; + ret_val = TRUE; + } + g_static_mutex_unlock (&lock->mutex); + return ret_val; +} + +/** + * g_static_rw_lock_writer_unlock: + * @lock: a #GStaticRWLock to unlock after writing. + * + * Unlocks @lock. If a thread is waiting to lock @lock for writing and + * all locks for reading have been unlocked, the waiting thread is + * woken up and can lock @lock for writing. If no thread is waiting to + * lock @lock for writing, and some thread or threads are waiting to + * lock @lock for reading, the waiting threads are woken up and can + * lock @lock for reading. + * + * Deprectated: 2.32: Use g_rw_lock_writer_unlock() instead + */ +void +g_static_rw_lock_writer_unlock (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (!g_threads_got_initialized) + return; + + g_static_mutex_lock (&lock->mutex); + lock->have_writer = FALSE; + g_static_rw_lock_signal (lock); + g_static_mutex_unlock (&lock->mutex); +} + +/** + * g_static_rw_lock_free: + * @lock: a #GStaticRWLock to be freed. + * + * Releases all resources allocated to @lock. + * + * You don't have to call this functions for a #GStaticRWLock with an + * unbounded lifetime, i.e. objects declared 'static', but if you have + * a #GStaticRWLock as a member of a structure, and the structure is + * freed, you should also free the #GStaticRWLock. + * + * Deprecated: 2.32: Use a #GRWLock instead + */ +void +g_static_rw_lock_free (GStaticRWLock* lock) +{ + g_return_if_fail (lock); + + if (lock->read_cond) + { + g_cond_free (lock->read_cond); + lock->read_cond = NULL; + } + if (lock->write_cond) + { + g_cond_free (lock->write_cond); + lock->write_cond = NULL; + } + g_static_mutex_free (&lock->mutex); +} + +/* GPrivate {{{1 ------------------------------------------------------ */ + +/** + * g_private_new: + * @notify: a #GDestroyNotify + * + * Creates a new #GPrivate. + * + * Deprecated:2.32: dynamic allocation of #GPrivate is a bad idea. Use + * static storage and G_PRIVATE_INIT() instead. + * + * Returns: a newly allocated #GPrivate (which can never be destroyed) + */ +GPrivate * +g_private_new (GDestroyNotify notify) +{ + GPrivate tmp = G_PRIVATE_INIT (notify); + GPrivate *key; + + key = g_slice_new (GPrivate); + *key = tmp; + + return key; +} + +/* {{{1 GStaticPrivate */ + +typedef struct _GStaticPrivateNode GStaticPrivateNode; +struct _GStaticPrivateNode +{ + gpointer data; + GDestroyNotify destroy; + GStaticPrivate *owner; +}; + +static void +g_static_private_cleanup (gpointer data) +{ + GArray *array = data; + guint i; + + for (i = 0; i < array->len; i++ ) + { + GStaticPrivateNode *node = &g_array_index (array, GStaticPrivateNode, i); + if (node->destroy) + node->destroy (node->data); + } + + g_array_free (array, TRUE); +} + +GPrivate static_private_private = G_PRIVATE_INIT (g_static_private_cleanup); + +/** + * GStaticPrivate: + * + * A #GStaticPrivate works almost like a #GPrivate, but it has one + * significant advantage. It doesn't need to be created at run-time + * like a #GPrivate, but can be defined at compile-time. This is + * similar to the difference between #GMutex and #GStaticMutex. Now + * look at our give_me_next_number() example with + * #GStaticPrivate: + * + * + * Using GStaticPrivate for per-thread data + * + * int + * give_me_next_number () + * { + * static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT; + * int *current_number = g_static_private_get (&current_number_key); + * + * if (!current_number) + * { + * current_number = g_new (int,1); + * *current_number = 0; + * g_static_private_set (&current_number_key, current_number, g_free); + * } + * + * *current_number = calc_next_number (*current_number); + * + * return *current_number; + * } + * + * + */ + +/** + * G_STATIC_PRIVATE_INIT: + * + * Every #GStaticPrivate must be initialized with this macro, before it + * can be used. + * + * |[ + * GStaticPrivate my_private = G_STATIC_PRIVATE_INIT; + * ]| + */ + +/** + * g_static_private_init: + * @private_key: a #GStaticPrivate to be initialized + * + * Initializes @private_key. Alternatively you can initialize it with + * #G_STATIC_PRIVATE_INIT. + */ +void +g_static_private_init (GStaticPrivate *private_key) +{ + private_key->index = 0; +} + +/** + * g_static_private_get: + * @private_key: a #GStaticPrivate + * + * Works like g_private_get() only for a #GStaticPrivate. + * + * This function works even if g_thread_init() has not yet been called. + * + * Returns: the corresponding pointer + */ +gpointer +g_static_private_get (GStaticPrivate *private_key) +{ + GArray *array; + gpointer ret = NULL; + + array = g_private_get (&static_private_private); + + if (array && private_key->index != 0 && private_key->index <= array->len) + { + GStaticPrivateNode *node; + + node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1); + + /* Deal with the possibility that the GStaticPrivate which used + * to have this index got freed and the index got allocated to + * a new one. In this case, the data in the node is stale, so + * free it and return NULL. + */ + if (G_UNLIKELY (node->owner != private_key)) + { + if (node->destroy) + node->destroy (node->data); + node->destroy = NULL; + node->data = NULL; + node->owner = NULL; + } + ret = node->data; + } + + return ret; +} + +/** + * g_static_private_set: + * @private_key: a #GStaticPrivate + * @data: the new pointer + * @notify: a function to be called with the pointer whenever the + * current thread ends or sets this pointer again + * + * Sets the pointer keyed to @private_key for the current thread and + * the function @notify to be called with that pointer (%NULL or + * non-%NULL), whenever the pointer is set again or whenever the + * current thread ends. + * + * This function works even if g_thread_init() has not yet been called. + * If g_thread_init() is called later, the @data keyed to @private_key + * will be inherited only by the main thread, i.e. the one that called + * g_thread_init(). + * + * @notify is used quite differently from @destructor in + * g_private_new(). + */ +void +g_static_private_set (GStaticPrivate *private_key, + gpointer data, + GDestroyNotify notify) +{ + GArray *array; + static guint next_index = 0; + GStaticPrivateNode *node; + + if (!private_key->index) + { + G_LOCK (g_thread); + + if (!private_key->index) + { + if (g_thread_free_indices) + { + private_key->index = GPOINTER_TO_UINT (g_thread_free_indices->data); + g_thread_free_indices = g_slist_delete_link (g_thread_free_indices, + g_thread_free_indices); + } + else + private_key->index = ++next_index; + } + + G_UNLOCK (g_thread); + } + + array = g_private_get (&static_private_private); + if (!array) + { + array = g_array_new (FALSE, TRUE, sizeof (GStaticPrivateNode)); + g_private_set (&static_private_private, array); + } + if (private_key->index > array->len) + g_array_set_size (array, private_key->index); + + node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1); + + if (node->destroy) + node->destroy (node->data); + + node->data = data; + node->destroy = notify; + node->owner = private_key; +} + +/** + * g_static_private_free: + * @private_key: a #GStaticPrivate to be freed + * + * Releases all resources allocated to @private_key. + * + * You don't have to call this functions for a #GStaticPrivate with an + * unbounded lifetime, i.e. objects declared 'static', but if you have + * a #GStaticPrivate as a member of a structure and the structure is + * freed, you should also free the #GStaticPrivate. + */ +void +g_static_private_free (GStaticPrivate *private_key) +{ + guint idx = private_key->index; + + if (!idx) + return; + + private_key->index = 0; + + /* Freeing the per-thread data is deferred to either the + * thread end or the next g_static_private_get() call for + * the same index. + */ + G_LOCK (g_thread); + g_thread_free_indices = g_slist_prepend (g_thread_free_indices, + GUINT_TO_POINTER (idx)); + G_UNLOCK (g_thread); +} + +/* GMutex {{{1 ------------------------------------------------------ */ + +/** + * g_mutex_new: + * + * Allocates and initializes a new #GMutex. + * + * Returns: a newly allocated #GMutex. Use g_mutex_free() to free + * + * Deprecated:3.32:GMutex can now be statically allocated, or embedded + * in structures and initialised with g_mutex_init(). + */ +GMutex * +g_mutex_new (void) +{ + GMutex *mutex; + + mutex = g_slice_new (GMutex); + g_mutex_init (mutex); + + return mutex; +} + +/** + * g_mutex_free: + * @mutex: a #GMutex + * + * Destroys a @mutex that has been created with g_mutex_new(). + * + * Calling g_mutex_free() on a locked mutex may result + * in undefined behaviour. + * + * Deprecated:3.32:GMutex can now be statically allocated, or embedded + * in structures and initialised with g_mutex_init(). + */ +void +g_mutex_free (GMutex *mutex) +{ + g_mutex_clear (mutex); + g_slice_free (GMutex, mutex); +} + +/* GCond {{{1 ------------------------------------------------------ */ + +/** + * g_cond_new: + * + * Allocates and initializes a new #GCond. + * + * Returns: a newly allocated #GCond. Free with g_cond_free() + * + * Deprecated:3.32:GCond can now be statically allocated, or embedded + * in structures and initialised with g_cond_init(). + */ +GCond * +g_cond_new (void) +{ + GCond *cond; + + cond = g_slice_new (GCond); + g_cond_init (cond); + + return cond; +} + +/** + * g_cond_free: + * @cond: a #GCond + * + * Destroys a #GCond that has been created with g_cond_new(). + * + * Calling g_cond_free() for a #GCond on which threads are + * blocking leads to undefined behaviour. + * + * Deprecated:3.32:GCond can now be statically allocated, or embedded + * in structures and initialised with g_cond_init(). + */ +void +g_cond_free (GCond *cond) +{ + g_cond_clear (cond); + g_slice_free (GCond, cond); +} + +/** + * g_cond_timed_wait: + * @cond: a #GCond + * @mutex: a #GMutex that is currently locked + * @abs_time: a #GTimeVal, determining the final time + * + * Waits until this thread is woken up on @cond, but not longer than + * until the time specified by @abs_time. The @mutex is unlocked before + * falling asleep and locked again before resuming. + * + * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait(). + * + * This function can be used even if g_thread_init() has not yet been + * called, and, in that case, will immediately return %TRUE. + * + * To easily calculate @abs_time a combination of g_get_current_time() + * and g_time_val_add() can be used. + * + * Returns: %TRUE if @cond was signalled, or %FALSE on timeout + * Deprecated:2.32: Use g_cond_wait_until() instead. + */ +gboolean +g_cond_timed_wait (GCond *cond, + GMutex *mutex, + GTimeVal *abs_time) +{ + gint64 end_time; + + if (abs_time == NULL) + { + g_cond_wait (cond, mutex); + return TRUE; + } + + end_time = abs_time->tv_sec; + end_time *= 1000000; + end_time += abs_time->tv_usec; + +#ifdef CLOCK_MONOTONIC + /* would be nice if we had clock_rtoffset, but that didn't seem to + * make it into the kernel yet... + */ + end_time += g_get_monotonic_time () - g_get_real_time (); +#else + /* if CLOCK_MONOTONIC is not defined then g_get_montonic_time() and + * g_get_real_time() are returning the same clock, so don't bother... + */ +#endif + + return g_cond_wait_until (cond, mutex, end_time); +} + +/* {{{1 Epilogue */ +/* vim: set foldmethod=marker: */ diff --git a/glib/glib/deprecated/gthread.h b/glib/glib/deprecated/gthread.h new file mode 100644 index 0000000..1866540 --- /dev/null +++ b/glib/glib/deprecated/gthread.h @@ -0,0 +1,285 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_DEPRECATED_THREAD_H__ +#define __G_DEPRECATED_THREAD_H__ + +#include + +G_BEGIN_DECLS + +typedef enum +{ + G_THREAD_PRIORITY_LOW, + G_THREAD_PRIORITY_NORMAL, + G_THREAD_PRIORITY_HIGH, + G_THREAD_PRIORITY_URGENT +} GThreadPriority; + +struct _GThread +{ + /*< private >*/ + GThreadFunc func; + gpointer data; + gboolean joinable; + GThreadPriority priority; +}; + +typedef struct _GThreadFunctions GThreadFunctions; +struct _GThreadFunctions +{ + GMutex* (*mutex_new) (void); + void (*mutex_lock) (GMutex *mutex); + gboolean (*mutex_trylock) (GMutex *mutex); + void (*mutex_unlock) (GMutex *mutex); + void (*mutex_free) (GMutex *mutex); + GCond* (*cond_new) (void); + void (*cond_signal) (GCond *cond); + void (*cond_broadcast) (GCond *cond); + void (*cond_wait) (GCond *cond, + GMutex *mutex); + gboolean (*cond_timed_wait) (GCond *cond, + GMutex *mutex, + GTimeVal *end_time); + void (*cond_free) (GCond *cond); + GPrivate* (*private_new) (GDestroyNotify destructor); + gpointer (*private_get) (GPrivate *private_key); + void (*private_set) (GPrivate *private_key, + gpointer data); + void (*thread_create) (GThreadFunc func, + gpointer data, + gulong stack_size, + gboolean joinable, + gboolean bound, + GThreadPriority priority, + gpointer thread, + GError **error); + void (*thread_yield) (void); + void (*thread_join) (gpointer thread); + void (*thread_exit) (void); + void (*thread_set_priority)(gpointer thread, + GThreadPriority priority); + void (*thread_self) (gpointer thread); + gboolean (*thread_equal) (gpointer thread1, + gpointer thread2); +}; + +GLIB_VAR GThreadFunctions g_thread_functions_for_glib_use; +GLIB_VAR gboolean g_thread_use_default_impl; + +GLIB_VAR guint64 (*g_thread_gettime) (void); + +GLIB_DEPRECATED_IN_2_32_FOR(g_thread_new) +GThread *g_thread_create (GThreadFunc func, + gpointer data, + gboolean joinable, + GError **error); + +GLIB_DEPRECATED_IN_2_32_FOR(g_thread_new) +GThread *g_thread_create_full (GThreadFunc func, + gpointer data, + gulong stack_size, + gboolean joinable, + gboolean bound, + GThreadPriority priority, + GError **error); + +GLIB_DEPRECATED_IN_2_32 +void g_thread_set_priority (GThread *thread, + GThreadPriority priority); + +GLIB_DEPRECATED_IN_2_32 +void g_thread_foreach (GFunc thread_func, + gpointer user_data); + +#ifndef G_OS_WIN32 +#include +#endif + +#define g_static_mutex_get_mutex g_static_mutex_get_mutex_impl +#define G_STATIC_MUTEX_INIT { NULL } +typedef struct +{ + GMutex *mutex; +#ifndef G_OS_WIN32 + /* only for ABI compatibility reasons */ + pthread_mutex_t unused; +#endif +} GStaticMutex; + +#define g_static_mutex_lock(mutex) \ + g_mutex_lock (g_static_mutex_get_mutex (mutex)) +#define g_static_mutex_trylock(mutex) \ + g_mutex_trylock (g_static_mutex_get_mutex (mutex)) +#define g_static_mutex_unlock(mutex) \ + g_mutex_unlock (g_static_mutex_get_mutex (mutex)) + +GLIB_DEPRECATED_IN_2_32_FOR(g_mutex_init) +void g_static_mutex_init (GStaticMutex *mutex); +GLIB_DEPRECATED_IN_2_32_FOR(g_mutex_free) +void g_static_mutex_free (GStaticMutex *mutex); +GMutex *g_static_mutex_get_mutex_impl (GStaticMutex *mutex); + +typedef struct _GStaticRecMutex GStaticRecMutex; +struct _GStaticRecMutex +{ + /*< private >*/ + GStaticMutex mutex; + guint depth; + + /* ABI compat only */ + union { +#ifdef G_OS_WIN32 + void *owner; +#else + pthread_t owner; +#endif + gdouble dummy; + } unused; +}; + +#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT } +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_init) +void g_static_rec_mutex_init (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_lock) +void g_static_rec_mutex_lock (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_try_lock) +gboolean g_static_rec_mutex_trylock (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_unlock) +void g_static_rec_mutex_unlock (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32 +void g_static_rec_mutex_lock_full (GStaticRecMutex *mutex, + guint depth); + +GLIB_DEPRECATED_IN_2_32 +guint g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rec_mutex_free) +void g_static_rec_mutex_free (GStaticRecMutex *mutex); + +typedef struct _GStaticRWLock GStaticRWLock; +struct _GStaticRWLock +{ + /*< private >*/ + GStaticMutex mutex; + GCond *read_cond; + GCond *write_cond; + guint read_counter; + gboolean have_writer; + guint want_to_read; + guint want_to_write; +}; + +#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 } + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_init) +void g_static_rw_lock_init (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_reader_lock) +void g_static_rw_lock_reader_lock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_reader_trylock) +gboolean g_static_rw_lock_reader_trylock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_reader_unlock) +void g_static_rw_lock_reader_unlock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_writer_lock) +void g_static_rw_lock_writer_lock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_writer_trylock) +gboolean g_static_rw_lock_writer_trylock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_writer_unlock) +void g_static_rw_lock_writer_unlock (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32_FOR(g_rw_lock_free) +void g_static_rw_lock_free (GStaticRWLock *lock); + +GLIB_DEPRECATED_IN_2_32 +GPrivate * g_private_new (GDestroyNotify notify); + +typedef struct _GStaticPrivate GStaticPrivate; +struct _GStaticPrivate +{ + /*< private >*/ + guint index; +}; + +#define G_STATIC_PRIVATE_INIT { 0 } +GLIB_DEPRECATED_IN_2_32 +void g_static_private_init (GStaticPrivate *private_key); + +GLIB_DEPRECATED_IN_2_32_FOR(g_private_get) +gpointer g_static_private_get (GStaticPrivate *private_key); + +GLIB_DEPRECATED_IN_2_32_FOR(g_private_set) +void g_static_private_set (GStaticPrivate *private_key, + gpointer data, + GDestroyNotify notify); + +GLIB_DEPRECATED_IN_2_32 +void g_static_private_free (GStaticPrivate *private_key); + +GLIB_DEPRECATED_IN_2_32 +gboolean g_once_init_enter_impl (volatile gsize *location); + +GLIB_DEPRECATED_IN_2_32 +void g_thread_init (gpointer vtable); +GLIB_DEPRECATED_IN_2_32 +void g_thread_init_with_errorcheck_mutexes (gpointer vtable); + +GLIB_DEPRECATED_IN_2_32 +gboolean g_thread_get_initialized (void); + +GLIB_VAR gboolean g_threads_got_initialized; + +#define g_thread_supported() (1) + +GLIB_DEPRECATED_IN_2_32 +GMutex * g_mutex_new (void); +GLIB_DEPRECATED_IN_2_32 +void g_mutex_free (GMutex *mutex); +GLIB_DEPRECATED_IN_2_32 +GCond * g_cond_new (void); +GLIB_DEPRECATED_IN_2_32 +void g_cond_free (GCond *cond); +GLIB_DEPRECATED_IN_2_32 +gboolean g_cond_timed_wait (GCond *cond, + GMutex *mutex, + GTimeVal *timeval); + +G_END_DECLS + +#endif /* __G_DEPRECATED_THREAD_H__ */ diff --git a/glib/glib/docs.c b/glib/glib/docs.c new file mode 100644 index 0000000..a3d862c --- /dev/null +++ b/glib/glib/docs.c @@ -0,0 +1,2334 @@ +/* + * Copyright © 2011 Red Hat, Inc + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Matthias Clasen + */ + + +/* This file collects documentation for macros, typedefs and + * the like, which have no good home in any of the 'real' source + * files. + */ + +/* Basic types {{{1 */ + +/** + * SECTION:types + * @title: Basic Types + * @short_description: standard GLib types, defined for ease-of-use + * and portability + * + * GLib defines a number of commonly used types, which can be divided + * into 4 groups: + * - New types which are not part of standard C (but are defined in + * various C standard library header files) - #gboolean, #gsize, + * #gssize, #goffset, #gintptr, #guintptr. + * - Integer types which are guaranteed to be the same size across + * all platforms - #gint8, #guint8, #gint16, #guint16, #gint32, + * #guint32, #gint64, #guint64. + * - Types which are easier to use than their standard C counterparts - + * #gpointer, #gconstpointer, #guchar, #guint, #gushort, #gulong. + * - Types which correspond exactly to standard C types, but are + * included for completeness - #gchar, #gint, #gshort, #glong, + * #gfloat, #gdouble. + * + * GLib also defines macros for the limits of some of the standard + * integer and floating point types, as well as macros for suitable + * printf() formats for these types. + */ + +/** + * gboolean: + * + * A standard boolean type. + * Variables of this type should only contain the value + * %TRUE or %FALSE. + */ + +/** + * gpointer: + * + * An untyped pointer. + * #gpointer looks better and is easier to use + * than void*. + */ + +/** + * gconstpointer: + * + * An untyped pointer to constant data. + * The data pointed to should not be changed. + * + * This is typically used in function prototypes to indicate + * that the data pointed to will not be altered by the function. + */ + +/** + * gchar: + * + * Corresponds to the standard C char type. + */ + +/** + * guchar: + * + * Corresponds to the standard C unsigned char type. + */ + +/** + * gint: + * + * Corresponds to the standard C int type. + * Values of this type can range from #G_MININT to #G_MAXINT. + */ + +/** + * G_MININT: + * + * The minimum value which can be held in a #gint. + */ + +/** + * G_MAXINT: + * + * The maximum value which can be held in a #gint. + */ + +/** + * guint: + * + * Corresponds to the standard C unsigned int type. + * Values of this type can range from 0 to #G_MAXUINT. + */ + +/** + * G_MAXUINT: + * + * The maximum value which can be held in a #guint. + */ + +/** + * gshort: + * + * Corresponds to the standard C short type. + * Values of this type can range from #G_MINSHORT to #G_MAXSHORT. + */ + +/** + * G_MINSHORT: + * + * The minimum value which can be held in a #gshort. + */ + +/** + * G_MAXSHORT: + * + * The maximum value which can be held in a #gshort. + */ + +/** + * gushort: + * + * Corresponds to the standard C unsigned short type. + * Values of this type can range from 0 to #G_MAXUSHORT. + */ + +/** + * G_MAXUSHORT: + * + * The maximum value which can be held in a #gushort. + */ + +/** + * glong: + * + * Corresponds to the standard C long type. + * Values of this type can range from #G_MINLONG to #G_MAXLONG. + */ + +/** + * G_MINLONG: + * + * The minimum value which can be held in a #glong. + */ + +/** + * G_MAXLONG: + * + * The maximum value which can be held in a #glong. + */ + +/** + * gulong: + * + * Corresponds to the standard C unsigned long type. + * Values of this type can range from 0 to #G_MAXULONG. + */ + +/** + * G_MAXULONG: + * + * The maximum value which can be held in a #gulong. + */ + +/** + * gint8: + * + * A signed integer guaranteed to be 8 bits on all platforms. + * Values of this type can range from #G_MININT8 (= -128) to + * #G_MAXINT8 (= 127). + */ + +/** + * G_MININT8: + * + * The minimum value which can be held in a #gint8. + * + * Since: 2.4 + */ + +/** + * G_MAXINT8: + * + * The maximum value which can be held in a #gint8. + * + * Since: 2.4 + */ + +/** + * guint8: + * + * An unsigned integer guaranteed to be 8 bits on all platforms. + * Values of this type can range from 0 to #G_MAXUINT8 (= 255). + */ + +/** + * G_MAXUINT8: + * + * The maximum value which can be held in a #guint8. + * + * Since: 2.4 + */ + +/** + * gint16: + * + * A signed integer guaranteed to be 16 bits on all platforms. + * Values of this type can range from #G_MININT16 (= -32,768) to + * #G_MAXINT16 (= 32,767). + * + * To print or scan values of this type, use + * %G_GINT16_MODIFIER and/or %G_GINT16_FORMAT. + */ + +/** + * G_MININT16: + * + * The minimum value which can be held in a #gint16. + * + * Since: 2.4 + */ + +/** + * G_MAXINT16: + * + * The maximum value which can be held in a #gint16. + * + * Since: 2.4 + */ + +/** + * G_GINT16_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gint16 or #guint16. It + * is a string literal, but doesn't include the percent-sign, such + * that you can add precision and length modifiers between percent-sign + * and conversion specifier and append a conversion specifier. + * + * The following example prints "0x7b"; + * |[ + * gint16 value = 123; + * g_print ("%#" G_GINT16_MODIFIER "x", value); + * ]| + * + * Since: 2.4 + */ + +/** + * G_GINT16_FORMAT: + * + * This is the platform dependent conversion specifier for scanning and + * printing values of type #gint16. It is a string literal, but doesn't + * include the percent-sign, such that you can add precision and length + * modifiers between percent-sign and conversion specifier. + * + * |[ + * gint16 in; + * gint32 out; + * sscanf ("42", "%" G_GINT16_FORMAT, &in) + * out = in * 1000; + * g_print ("%" G_GINT32_FORMAT, out); + * ]| + */ + +/** + * guint16: + * + * An unsigned integer guaranteed to be 16 bits on all platforms. + * Values of this type can range from 0 to #G_MAXUINT16 (= 65,535). + * + * To print or scan values of this type, use + * %G_GINT16_MODIFIER and/or %G_GUINT16_FORMAT. + */ + +/** + * G_MAXUINT16: + * + * The maximum value which can be held in a #guint16. + * + * Since: 2.4 + */ + +/** + * G_GUINT16_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #guint16. See also #G_GINT16_FORMAT + */ + +/** + * gint32: + * + * A signed integer guaranteed to be 32 bits on all platforms. + * Values of this type can range from #G_MININT32 (= -2,147,483,648) + * to #G_MAXINT32 (= 2,147,483,647). + * + * To print or scan values of this type, use + * %G_GINT32_MODIFIER and/or %G_GINT32_FORMAT. + */ + +/** + * G_MININT32: + * + * The minimum value which can be held in a #gint32. + * + * Since: 2.4 + */ + +/** + * G_MAXINT32: + * + * The maximum value which can be held in a #gint32. + * + * Since: 2.4 + */ + +/** + * G_GINT32_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gint32 or #guint32. It + * is a string literal. See also #G_GINT16_MODIFIER. + * + * Since: 2.4 + */ + +/** + * G_GINT32_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gint32. See also #G_GINT16_FORMAT. + */ + +/** + * guint32: + * + * An unsigned integer guaranteed to be 32 bits on all platforms. + * Values of this type can range from 0 to #G_MAXUINT32 (= 4,294,967,295). + * + * To print or scan values of this type, use + * %G_GINT32_MODIFIER and/or %G_GUINT32_FORMAT. + */ + +/** + * G_MAXUINT32: + * + * The maximum value which can be held in a #guint32. + * + * Since: 2.4 + */ + +/** + * G_GUINT32_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #guint32. See also #G_GINT16_FORMAT. + */ + +/** + * gint64: + * + * A signed integer guaranteed to be 64 bits on all platforms. + * Values of this type can range from #G_MININT64 + * (= -9,223,372,036,854,775,808) to #G_MAXINT64 + * (= 9,223,372,036,854,775,807). + * + * To print or scan values of this type, use + * %G_GINT64_MODIFIER and/or %G_GINT64_FORMAT. + */ + +/** + * G_MININT64: + * + * The minimum value which can be held in a #gint64. + */ + +/** + * G_MAXINT64: + * + * The maximum value which can be held in a #gint64. + */ + +/** + * G_GINT64_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gint64 or #guint64. + * It is a string literal. + * + * + * Some platforms do not support printing 64 bit integers, even + * though the types are supported. On such platforms #G_GINT64_MODIFIER + * is not defined. + * + * + * Since: 2.4 + */ + +/** + * G_GINT64_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gint64. See also #G_GINT16_FORMAT. + * + * + * Some platforms do not support scanning and printing 64 bit integers, + * even though the types are supported. On such platforms #G_GINT64_FORMAT + * is not defined. Note that scanf() may not support 64 bit integers, even + * if #G_GINT64_FORMAT is defined. Due to its weak error handling, scanf() + * is not recommended for parsing anyway; consider using g_ascii_strtoull() + * instead. + * + */ + +/** + * guint64: + * + * An unsigned integer guaranteed to be 64 bits on all platforms. + * Values of this type can range from 0 to #G_MAXUINT64 + * (= 18,446,744,073,709,551,615). + * + * To print or scan values of this type, use + * %G_GINT64_MODIFIER and/or %G_GUINT64_FORMAT. + */ + +/** + * G_MAXUINT64: + * + * The maximum value which can be held in a #guint64. + */ + +/** + * G_GUINT64_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #guint64. See also #G_GINT16_FORMAT. + * + * + * Some platforms do not support scanning and printing 64 bit integers, + * even though the types are supported. On such platforms #G_GUINT64_FORMAT + * is not defined. Note that scanf() may not support 64 bit integers, even + * if #G_GINT64_FORMAT is defined. Due to its weak error handling, scanf() + * is not recommended for parsing anyway; consider using g_ascii_strtoull() + * instead. + * + */ + +/** + * G_GINT64_CONSTANT: + * @val: a literal integer value, e.g. 0x1d636b02300a7aa7 + * + * This macro is used to insert 64-bit integer literals + * into the source code. + */ + +/** + * G_GUINT64_CONSTANT: + * @val: a literal integer value, e.g. 0x1d636b02300a7aa7U + * + * This macro is used to insert 64-bit unsigned integer + * literals into the source code. + * + * Since: 2.10 + */ + +/** + * gfloat: + * + * Corresponds to the standard C float type. + * Values of this type can range from -#G_MAXFLOAT to #G_MAXFLOAT. + */ + +/** + * G_MINFLOAT: + * + * The minimum positive value which can be held in a #gfloat. + * + * If you are interested in the smallest value which can be held + * in a #gfloat, use -G_MAXFLOAT. + */ + +/** + * G_MAXFLOAT: + * + * The maximum value which can be held in a #gfloat. + */ + +/** + * gdouble: + * + * Corresponds to the standard C double type. + * Values of this type can range from -#G_MAXDOUBLE to #G_MAXDOUBLE. + */ + +/** + * G_MINDOUBLE: + * + * The minimum positive value which can be held in a #gdouble. + * + * If you are interested in the smallest value which can be held + * in a #gdouble, use -G_MAXDOUBLE. + */ + +/** + * G_MAXDOUBLE: + * + * The maximum value which can be held in a #gdouble. + */ + +/** + * gsize: + * + * An unsigned integer type of the result of the sizeof operator, + * corresponding to the size_t type defined in C99. + * This type is wide enough to hold the numeric value of a pointer, + * so it is usually 32bit wide on a 32bit platform and 64bit wide + * on a 64bit platform. Values of this type can range from 0 to + * #G_MAXSIZE. + * + * To print or scan values of this type, use + * %G_GSIZE_MODIFIER and/or %G_GSIZE_FORMAT. + */ + +/** + * G_MAXSIZE: + * + * The maximum value which can be held in a #gsize. + * + * Since: 2.4 + */ + +/** + * G_GSIZE_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gsize or #gssize. It + * is a string literal. + * + * Since: 2.6 + */ + +/** + * G_GSIZE_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gsize. See also #G_GINT16_FORMAT. + * + * Since: 2.6 + */ + +/** + * gssize: + * + * A signed variant of #gsize, corresponding to the + * ssize_t defined on most platforms. + * Values of this type can range from #G_MINSSIZE + * to #G_MAXSSIZE. + * + * To print or scan values of this type, use + * %G_GSIZE_MODIFIER and/or %G_GSSIZE_FORMAT. + */ + +/** + * G_MINSSIZE: + * + * The minimum value which can be held in a #gssize. + * + * Since: 2.14 + */ + +/** + * G_MAXSSIZE: + * + * The maximum value which can be held in a #gssize. + * + * Since: 2.14 + */ + +/** + * G_GSSIZE_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gssize. See also #G_GINT16_FORMAT. + * + * Since: 2.6 + */ + +/** + * goffset: + * + * A signed integer type that is used for file offsets, + * corresponding to the C99 type off64_t. + * Values of this type can range from #G_MINOFFSET to + * #G_MAXOFFSET. + * + * To print or scan values of this type, use + * %G_GOFFSET_MODIFIER and/or %G_GOFFSET_FORMAT. + * + * Since: 2.14 + */ + +/** + * G_MINOFFSET: + * + * The minimum value which can be held in a #goffset. + */ + +/** + * G_MAXOFFSET: + * + * The maximum value which can be held in a #goffset. + */ + +/** + * G_GOFFSET_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #goffset. It is a string + * literal. See also #G_GINT64_MODIFIER. + * + * Since: 2.20 + */ + +/** + * G_GOFFSET_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #goffset. See also #G_GINT64_FORMAT. + * + * Since: 2.20 + */ + +/** + * G_GOFFSET_CONSTANT: + * @val: a literal integer value, e.g. 0x1d636b02300a7aa7 + * + * This macro is used to insert #goffset 64-bit integer literals + * into the source code. + * + * See also #G_GINT64_CONSTANT. + * + * Since: 2.20 + */ + +/** + * gintptr: + * + * Corresponds to the C99 type intptr_t, + * a signed integer type that can hold any pointer. + * + * To print or scan values of this type, use + * %G_GINTPTR_MODIFIER and/or %G_GINTPTR_FORMAT. + * + * Since: 2.18 + */ + +/** + * G_GINTPTR_MODIFIER: + * + * The platform dependent length modifier for conversion specifiers + * for scanning and printing values of type #gintptr or #guintptr. + * It is a string literal. + * + * Since: 2.22 + */ + +/** + * G_GINTPTR_FORMAT: + * + * This is the platform dependent conversion specifier for scanning + * and printing values of type #gintptr. + * + * Since: 2.22 + */ + +/** + * guintptr: + * + * Corresponds to the C99 type uintptr_t, + * an unsigned integer type that can hold any pointer. + * + * To print or scan values of this type, use + * %G_GINTPTR_MODIFIER and/or %G_GUINTPTR_FORMAT. + * + * Since: 2.18 + */ + +/** + * G_GUINTPTR_FORMAT: + * + * This is the platform dependent conversion specifier + * for scanning and printing values of type #guintptr. + * + * Since: 2.22 + */ + +/* Type conversion {{{1 */ + +/** + * SECTION:type_conversion + * @title: Type Conversion Macros + * @short_description: portably storing integers in pointer variables + * + * Many times GLib, GTK+, and other libraries allow you to pass "user + * data" to a callback, in the form of a void pointer. From time to time + * you want to pass an integer instead of a pointer. You could allocate + * an integer, with something like: + * |[ + * int *ip = g_new (int, 1); + * *ip = 42; + * ]| + * But this is inconvenient, and it's annoying to have to free the + * memory at some later time. + * + * Pointers are always at least 32 bits in size (on all platforms GLib + * intends to support). Thus you can store at least 32-bit integer values + * in a pointer value. Naively, you might try this, but it's incorrect: + * |[ + * gpointer p; + * int i; + * p = (void*) 42; + * i = (int) p; + * ]| + * Again, that example was not correct, don't copy it. + * The problem is that on some systems you need to do this: + * |[ + * gpointer p; + * int i; + * p = (void*) (long) 42; + * i = (int) (long) p; + * ]| + * The GLib macros GPOINTER_TO_INT(), GINT_TO_POINTER(), etc. take care + * to do the right thing on the every platform. + * + * You may not store pointers in integers. This is not + * portable in any way, shape or form. These macros only + * allow storing integers in pointers, and only preserve 32 bits of the + * integer; values outside the range of a 32-bit integer will be mangled. + * + */ + +/** + * GINT_TO_POINTER: + * @i: integer to stuff into a pointer + * + * Stuffs an integer into a pointer type. + * + * Remember, you may not store pointers in integers. This is not portable + * in any way, shape or form. These macros only allow + * storing integers in pointers, and only preserve 32 bits of the + * integer; values outside the range of a 32-bit integer will be mangled. + */ + +/** + * GPOINTER_TO_INT: + * @p: pointer containing an integer + * + * Extracts an integer from a pointer. The integer must have + * been stored in the pointer with GINT_TO_POINTER(). + * + * Remember, you may not store pointers in integers. This is not portable + * in any way, shape or form. These macros only allow + * storing integers in pointers, and only preserve 32 bits of the + * integer; values outside the range of a 32-bit integer will be mangled. + */ + +/** + * GUINT_TO_POINTER: + * @u: unsigned integer to stuff into the pointer + * + * Stuffs an unsigned integer into a pointer type. + */ + +/** + * GPOINTER_TO_UINT: + * @p: pointer to extract an unsigned integer from + * + * Extracts an unsigned integer from a pointer. The integer must have + * been stored in the pointer with GUINT_TO_POINTER(). + */ + +/** + * GSIZE_TO_POINTER: + * @s: #gsize to stuff into the pointer + * + * Stuffs a #gsize into a pointer type. + */ + +/** + * GPOINTER_TO_SIZE: + * @p: pointer to extract a #gsize from + * + * Extracts a #gsize from a pointer. The #gsize must have + * been stored in the pointer with GSIZE_TO_POINTER(). + */ + +/* Byte order {{{1 */ + +/** + * SECTION:byte_order + * @title: Byte Order Macros + * @short_description: a portable way to convert between different byte orders + * + * These macros provide a portable way to determine the host byte order + * and to convert values between different byte orders. + * + * The byte order is the order in which bytes are stored to create larger + * data types such as the #gint and #glong values. + * The host byte order is the byte order used on the current machine. + * + * Some processors store the most significant bytes (i.e. the bytes that + * hold the largest part of the value) first. These are known as big-endian + * processors. Other processors (notably the x86 family) store the most + * significant byte last. These are known as little-endian processors. + * + * Finally, to complicate matters, some other processors store the bytes in + * a rather curious order known as PDP-endian. For a 4-byte word, the 3rd + * most significant byte is stored first, then the 4th, then the 1st and + * finally the 2nd. + * + * Obviously there is a problem when these different processors communicate + * with each other, for example over networks or by using binary file formats. + * This is where these macros come in. They are typically used to convert + * values into a byte order which has been agreed on for use when + * communicating between different processors. The Internet uses what is + * known as 'network byte order' as the standard byte order (which is in + * fact the big-endian byte order). + * + * Note that the byte order conversion macros may evaluate their arguments + * multiple times, thus you should not use them with arguments which have + * side-effects. + */ + +/** + * G_BYTE_ORDER: + * + * The host byte order. + * This can be either #G_LITTLE_ENDIAN or #G_BIG_ENDIAN (support for + * #G_PDP_ENDIAN may be added in future.) + */ + +/** + * G_LITTLE_ENDIAN: + * + * Specifies one of the possible types of byte order. + * See #G_BYTE_ORDER. + */ + +/** + * G_BIG_ENDIAN: + * + * Specifies one of the possible types of byte order. + * See #G_BYTE_ORDER. + */ + +/** + * G_PDP_ENDIAN: + * + * Specifies one of the possible types of byte order + * (currently unused). See #G_BYTE_ORDER. + */ + +/** + * g_htonl: + * @val: a 32-bit integer value in host byte order + * + * Converts a 32-bit integer value from host to network byte order. + * + * Returns: @val converted to network byte order + */ + +/** + * g_htons: + * @val: a 16-bit integer value in host byte order + * + * Converts a 16-bit integer value from host to network byte order. + * + * Returns: @val converted to network byte order + */ + +/** + * g_ntohl: + * @val: a 32-bit integer value in network byte order + * + * Converts a 32-bit integer value from network to host byte order. + * + * Returns: @val converted to host byte order. + */ + +/** + * g_ntohs: + * @val: a 16-bit integer value in network byte order + * + * Converts a 16-bit integer value from network to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT_FROM_BE: + * @val: a #gint value in big-endian byte order + * + * Converts a #gint value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT_FROM_LE: + * @val: a #gint value in little-endian byte order + * + * Converts a #gint value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT_TO_BE: + * @val: a #gint value in host byte order + * + * Converts a #gint value from host byte order to big-endian. + * + * Returns: @val converted to big-endian byte order + */ + +/** + * GINT_TO_LE: + * @val: a #gint value in host byte order + * + * Converts a #gint value from host byte order to little-endian. + * + * Returns: @val converted to little-endian byte order + */ + +/** + * GUINT_FROM_BE: + * @val: a #guint value in big-endian byte order + * + * Converts a #guint value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT_FROM_LE: + * @val: a #guint value in little-endian byte order + * + * Converts a #guint value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT_TO_BE: + * @val: a #guint value in host byte order + * + * Converts a #guint value from host byte order to big-endian. + * + * Returns: @val converted to big-endian byte order + */ + +/** + * GUINT_TO_LE: + * @val: a #guint value in host byte order + * + * Converts a #guint value from host byte order to little-endian. + * + * Returns: @val converted to little-endian byte order. + */ + +/** + * GLONG_FROM_BE: + * @val: a #glong value in big-endian byte order + * + * Converts a #glong value from big-endian to the host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GLONG_FROM_LE: + * @val: a #glong value in little-endian byte order + * + * Converts a #glong value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GLONG_TO_BE: + * @val: a #glong value in host byte order + * + * Converts a #glong value from host byte order to big-endian. + * + * Returns: @val converted to big-endian byte order + */ + +/** + * GLONG_TO_LE: + * @val: a #glong value in host byte order + * + * Converts a #glong value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GULONG_FROM_BE: + * @val: a #gulong value in big-endian byte order + * + * Converts a #gulong value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GULONG_FROM_LE: + * @val: a #gulong value in little-endian byte order + * + * Converts a #gulong value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GULONG_TO_BE: + * @val: a #gulong value in host byte order + * + * Converts a #gulong value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GULONG_TO_LE: + * @val: a #gulong value in host byte order + * + * Converts a #gulong value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GSIZE_FROM_BE: + * @val: a #gsize value in big-endian byte order + * + * Converts a #gsize value from big-endian to the host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GSIZE_FROM_LE: + * @val: a #gsize value in little-endian byte order + * + * Converts a #gsize value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GSIZE_TO_BE: + * @val: a #gsize value in host byte order + * + * Converts a #gsize value from host byte order to big-endian. + * + * Returns: @val converted to big-endian byte order + */ + +/** + * GSIZE_TO_LE: + * @val: a #gsize value in host byte order + * + * Converts a #gsize value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GSSIZE_FROM_BE: + * @val: a #gssize value in big-endian byte order + * + * Converts a #gssize value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GSSIZE_FROM_LE: + * @val: a #gssize value in little-endian byte order + * + * Converts a #gssize value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GSSIZE_TO_BE: + * @val: a #gssize value in host byte order + * + * Converts a #gssize value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GSSIZE_TO_LE: + * @val: a #gssize value in host byte order + * + * Converts a #gssize value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GINT16_FROM_BE: + * @val: a #gint16 value in big-endian byte order + * + * Converts a #gint16 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT16_FROM_LE: + * @val: a #gint16 value in little-endian byte order + * + * Converts a #gint16 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT16_TO_BE: + * @val: a #gint16 value in host byte order + * + * Converts a #gint16 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GINT16_TO_LE: + * @val: a #gint16 value in host byte order + * + * Converts a #gint16 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GUINT16_FROM_BE: + * @val: a #guint16 value in big-endian byte order + * + * Converts a #guint16 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT16_FROM_LE: + * @val: a #guint16 value in little-endian byte order + * + * Converts a #guint16 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT16_TO_BE: + * @val: a #guint16 value in host byte order + * + * Converts a #guint16 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GUINT16_TO_LE: + * @val: a #guint16 value in host byte order + * + * Converts a #guint16 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GINT32_FROM_BE: + * @val: a #gint32 value in big-endian byte order + * + * Converts a #gint32 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT32_FROM_LE: + * @val: a #gint32 value in little-endian byte order + * + * Converts a #gint32 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT32_TO_BE: + * @val: a #gint32 value in host byte order + * + * Converts a #gint32 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GINT32_TO_LE: + * @val: a #gint32 value in host byte order + * + * Converts a #gint32 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GUINT32_FROM_BE: + * @val: a #guint32 value in big-endian byte order + * + * Converts a #guint32 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT32_FROM_LE: + * @val: a #guint32 value in little-endian byte order + * + * Converts a #guint32 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT32_TO_BE: + * @val: a #guint32 value in host byte order + * + * Converts a #guint32 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GUINT32_TO_LE: + * @val: a #guint32 value in host byte order + * + * Converts a #guint32 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GINT64_FROM_BE: + * @val: a #gint64 value in big-endian byte order + * + * Converts a #gint64 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT64_FROM_LE: + * @val: a #gint64 value in little-endian byte order + * + * Converts a #gint64 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GINT64_TO_BE: + * @val: a #gint64 value in host byte order + * + * Converts a #gint64 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GINT64_TO_LE: + * @val: a #gint64 value in host byte order + * + * Converts a #gint64 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GUINT64_FROM_BE: + * @val: a #guint64 value in big-endian byte order + * + * Converts a #guint64 value from big-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT64_FROM_LE: + * @val: a #guint64 value in little-endian byte order + * + * Converts a #guint64 value from little-endian to host byte order. + * + * Returns: @val converted to host byte order + */ + +/** + * GUINT64_TO_BE: + * @val: a #guint64 value in host byte order + * + * Converts a #guint64 value from host byte order to big-endian. + * + * Returns: @val converted to big-endian + */ + +/** + * GUINT64_TO_LE: + * @val: a #guint64 value in host byte order + * + * Converts a #guint64 value from host byte order to little-endian. + * + * Returns: @val converted to little-endian + */ + +/** + * GUINT16_SWAP_BE_PDP: + * @val: a #guint16 value in big-endian or pdp-endian byte order + * + * Converts a #guint16 value between big-endian and pdp-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT16_SWAP_LE_BE: + * @val: a #guint16 value in little-endian or big-endian byte order + * + * Converts a #guint16 value between little-endian and big-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT16_SWAP_LE_PDP: + * @val: a #guint16 value in little-endian or pdp-endian byte order + * + * Converts a #guint16 value between little-endian and pdp-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT32_SWAP_BE_PDP: + * @val: a #guint32 value in big-endian or pdp-endian byte order + * + * Converts a #guint32 value between big-endian and pdp-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT32_SWAP_LE_BE: + * @val: a #guint32 value in little-endian or big-endian byte order + * + * Converts a #guint32 value between little-endian and big-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT32_SWAP_LE_PDP: + * @val: a #guint32 value in little-endian or pdp-endian byte order + * + * Converts a #guint32 value between little-endian and pdp-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/** + * GUINT64_SWAP_LE_BE: + * @val: a #guint64 value in little-endian or big-endian byte order + * + * Converts a #guint64 value between little-endian and big-endian byte order. + * The conversion is symmetric so it can be used both ways. + * + * Returns: @val converted to the opposite byte order + */ + +/* Numerical Definitions {{{1 */ + +/** + * SECTION:numerical + * @title: Numerical Definitions + * @short_description: mathematical constants, and floating point decomposition + * + * GLib offers mathematical constants such as #G_PI for the value of pi; + * many platforms have these in the C library, but some don't, the GLib + * versions always exist. + * + * The #GFloatIEEE754 and #GDoubleIEEE754 unions are used to access the + * sign, mantissa and exponent of IEEE floats and doubles. These unions are + * defined as appropriate for a given platform. IEEE floats and doubles are + * supported (used for storage) by at least Intel, PPC and Sparc. See + * IEEE 754-2008 + * for more information about IEEE number formats. + */ + +/** + * G_IEEE754_FLOAT_BIAS: + * + * The bias by which exponents in single-precision floats are offset. + */ + +/** + * G_IEEE754_DOUBLE_BIAS: + * + * The bias by which exponents in double-precision floats are offset. + */ + +/** + * GFloatIEEE754: + * @v_float: the double value + * + * The #GFloatIEEE754 and #GDoubleIEEE754 unions are used to access the sign, + * mantissa and exponent of IEEE floats and doubles. These unions are defined + * as appropriate for a given platform. IEEE floats and doubles are supported + * (used for storage) by at least Intel, PPC and Sparc. + */ + +/** + * GDoubleIEEE754: + * @v_double: the double value + * + * The #GFloatIEEE754 and #GDoubleIEEE754 unions are used to access the sign, + * mantissa and exponent of IEEE floats and doubles. These unions are defined + * as appropriate for a given platform. IEEE floats and doubles are supported + * (used for storage) by at least Intel, PPC and Sparc. + */ + +/** + * G_E: + * + * The base of natural logarithms. + */ + +/** + * G_LN2: + * + * The natural logarithm of 2. + */ + +/** + * G_LN10: + * + * The natural logarithm of 10. + */ + +/** + * G_PI: + * + * The value of pi (ratio of circle's circumference to its diameter). + */ + +/** + * G_PI_2: + * + * Pi divided by 2. + */ + +/** + * G_PI_4: + * + * Pi divided by 4. + */ + +/** + * G_SQRT2: + * + * The square root of two. + */ + +/** + * G_LOG_2_BASE_10: + * + * Multiplying the base 2 exponent by this number yields the base 10 exponent. + */ + +/* Macros {{{1 */ + +/** + * SECTION:macros + * @title: Standard Macros + * @short_description: commonly-used macros + * + * These macros provide a few commonly-used features. + */ + +/** + * G_OS_WIN32: + * + * This macro is defined only on Windows. So you can bracket + * Windows-specific code in "#ifdef G_OS_WIN32". + */ + +/** + * G_OS_BEOS: + * + * This macro is defined only on BeOS. So you can bracket + * BeOS-specific code in "#ifdef G_OS_BEOS". + */ + +/** + * G_OS_UNIX: + * + * This macro is defined only on UNIX. So you can bracket + * UNIX-specific code in "#ifdef G_OS_UNIX". + */ + +/** + * G_DIR_SEPARATOR: + * + * The directory separator character. + * This is '/' on UNIX machines and '\' under Windows. + */ + +/** + * G_DIR_SEPARATOR_S: + * + * The directory separator as a string. + * This is "/" on UNIX machines and "\" under Windows. + */ + +/** + * G_IS_DIR_SEPARATOR: + * @c: a character + * + * Checks whether a character is a directory + * separator. It returns %TRUE for '/' on UNIX + * machines and for '\' or '/' under Windows. + * + * Since: 2.6 + */ + +/** + * G_SEARCHPATH_SEPARATOR: + * + * The search path separator character. + * This is ':' on UNIX machines and ';' under Windows. + */ + +/** + * G_SEARCHPATH_SEPARATOR_S: + * + * The search path separator as a string. + * This is ":" on UNIX machines and ";" under Windows. + */ + +/** + * TRUE: + * + * Defines the %TRUE value for the #gboolean type. + */ + +/** + * FALSE: + * + * Defines the %FALSE value for the #gboolean type. + */ + +/** + * NULL: + * + * Defines the standard %NULL pointer. + */ + +/** + * MIN: + * @a: a numeric value + * @b: a numeric value + * + * Calculates the minimum of @a and @b. + * + * Returns: the minimum of @a and @b. + */ + +/** + * MAX: + * @a: a numeric value + * @b: a numeric value + * + * Calculates the maximum of @a and @b. + * + * Returns: the maximum of @a and @b. + */ + +/** + * ABS: + * @a: a numeric value + * + * Calculates the absolute value of @a. + * The absolute value is simply the number with any negative sign taken away. + * + * For example, + * - ABS(-10) is 10. + * - ABS(10) is also 10. + * + * Returns: the absolute value of @a. + */ + +/** + * CLAMP: + * @x: the value to clamp + * @low: the minimum value allowed + * @high: the maximum value allowed + * + * Ensures that @x is between the limits set by @low and @high. If @low is + * greater than @high the result is undefined. + * + * For example, + * - CLAMP(5, 10, 15) is 10. + * - CLAMP(15, 5, 10) is 10. + * - CLAMP(20, 15, 25) is 20. + * + * Returns: the value of @x clamped to the range between @low and @high + */ + +/** + * G_STRUCT_MEMBER: + * @member_type: the type of the struct field + * @struct_p: a pointer to a struct + * @struct_offset: the offset of the field from the start of the struct, + * in bytes + * + * Returns a member of a structure at a given offset, using the given type. + * + * Returns: the struct member + */ + +/** + * G_STRUCT_MEMBER_P: + * @struct_p: a pointer to a struct + * @struct_offset: the offset from the start of the struct, in bytes + * + * Returns an untyped pointer to a given offset of a struct. + * + * Returns: an untyped pointer to @struct_p plus @struct_offset bytes + */ + +/** + * G_STRUCT_OFFSET: + * @struct_type: a structure type, e.g. GtkWidget + * @member: a field in the structure, e.g. window + * + * Returns the offset, in bytes, of a member of a struct. + * + * Returns: the offset of @member from the start of @struct_type + */ + +/** + * G_CONST_RETURN: + * + * If G_DISABLE_CONST_RETURNS is defined, this macro expands + * to nothing. By default, the macro expands to const. + * The macro should be used in place of const for + * functions that return a value that should not be modified. The + * purpose of this macro is to allow us to turn on const + * for returned constant strings by default, while allowing programmers + * who find that annoying to turn it off. This macro should only be used + * for return values and for out parameters, it doesn't + * make sense for in parameters. + * + * Deprecated: 2.30: API providers should replace all existing uses with + * const and API consumers should adjust their code + * accordingly + */ + +/** + * G_N_ELEMENTS: + * @arr: the array + * + * Determines the number of elements in an array. The array must be + * declared so the compiler knows its size at compile-time; this + * macro will not work on an array allocated on the heap, only static + * arrays or arrays on the stack. + */ + +/* Miscellaneous Macros {{{1 */ + +/** + * SECTION:macros_misc + * @title: Miscellaneous Macros + * @short_description: specialized macros which are not used often + * + * These macros provide more specialized features which are not + * needed so often by application programmers. + */ + +/** + * G_INLINE_FUNC: + * + * This macro is used to export function prototypes so they can be linked + * with an external version when no inlining is performed. The file which + * implements the functions should define G_IMPLEMENTS_INLINES + * before including the headers which contain %G_INLINE_FUNC declarations. + * Since inlining is very compiler-dependent using these macros correctly + * is very difficult. Their use is strongly discouraged. + * + * This macro is often mistaken for a replacement for the inline keyword; + * inline is already declared in a portable manner in the GLib headers + * and can be used normally. + */ + +/** + * G_STMT_START: + * + * Used within multi-statement macros so that they can be used in places + * where only one statement is expected by the compiler. + */ + +/** + * G_STMT_END: + * + * Used within multi-statement macros so that they can be used in places + * where only one statement is expected by the compiler. + */ + +/** + * G_BEGIN_DECLS: + * + * Used (along with #G_END_DECLS) to bracket header files. If the + * compiler in use is a C++ compiler, adds extern "C" + * around the header. + */ + +/** + * G_END_DECLS: + * + * Used (along with #G_BEGIN_DECLS) to bracket header files. If the + * compiler in use is a C++ compiler, adds extern "C" + * around the header. + */ + +/** + * G_VA_COPY: + * @ap1: the va_list variable to place a copy of @ap2 in + * @ap2: a va_list + * + * Portable way to copy va_list variables. + * + * In order to use this function, you must include + * string.h yourself, because this macro may + * use memmove() and GLib does not include string.h + * for you. + */ + +/** + * G_STRINGIFY: + * @macro_or_string: a macro or a string + * + * Accepts a macro or a string and converts it into a string after + * preprocessor argument expansion. For example, the following code: + * + * |[ + * #define AGE 27 + * const gchar *greeting = G_STRINGIFY (AGE) " today!"; + * ]| + * + * is transformed by the preprocessor into (code equivalent to): + * + * |[ + * const gchar *greeting = "27 today!"; + * ]| + */ + +/** + * G_PASTE: + * @identifier1: an identifier + * @identifier2: an identifier + * + * Yields a new preprocessor pasted identifier + * identifier1identifier2 from its expanded + * arguments @identifier1 and @identifier2. For example, + * the following code: + * |[ + * #define GET(traveller,method) G_PASTE(traveller_get_, method) (traveller) + * const gchar *name = GET (traveller, name); + * const gchar *quest = GET (traveller, quest); + * GdkColor *favourite = GET (traveller, favourite_colour); + * ]| + * + * is transformed by the preprocessor into: + * |[ + * const gchar *name = traveller_get_name (traveller); + * const gchar *quest = traveller_get_quest (traveller); + * GdkColor *favourite = traveller_get_favourite_colour (traveller); + * ]| + * + * Since: 2.20 + */ + +/** + * G_STATIC_ASSERT: + * @expr: a constant expression + * + * The G_STATIC_ASSERT macro lets the programmer check + * a condition at compile time, the condition needs to + * be compile time computable. The macro can be used in + * any place where a typedef is valid. + * + * + * A typedef is generally allowed in + * exactly the same places that a variable declaration is + * allowed. For this reason, you should not use + * G_STATIC_ASSERT in the middle of + * blocks of code. + * + * + * The macro should only be used once per source code line. + * + * Since: 2.20 + */ + +/** + * G_STATIC_ASSERT_EXPR: + * @expr: a constant expression + * + * The G_STATIC_ASSERT_EXPR macro lets the programmer check + * a condition at compile time. The condition needs to be + * compile time computable. + * + * Unlike G_STATIC_ASSERT, this macro + * evaluates to an expression and, as such, can be used in + * the middle of other expressions. Its value should be + * ignored. This can be accomplished by placing it as + * the first argument of a comma expression. + * + * |[ + * #define ADD_ONE_TO_INT(x) \ + * (G_STATIC_ASSERT_EXPR(sizeof (x) == sizeof (int)), ((x) + 1)) + * ]| + * + * Since: 2.30 + */ + +/** + * G_GNUC_EXTENSION: + * + * Expands to __extension__ when gcc + * is used as the compiler. This simply tells gcc not + * to warn about the following non-standard code when compiling with the + * option. + */ + +/** + * G_GNUC_CONST: + * + * Expands to the GNU C const function attribute if + * the compiler is gcc. Declaring a function as const + * enables better optimization of calls to the function. A const function + * doesn't examine any values except its parameters, and has no effects + * except its return value. See the GNU C documentation for details. + * + * + * A function that has pointer arguments and examines the data pointed to + * must not be declared const. Likewise, a function + * that calls a non-const function usually must not be const. It doesn't + * make sense for a const function to return void. + * + */ + +/** + * G_GNUC_PURE: + * + * Expands to the GNU C pure function attribute if the + * compiler is gcc. Declaring a function as pure enables + * better optimization of calls to the function. A pure function has no + * effects except its return value and the return value depends only on + * the parameters and/or global variables. See the GNU C documentation + * for details. + */ + +/** + * G_GNUC_MALLOC: + * + * Expands to the GNU C malloc function attribute if the + * compiler is gcc. Declaring a function as malloc enables + * better optimization of the function. A function can have the malloc + * attribute if it returns a pointer which is guaranteed to not alias with + * any other pointer when the function returns (in practice, this means newly + * allocated memory). See the GNU C documentation for details. + * + * Since: 2.6 + */ + +/** + * G_GNUC_ALLOC_SIZE: + * @x: the index of the argument specifying the allocation size + * + * Expands to the GNU C alloc_size function attribute + * if the compiler is a new enough gcc. This attribute + * tells the compiler that the function returns a pointer to memory of a + * size that is specified by the @xth function parameter. + * See the GNU C documentation for details. + * + * Since: 2.18 + */ + +/** + * G_GNUC_ALLOC_SIZE2: + * @x: the index of the argument specifying one factor of the allocation size + * @y: the index of the argument specifying the second factor of the allocation size + * + * Expands to the GNU C alloc_size function attribute + * if the compiler is a new enough gcc. This attribute + * tells the compiler that the function returns a pointer to memory of a + * size that is specified by the product of two function parameters. + * See the GNU C documentation for details. + * + * Since: 2.18 + */ + +/** + * G_GNUC_DEPRECATED: + * + * Expands to the GNU C deprecated attribute if the + * compiler is gcc. It can be used to mark typedefs, + * variables and functions as deprecated. When called with the + * option, the compiler will + * generate warnings when deprecated interfaces are used. + * See the GNU C documentation for details. + * + * Since: 2.2 + */ + +/** + * G_GNUC_DEPRECATED_FOR: + * @f: the intended replacement for the deprecated symbol, + * such as the name of a function + * + * Like %G_GNUC_DEPRECATED, but names the intended replacement for the + * deprecated symbol if the version of gcc in use is + * new enough to support custom deprecation messages. + * See the GNU C documentation for details. + * + * Note that if @f is a macro, it will be expanded in the warning message. + * You can enclose it in quotes to prevent this. (The quotes will show up + * in the warning, but it's better than showing the macro expansion.) + * + * Since: 2.26 + */ + +/** + * G_GNUC_BEGIN_IGNORE_DEPRECATIONS: + * + * Tells gcc (if it is a new enough version) to + * temporarily stop emitting warnings when functions marked with + * %G_GNUC_DEPRECATED or %G_GNUC_DEPRECATED_FOR are called. This is + * useful for when you have one deprecated function calling another + * one, or when you still have regression tests for deprecated + * functions. + * + * Use %G_GNUC_END_IGNORE_DEPRECATIONS to begin warning again. (If you + * are not compiling with -Wdeprecated-declarations + * then neither macro has any effect.) + * + * This macro can be used either inside or outside of a function body, + * but must appear on a line by itself. + * + * Since: 2.32 + */ + +/** + * G_GNUC_END_IGNORE_DEPRECATIONS: + * + * Undoes the effect of %G_GNUC_BEGIN_IGNORE_DEPRECATIONS, telling + * gcc to begin outputting warnings again + * (assuming those warnings had been enabled to begin with). + * + * This macro can be used either inside or outside of a function body, + * but must appear on a line by itself. + * + * Since: 2.32 + */ + +/** + * G_DEPRECATED: + * + * This macro is similar to %G_GNUC_DEPRECATED, and can be used to mark + * functions declarations as deprecated. Unlike %G_GNUC_DEPRECATED, it is + * meant to be portable across different compilers and must be placed + * before the function declaration. + * + * Since: 2.32 + */ + +/** + * G_DEPRECATED_FOR: + * + * This macro is similar to %G_GNUC_DEPRECATED_FOR, and can be used to mark + * functions declarations as deprecated. Unlike %G_GNUC_DEPRECATED_FOR, it is + * meant to be portable across different compilers and must be placed + * before the function declaration. + * + * Since: 2.32 + */ + +/** + * G_UNAVAILABLE: + * + * This macro can be used to mark a function declaration as unavailable. + * It must be placed before the function declaration. Use of a function + * that has been annotated with this macros will produce a compiler warning. + * + * Since: 2.32 + */ + +/** + * GLIB_DISABLE_DEPRECATION_WARNINGS: + * + * A macro that should be defined before including the glib.h header. + * If it is defined, no compiler warnings will be produced for uses + * of deprecated GLib APIs. + */ + +/** + * G_GNUC_NORETURN: + * + * Expands to the GNU C noreturn function attribute + * if the compiler is gcc. It is used for declaring + * functions which never return. It enables optimization of the function, + * and avoids possible compiler warnings. See the GNU C documentation for + * details. + */ + +/** + * G_GNUC_UNUSED: + * + * Expands to the GNU C unused function attribute if + * the compiler is gcc. It is used for declaring + * functions which may never be used. It avoids possible compiler warnings. + * See the GNU C documentation for details. + */ + +/** + * G_GNUC_PRINTF: + * @format_idx: the index of the argument corresponding to the + * format string (The arguments are numbered from 1) + * @arg_idx: the index of the first of the format arguments + * + * Expands to the GNU C format function attribute + * if the compiler is gcc. This is used for declaring + * functions which take a variable number of arguments, with the same + * syntax as printf(). It allows the compiler to type-check the arguments + * passed to the function. See the GNU C documentation for details. + * + * |[ + * gint g_snprintf (gchar *string, + * gulong n, + * gchar const *format, + * ...) G_GNUC_PRINTF (3, 4); + * ]| + */ + +/** + * G_GNUC_SCANF: + * @format_idx: the index of the argument corresponding to + * the format string (The arguments are numbered from 1) + * @arg_idx: the index of the first of the format arguments + * + * Expands to the GNU C format function attribute + * if the compiler is gcc. This is used for declaring + * functions which take a variable number of arguments, with the same + * syntax as scanf(). It allows the compiler to type-check the arguments + * passed to the function. See the GNU C documentation for details. + */ + +/** + * G_GNUC_FORMAT: + * @arg_idx: the index of the argument + * + * Expands to the GNU C format_arg function attribute + * if the compiler is gcc. This function attribute + * specifies that a function takes a format string for a printf(), + * scanf(), strftime() or strfmon() style function and modifies it, + * so that the result can be passed to a printf(), scanf(), strftime() + * or strfmon() style function (with the remaining arguments to the + * format function the same as they would have been for the unmodified + * string). See the GNU C documentation for details. + * + * |[ + * gchar *g_dgettext (gchar *domain_name, gchar *msgid) G_GNUC_FORMAT (2); + * ]| + */ + +/** + * G_GNUC_NULL_TERMINATED: + * + * Expands to the GNU C sentinel function attribute + * if the compiler is gcc, or "" if it isn't. This + * function attribute only applies to variadic functions and instructs + * the compiler to check that the argument list is terminated with an + * explicit %NULL. See the GNU C documentation for details. + * + * Since: 2.8 + */ + +/** + * G_GNUC_WARN_UNUSED_RESULT: + * + * Expands to the GNU C warn_unused_result function + * attribute if the compiler is gcc, or "" if it isn't. + * This function attribute makes the compiler emit a warning if the result + * of a function call is ignored. See the GNU C documentation for details. + * + * Since: 2.10 + */ + +/** + * G_GNUC_FUNCTION: + * + * Expands to "" on all modern compilers, and to + * __FUNCTION__ on gcc version 2.x. + * Don't use it. + * + * Deprecated: 2.16: Use #G_STRFUNC instead + */ + +/** + * G_GNUC_PRETTY_FUNCTION: + * + * Expands to "" on all modern compilers, and to + * __PRETTY_FUNCTION__ on gcc + * version 2.x. Don't use it. + * + * Deprecated: 2.16: Use #G_STRFUNC instead + */ + +/** + * G_GNUC_NO_INSTRUMENT: + * + * Expands to the GNU C no_instrument_function function + * attribute if the compiler is gcc. Functions with this + * attribute will not be instrumented for profiling, when the compiler is + * called with the option. + * See the GNU C documentation for details. + */ + +/** + * G_GNUC_INTERNAL: + * + * This attribute can be used for marking library functions as being used + * internally to the library only, which may allow the compiler to handle + * function calls more efficiently. Note that static functions do not need + * to be marked as internal in this way. See the GNU C documentation for + * details. + * + * When using a compiler that supports the GNU C hidden visibility attribute, + * this macro expands to __attribute__((visibility("hidden"))). + * When using the Sun Studio compiler, it expands to __hidden. + * + * Note that for portability, the attribute should be placed before the + * function declaration. While GCC allows the macro after the declaration, + * Sun Studio does not. + * + * |[ + * G_GNUC_INTERNAL + * void _g_log_fallback_handler (const gchar *log_domain, + * GLogLevelFlags log_level, + * const gchar *message, + * gpointer unused_data); + * ]| + * + * Since: 2.6 + */ + +/** + * G_GNUC_MAY_ALIAS: + * + * Expands to the GNU C may_alias type attribute + * if the compiler is gcc. Types with this attribute + * will not be subjected to type-based alias analysis, but are assumed + * to alias with any other type, just like char. + * See the GNU C documentation for details. + * + * Since: 2.14 + */ + +/** + * G_LIKELY: + * @expr: the expression + * + * Hints the compiler that the expression is likely to evaluate to + * a true value. The compiler may use this information for optimizations. + * + * |[ + * if (G_LIKELY (random () != 1)) + * g_print ("not one"); + * ]| + * + * Returns: the value of @expr + * + * Since: 2.2 + */ + +/** + * G_UNLIKELY: + * @expr: the expression + * + * Hints the compiler that the expression is unlikely to evaluate to + * a true value. The compiler may use this information for optimizations. + * + * |[ + * if (G_UNLIKELY (random () == 1)) + * g_print ("a random one"); + * ]| + * + * Returns: the value of @expr + * + * Since: 2.2 + */ + +/** + * G_STRLOC: + * + * Expands to a string identifying the current code position. + */ + +/** + * G_STRFUNC: + * + * Expands to a string identifying the current function. + * + * Since: 2.4 + */ + +/* Windows Compatibility Functions {{{1 */ + +/** + * SECTION:windows + * @title: Windows Compatibility Functions + * @short_description: UNIX emulation on Windows + * + * These functions provide some level of UNIX emulation on the + * Windows platform. If your application really needs the POSIX + * APIs, we suggest you try the Cygwin project. + */ + +/** + * MAXPATHLEN: + * + * Provided for UNIX emulation on Windows; equivalent to UNIX + * macro %MAXPATHLEN, which is the maximum length of a filename + * (including full path). + */ + +/** + * G_WIN32_DLLMAIN_FOR_DLL_NAME: + * @static: empty or "static" + * @dll_name: the name of the (pointer to the) char array where + * the DLL name will be stored. If this is used, you must also + * include windows.h. If you need a more + * complex DLL entry point function, you cannot use this + * + * On Windows, this macro defines a DllMain() function that stores + * the actual DLL name that the code being compiled will be included in. + * + * On non-Windows platforms, expands to nothing. + */ + +/** + * G_WIN32_HAVE_WIDECHAR_API: + * + * On Windows, this macro defines an expression which evaluates to + * %TRUE if the code is running on a version of Windows where the wide + * character versions of the Win32 API functions, and the wide character + * versions of the C library functions work. (They are always present in + * the DLLs, but don't work on Windows 9x and Me.) + * + * On non-Windows platforms, it is not defined. + * + * Since: 2.6 + */ + + +/** + * G_WIN32_IS_NT_BASED: + * + * On Windows, this macro defines an expression which evaluates to + * %TRUE if the code is running on an NT-based Windows operating system. + * + * On non-Windows platforms, it is not defined. + * + * Since: 2.6 + */ + +/* Epilogue {{{1 */ +/* vim: set foldmethod=marker: */ diff --git a/glib/glib/galloca.h b/glib/glib/galloca.h new file mode 100644 index 0000000..1ecdf65 --- /dev/null +++ b/glib/glib/galloca.h @@ -0,0 +1,110 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_ALLOCA_H__ +#define __G_ALLOCA_H__ + +#include + +#ifdef __GNUC__ +/* GCC does the right thing */ +# undef alloca +# define alloca(size) __builtin_alloca (size) +#elif defined (GLIB_HAVE_ALLOCA_H) +/* a native and working alloca.h is there */ +# include +#else /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */ +# if defined(_MSC_VER) || defined(__DMC__) +# include +# define alloca _alloca +# else /* !_MSC_VER && !__DMC__ */ +# ifdef _AIX +# pragma alloca +# else /* !_AIX */ +# ifndef alloca /* predefined by HP cc +Olibcalls */ +G_BEGIN_DECLS +char *alloca (); +G_END_DECLS +# endif /* !alloca */ +# endif /* !_AIX */ +# endif /* !_MSC_VER && !__DMC__ */ +#endif /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */ + +/** + * g_alloca: + * @size: number of bytes to allocate. + * + * Allocates @size bytes on the stack; these bytes will be freed when the current + * stack frame is cleaned up. This macro essentially just wraps the alloca() + * function present on most UNIX variants. + * Thus it provides the same advantages and pitfalls as alloca(): + * + * + * + alloca() is very fast, as on most systems it's implemented by just adjusting + * the stack pointer register. + * + * + * + It doesn't cause any memory fragmentation, within its scope, separate alloca() + * blocks just build up and are released together at function end. + * + * + * - Allocation sizes have to fit into the current stack frame. For instance in a + * threaded environment on Linux, the per-thread stack size is limited to 2 Megabytes, + * so be sparse with alloca() uses. + * + * + * - Allocation failure due to insufficient stack space is not indicated with a %NULL + * return like e.g. with malloc(). Instead, most systems probably handle it the same + * way as out of stack space situations from infinite function recursion, i.e. + * with a segmentation fault. + * + * + * - Special care has to be taken when mixing alloca() with GNU C variable sized arrays. + * Stack space allocated with alloca() in the same scope as a variable sized array + * will be freed together with the variable sized array upon exit of that scope, and + * not upon exit of the enclosing function scope. + * + * + * + * Returns: space for @size bytes, allocated on the stack + */ +#define g_alloca(size) alloca (size) +/** + * g_newa: + * @struct_type: Type of memory chunks to be allocated + * @n_structs: Number of chunks to be allocated + * + * Wraps g_alloca() in a more typesafe manner. + * + * Returns: Pointer to stack space for @n_structs chunks of type @struct_type + */ +#define g_newa(struct_type, n_structs) ((struct_type*) g_alloca (sizeof (struct_type) * (gsize) (n_structs))) + +#endif /* __G_ALLOCA_H__ */ diff --git a/glib/glib/garray.c b/glib/glib/garray.c new file mode 100644 index 0000000..567774c --- /dev/null +++ b/glib/glib/garray.c @@ -0,0 +1,1777 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include + +#include "garray.h" + +#include "gbytes.h" +#include "gslice.h" +#include "gmem.h" +#include "gtestutils.h" +#include "gthread.h" +#include "gmessages.h" +#include "gqsort.h" + + +/** + * SECTION:arrays + * @title: Arrays + * @short_description: arrays of arbitrary elements which grow + * automatically as elements are added + * + * Arrays are similar to standard C arrays, except that they grow + * automatically as elements are added. + * + * Array elements can be of any size (though all elements of one array + * are the same size), and the array can be automatically cleared to + * '0's and zero-terminated. + * + * To create a new array use g_array_new(). + * + * To add elements to an array, use g_array_append_val(), + * g_array_append_vals(), g_array_prepend_val(), and + * g_array_prepend_vals(). + * + * To access an element of an array, use g_array_index(). + * + * To set the size of an array, use g_array_set_size(). + * + * To free an array, use g_array_free(). + * + * + * Using a #GArray to store #gint values + * + * GArray *garray; + * gint i; + * /* We create a new array to store gint values. + * We don't want it zero-terminated or cleared to 0's. */ + * garray = g_array_new (FALSE, FALSE, sizeof (gint)); + * for (i = 0; i < 10000; i++) + * g_array_append_val (garray, i); + * for (i = 0; i < 10000; i++) + * if (g_array_index (garray, gint, i) != i) + * g_print ("ERROR: got %d instead of %d\n", + * g_array_index (garray, gint, i), i); + * g_array_free (garray, TRUE); + * + * + **/ + +#define MIN_ARRAY_SIZE 16 + +typedef struct _GRealArray GRealArray; + +/** + * GArray: + * @data: a pointer to the element data. The data may be moved as + * elements are added to the #GArray. + * @len: the number of elements in the #GArray not including the + * possible terminating zero element. + * + * Contains the public fields of an Array. + **/ +struct _GRealArray +{ + guint8 *data; + guint len; + guint alloc; + guint elt_size; + guint zero_terminated : 1; + guint clear : 1; + gint ref_count; + GDestroyNotify clear_func; +}; + +/** + * g_array_index: + * @a: a #GArray. + * @t: the type of the elements. + * @i: the index of the element to return. + * @Returns: the element of the #GArray at the index given by @i. + * + * Returns the element of a #GArray at the given index. The return + * value is cast to the given type. + * + * + * Getting a pointer to an element in a #GArray + * + * EDayViewEvent *event; + * /* This gets a pointer to the 4th element + * in the array of EDayViewEvent structs. */ + * event = &g_array_index (events, EDayViewEvent, 3); + * + * + **/ + +#define g_array_elt_len(array,i) ((array)->elt_size * (i)) +#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i))) +#define g_array_elt_zero(array, pos, len) \ + (memset (g_array_elt_pos ((array), pos), 0, g_array_elt_len ((array), len))) +#define g_array_zero_terminate(array) G_STMT_START{ \ + if ((array)->zero_terminated) \ + g_array_elt_zero ((array), (array)->len, 1); \ +}G_STMT_END + +static guint g_nearest_pow (gint num) G_GNUC_CONST; +static void g_array_maybe_expand (GRealArray *array, + gint len); + +/** + * g_array_new: + * @zero_terminated: %TRUE if the array should have an extra element at + * the end which is set to 0. + * @clear_: %TRUE if #GArray elements should be automatically cleared + * to 0 when they are allocated. + * @element_size: the size of each element in bytes. + * @Returns: the new #GArray. + * + * Creates a new #GArray with a reference count of 1. + **/ +GArray* +g_array_new (gboolean zero_terminated, + gboolean clear, + guint elt_size) +{ + g_return_val_if_fail (elt_size > 0, NULL); + + return g_array_sized_new (zero_terminated, clear, elt_size, 0); +} + +/** + * g_array_sized_new: + * @zero_terminated: %TRUE if the array should have an extra element at + * the end with all bits cleared. + * @clear_: %TRUE if all bits in the array should be cleared to 0 on + * allocation. + * @element_size: size of each element in the array. + * @reserved_size: number of elements preallocated. + * @Returns: the new #GArray. + * + * Creates a new #GArray with @reserved_size elements preallocated and + * a reference count of 1. This avoids frequent reallocation, if you + * are going to add many elements to the array. Note however that the + * size of the array is still 0. + **/ +GArray* g_array_sized_new (gboolean zero_terminated, + gboolean clear, + guint elt_size, + guint reserved_size) +{ + GRealArray *array; + + g_return_val_if_fail (elt_size > 0, NULL); + + array = g_slice_new (GRealArray); + + array->data = NULL; + array->len = 0; + array->alloc = 0; + array->zero_terminated = (zero_terminated ? 1 : 0); + array->clear = (clear ? 1 : 0); + array->elt_size = elt_size; + array->ref_count = 1; + array->clear_func = NULL; + + if (array->zero_terminated || reserved_size != 0) + { + g_array_maybe_expand (array, reserved_size); + g_array_zero_terminate(array); + } + + return (GArray*) array; +} + +/** + * g_array_set_clear_func: + * @array: A #GArray + * @clear_func: a function to clear an element of @array + * + * Sets a function to clear an element of @array. + * + * The @clear_func will be called when an element in the array + * data segment is removed and when the array is freed and data + * segment is deallocated as well. + * + * Note that in contrast with other uses of #GDestroyNotify + * functions, @clear_func is expected to clear the contents of + * the array element it is given, but not free the element itself. + * + * Since: 2.32 + */ +void +g_array_set_clear_func (GArray *array, + GDestroyNotify clear_func) +{ + GRealArray *rarray = (GRealArray *) array; + + g_return_if_fail (array != NULL); + + rarray->clear_func = clear_func; +} + +/** + * g_array_ref: + * @array: A #GArray. + * + * Atomically increments the reference count of @array by one. This + * function is MT-safe and may be called from any thread. + * + * Returns: The passed in #GArray. + * + * Since: 2.22 + **/ +GArray * +g_array_ref (GArray *array) +{ + GRealArray *rarray = (GRealArray*) array; + g_return_val_if_fail (array, NULL); + + g_atomic_int_inc (&rarray->ref_count); + + return array; +} + +typedef enum +{ + FREE_SEGMENT = 1 << 0, + PRESERVE_WRAPPER = 1 << 1 +} ArrayFreeFlags; + +static gchar *array_free (GRealArray *, ArrayFreeFlags); + +/** + * g_array_unref: + * @array: A #GArray. + * + * Atomically decrements the reference count of @array by one. If the + * reference count drops to 0, all memory allocated by the array is + * released. This function is MT-safe and may be called from any + * thread. + * + * Since: 2.22 + **/ +void +g_array_unref (GArray *array) +{ + GRealArray *rarray = (GRealArray*) array; + g_return_if_fail (array); + + if (g_atomic_int_dec_and_test (&rarray->ref_count)) + array_free (rarray, FREE_SEGMENT); +} + +/** + * g_array_get_element_size: + * @array: A #GArray. + * + * Gets the size of the elements in @array. + * + * Returns: Size of each element, in bytes. + * + * Since: 2.22 + **/ +guint +g_array_get_element_size (GArray *array) +{ + GRealArray *rarray = (GRealArray*) array; + + g_return_val_if_fail (array, 0); + + return rarray->elt_size; +} + +/** + * g_array_free: + * @array: a #GArray. + * @free_segment: if %TRUE the actual element data is freed as well. + * @Returns: the element data if @free_segment is %FALSE, otherwise + * %NULL. The element data should be freed using g_free(). + * + * Frees the memory allocated for the #GArray. If @free_segment is + * %TRUE it frees the memory block holding the elements as well and + * also each element if @array has a @element_free_func set. Pass + * %FALSE if you want to free the #GArray wrapper but preserve the + * underlying array for use elsewhere. If the reference count of @array + * is greater than one, the #GArray wrapper is preserved but the size + * of @array will be set to zero. + * + * If array elements contain dynamically-allocated memory, + * they should be freed separately. + **/ +gchar* +g_array_free (GArray *farray, + gboolean free_segment) +{ + GRealArray *array = (GRealArray*) farray; + ArrayFreeFlags flags; + + g_return_val_if_fail (array, NULL); + + flags = (free_segment ? FREE_SEGMENT : 0); + + /* if others are holding a reference, preserve the wrapper but do free/return the data */ + if (!g_atomic_int_dec_and_test (&array->ref_count)) + flags |= PRESERVE_WRAPPER; + + return array_free (array, flags); +} + +static gchar * +array_free (GRealArray *array, + ArrayFreeFlags flags) +{ + gchar *segment; + + if (flags & FREE_SEGMENT) + { + if (array->clear_func != NULL) + { + guint i; + + for (i = 0; i < array->len; i++) + array->clear_func (g_array_elt_pos (array, i)); + } + + g_free (array->data); + segment = NULL; + } + else + segment = (gchar*) array->data; + + if (flags & PRESERVE_WRAPPER) + { + array->data = NULL; + array->len = 0; + array->alloc = 0; + } + else + { + g_slice_free1 (sizeof (GRealArray), array); + } + + return segment; +} + +/** + * g_array_append_vals: + * @array: a #GArray. + * @data: a pointer to the elements to append to the end of the array. + * @len: the number of elements to append. + * @Returns: the #GArray. + * + * Adds @len elements onto the end of the array. + **/ +/** + * g_array_append_val: + * @a: a #GArray. + * @v: the value to append to the #GArray. + * @Returns: the #GArray. + * + * Adds the value on to the end of the array. The array will grow in + * size automatically if necessary. + * + * g_array_append_val() is a macro which uses a reference + * to the value parameter @v. This means that you cannot use it with + * literal values such as "27". You must use variables. + **/ +GArray* +g_array_append_vals (GArray *farray, + gconstpointer data, + guint len) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + g_array_maybe_expand (array, len); + + memcpy (g_array_elt_pos (array, array->len), data, + g_array_elt_len (array, len)); + + array->len += len; + + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_prepend_vals: + * @array: a #GArray. + * @data: a pointer to the elements to prepend to the start of the + * array. + * @len: the number of elements to prepend. + * @Returns: the #GArray. + * + * Adds @len elements onto the start of the array. + * + * This operation is slower than g_array_append_vals() since the + * existing elements in the array have to be moved to make space for + * the new elements. + **/ +/** + * g_array_prepend_val: + * @a: a #GArray. + * @v: the value to prepend to the #GArray. + * @Returns: the #GArray. + * + * Adds the value on to the start of the array. The array will grow in + * size automatically if necessary. + * + * This operation is slower than g_array_append_val() since the + * existing elements in the array have to be moved to make space for + * the new element. + * + * g_array_prepend_val() is a macro which uses a reference + * to the value parameter @v. This means that you cannot use it with + * literal values such as "27". You must use variables. + **/ +GArray* +g_array_prepend_vals (GArray *farray, + gconstpointer data, + guint len) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + g_array_maybe_expand (array, len); + + g_memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0), + g_array_elt_len (array, array->len)); + + memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len)); + + array->len += len; + + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_insert_vals: + * @array: a #GArray. + * @index_: the index to place the elements at. + * @data: a pointer to the elements to insert. + * @len: the number of elements to insert. + * @Returns: the #GArray. + * + * Inserts @len elements into a #GArray at the given index. + **/ +/** + * g_array_insert_val: + * @a: a #GArray. + * @i: the index to place the element at. + * @v: the value to insert into the array. + * @Returns: the #GArray. + * + * Inserts an element into an array at the given index. + * + * g_array_insert_val() is a macro which uses a reference + * to the value parameter @v. This means that you cannot use it with + * literal values such as "27". You must use variables. + **/ +GArray* +g_array_insert_vals (GArray *farray, + guint index_, + gconstpointer data, + guint len) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + g_array_maybe_expand (array, len); + + g_memmove (g_array_elt_pos (array, len + index_), + g_array_elt_pos (array, index_), + g_array_elt_len (array, array->len - index_)); + + memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len)); + + array->len += len; + + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_set_size: + * @array: a #GArray. + * @length: the new size of the #GArray. + * @Returns: the #GArray. + * + * Sets the size of the array, expanding it if necessary. If the array + * was created with @clear_ set to %TRUE, the new elements are set to 0. + **/ +GArray* +g_array_set_size (GArray *farray, + guint length) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + if (length > array->len) + { + g_array_maybe_expand (array, length - array->len); + + if (array->clear) + g_array_elt_zero (array, array->len, length - array->len); + } + else if (length < array->len) + g_array_remove_range (farray, length, array->len - length); + + array->len = length; + + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_remove_index: + * @array: a #GArray. + * @index_: the index of the element to remove. + * @Returns: the #GArray. + * + * Removes the element at the given index from a #GArray. The following + * elements are moved down one place. + **/ +GArray* +g_array_remove_index (GArray *farray, + guint index_) +{ + GRealArray* array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + g_return_val_if_fail (index_ < array->len, NULL); + + if (array->clear_func != NULL) + array->clear_func (g_array_elt_pos (array, index_)); + + if (index_ != array->len - 1) + g_memmove (g_array_elt_pos (array, index_), + g_array_elt_pos (array, index_ + 1), + g_array_elt_len (array, array->len - index_ - 1)); + + array->len -= 1; + + if (G_UNLIKELY (g_mem_gc_friendly)) + g_array_elt_zero (array, array->len, 1); + else + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_remove_index_fast: + * @array: a @GArray. + * @index_: the index of the element to remove. + * @Returns: the #GArray. + * + * Removes the element at the given index from a #GArray. The last + * element in the array is used to fill in the space, so this function + * does not preserve the order of the #GArray. But it is faster than + * g_array_remove_index(). + **/ +GArray* +g_array_remove_index_fast (GArray *farray, + guint index_) +{ + GRealArray* array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + + g_return_val_if_fail (index_ < array->len, NULL); + + if (array->clear_func != NULL) + array->clear_func (g_array_elt_pos (array, index_)); + + if (index_ != array->len - 1) + memcpy (g_array_elt_pos (array, index_), + g_array_elt_pos (array, array->len - 1), + g_array_elt_len (array, 1)); + + array->len -= 1; + + if (G_UNLIKELY (g_mem_gc_friendly)) + g_array_elt_zero (array, array->len, 1); + else + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_remove_range: + * @array: a @GArray. + * @index_: the index of the first element to remove. + * @length: the number of elements to remove. + * @Returns: the #GArray. + * + * Removes the given number of elements starting at the given index + * from a #GArray. The following elements are moved to close the gap. + * + * Since: 2.4 + **/ +GArray* +g_array_remove_range (GArray *farray, + guint index_, + guint length) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_val_if_fail (array, NULL); + g_return_val_if_fail (index_ < array->len, NULL); + g_return_val_if_fail (index_ + length <= array->len, NULL); + + if (array->clear_func != NULL) + { + guint i; + + for (i = 0; i < length; i++) + array->clear_func (g_array_elt_pos (array, index_ + i)); + } + + if (index_ + length != array->len) + g_memmove (g_array_elt_pos (array, index_), + g_array_elt_pos (array, index_ + length), + (array->len - (index_ + length)) * array->elt_size); + + array->len -= length; + if (G_UNLIKELY (g_mem_gc_friendly)) + g_array_elt_zero (array, array->len, length); + else + g_array_zero_terminate (array); + + return farray; +} + +/** + * g_array_sort: + * @array: a #GArray. + * @compare_func: comparison function. + * + * Sorts a #GArray using @compare_func which should be a qsort()-style + * comparison function (returns less than zero for first arg is less + * than second arg, zero for equal, greater zero if first arg is + * greater than second arg). + * + * This is guaranteed to be a stable sort since version 2.32. + **/ +void +g_array_sort (GArray *farray, + GCompareFunc compare_func) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_if_fail (array != NULL); + + /* Don't use qsort as we want a guaranteed stable sort */ + g_qsort_with_data (array->data, + array->len, + array->elt_size, + (GCompareDataFunc)compare_func, + NULL); +} + +/** + * g_array_sort_with_data: + * @array: a #GArray. + * @compare_func: comparison function. + * @user_data: data to pass to @compare_func. + * + * Like g_array_sort(), but the comparison function receives an extra + * user data argument. + * + * This is guaranteed to be a stable sort since version 2.32. + * + * There used to be a comment here about making the sort stable by + * using the addresses of the elements in the comparison function. + * This did not actually work, so any such code should be removed. + **/ +void +g_array_sort_with_data (GArray *farray, + GCompareDataFunc compare_func, + gpointer user_data) +{ + GRealArray *array = (GRealArray*) farray; + + g_return_if_fail (array != NULL); + + g_qsort_with_data (array->data, + array->len, + array->elt_size, + compare_func, + user_data); +} + +/* Returns the smallest power of 2 greater than n, or n if + * such power does not fit in a guint + */ +static guint +g_nearest_pow (gint num) +{ + guint n = 1; + + while (n < num && n > 0) + n <<= 1; + + return n ? n : num; +} + +static void +g_array_maybe_expand (GRealArray *array, + gint len) +{ + guint want_alloc = g_array_elt_len (array, array->len + len + + array->zero_terminated); + + if (want_alloc > array->alloc) + { + want_alloc = g_nearest_pow (want_alloc); + want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE); + + array->data = g_realloc (array->data, want_alloc); + + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (array->data + array->alloc, 0, want_alloc - array->alloc); + + array->alloc = want_alloc; + } +} + +/** + * SECTION:arrays_pointer + * @title: Pointer Arrays + * @short_description: arrays of pointers to any type of data, which + * grow automatically as new elements are added + * + * Pointer Arrays are similar to Arrays but are used only for storing + * pointers. + * + * If you remove elements from the array, elements at the + * end of the array are moved into the space previously occupied by the + * removed element. This means that you should not rely on the index of + * particular elements remaining the same. You should also be careful + * when deleting elements while iterating over the array. + * + * To create a pointer array, use g_ptr_array_new(). + * + * To add elements to a pointer array, use g_ptr_array_add(). + * + * To remove elements from a pointer array, use g_ptr_array_remove(), + * g_ptr_array_remove_index() or g_ptr_array_remove_index_fast(). + * + * To access an element of a pointer array, use g_ptr_array_index(). + * + * To set the size of a pointer array, use g_ptr_array_set_size(). + * + * To free a pointer array, use g_ptr_array_free(). + * + * + * Using a #GPtrArray + * + * GPtrArray *gparray; + * gchar *string1 = "one", *string2 = "two", *string3 = "three"; + * + * gparray = g_ptr_array_new (); + * g_ptr_array_add (gparray, (gpointer) string1); + * g_ptr_array_add (gparray, (gpointer) string2); + * g_ptr_array_add (gparray, (gpointer) string3); + * + * if (g_ptr_array_index (gparray, 0) != (gpointer) string1) + * g_print ("ERROR: got %p instead of %p\n", + * g_ptr_array_index (gparray, 0), string1); + * + * g_ptr_array_free (gparray, TRUE); + * + * + **/ + +typedef struct _GRealPtrArray GRealPtrArray; + +/** + * GPtrArray: + * @pdata: points to the array of pointers, which may be moved when the + * array grows. + * @len: number of pointers in the array. + * + * Contains the public fields of a pointer array. + **/ +struct _GRealPtrArray +{ + gpointer *pdata; + guint len; + guint alloc; + gint ref_count; + GDestroyNotify element_free_func; +}; + +/** + * g_ptr_array_index: + * @array: a #GPtrArray. + * @index_: the index of the pointer to return. + * @Returns: the pointer at the given index. + * + * Returns the pointer at the given index of the pointer array. + **/ + +static void g_ptr_array_maybe_expand (GRealPtrArray *array, + gint len); + +/** + * g_ptr_array_new: + * @Returns: the new #GPtrArray. + * + * Creates a new #GPtrArray with a reference count of 1. + **/ +GPtrArray* +g_ptr_array_new (void) +{ + return g_ptr_array_sized_new (0); +} + +/** + * g_ptr_array_sized_new: + * @reserved_size: number of pointers preallocated. + * @Returns: the new #GPtrArray. + * + * Creates a new #GPtrArray with @reserved_size pointers preallocated + * and a reference count of 1. This avoids frequent reallocation, if + * you are going to add many pointers to the array. Note however that + * the size of the array is still 0. + **/ +GPtrArray* +g_ptr_array_sized_new (guint reserved_size) +{ + GRealPtrArray *array = g_slice_new (GRealPtrArray); + + array->pdata = NULL; + array->len = 0; + array->alloc = 0; + array->ref_count = 1; + array->element_free_func = NULL; + + if (reserved_size != 0) + g_ptr_array_maybe_expand (array, reserved_size); + + return (GPtrArray*) array; +} + +/** + * g_ptr_array_new_with_free_func: + * @element_free_func: A function to free elements with destroy @array or %NULL. + * + * Creates a new #GPtrArray with a reference count of 1 and use @element_free_func + * for freeing each element when the array is destroyed either via + * g_ptr_array_unref(), when g_ptr_array_free() is called with @free_segment + * set to %TRUE or when removing elements. + * + * Returns: A new #GPtrArray. + * + * Since: 2.22 + **/ +GPtrArray * +g_ptr_array_new_with_free_func (GDestroyNotify element_free_func) +{ + GPtrArray *array; + + array = g_ptr_array_new (); + g_ptr_array_set_free_func (array, element_free_func); + return array; +} + +/** + * g_ptr_array_new_full: + * @reserved_size: number of pointers preallocated. + * @element_free_func: A function to free elements with destroy @array or %NULL. + * + * Creates a new #GPtrArray with @reserved_size pointers preallocated + * and a reference count of 1. This avoids frequent reallocation, if + * you are going to add many pointers to the array. Note however that + * the size of the array is still 0. It also set @element_free_func + * for freeing each element when the array is destroyed either via + * g_ptr_array_unref(), when g_ptr_array_free() is called with @free_segment + * set to %TRUE or when removing elements. + * + * Returns: A new #GPtrArray. + * + * Since: 2.30 + **/ +GPtrArray * +g_ptr_array_new_full (guint reserved_size, + GDestroyNotify element_free_func) +{ + GPtrArray *array; + + array = g_ptr_array_sized_new (reserved_size); + g_ptr_array_set_free_func (array, element_free_func); + return array; +} + +/** + * g_ptr_array_set_free_func: + * @array: A #GPtrArray. + * @element_free_func: A function to free elements with destroy @array or %NULL. + * + * Sets a function for freeing each element when @array is destroyed + * either via g_ptr_array_unref(), when g_ptr_array_free() is called + * with @free_segment set to %TRUE or when removing elements. + * + * Since: 2.22 + **/ +void +g_ptr_array_set_free_func (GPtrArray *array, + GDestroyNotify element_free_func) +{ + GRealPtrArray* rarray = (GRealPtrArray*) array; + + g_return_if_fail (array); + + rarray->element_free_func = element_free_func; +} + +/** + * g_ptr_array_ref: + * @array: A #GArray. + * + * Atomically increments the reference count of @array by one. This + * function is MT-safe and may be called from any thread. + * + * Returns: The passed in #GPtrArray. + * + * Since: 2.22 + **/ +GPtrArray * +g_ptr_array_ref (GPtrArray *array) +{ + GRealPtrArray *rarray = (GRealPtrArray*) array; + + g_return_val_if_fail (array, NULL); + + g_atomic_int_inc (&rarray->ref_count); + + return array; +} + +static gpointer *ptr_array_free (GPtrArray *, ArrayFreeFlags); + +/** + * g_ptr_array_unref: + * @array: A #GPtrArray. + * + * Atomically decrements the reference count of @array by one. If the + * reference count drops to 0, the effect is the same as calling + * g_ptr_array_free() with @free_segment set to %TRUE. This function + * is MT-safe and may be called from any thread. + * + * Since: 2.22 + **/ +void +g_ptr_array_unref (GPtrArray *array) +{ + GRealPtrArray *rarray = (GRealPtrArray*) array; + g_return_if_fail (array); + + if (g_atomic_int_dec_and_test (&rarray->ref_count)) + ptr_array_free (array, FREE_SEGMENT); +} + +/** + * g_ptr_array_free: + * @array: a #GPtrArray. + * @free_seg: if %TRUE the actual pointer array is freed as well. + * @Returns: the pointer array if @free_seg is %FALSE, otherwise %NULL. + * The pointer array should be freed using g_free(). + * + * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE + * it frees the memory block holding the elements as well. Pass %FALSE + * if you want to free the #GPtrArray wrapper but preserve the + * underlying array for use elsewhere. If the reference count of @array + * is greater than one, the #GPtrArray wrapper is preserved but the + * size of @array will be set to zero. + * + * If array contents point to dynamically-allocated + * memory, they should be freed separately if @free_seg is %TRUE and no + * #GDestroyNotify function has been set for @array. + **/ +gpointer* +g_ptr_array_free (GPtrArray *farray, + gboolean free_segment) +{ + GRealPtrArray *array = (GRealPtrArray*) farray; + ArrayFreeFlags flags; + + g_return_val_if_fail (array, NULL); + + flags = (free_segment ? FREE_SEGMENT : 0); + + /* if others are holding a reference, preserve the wrapper but do free/return the data */ + if (!g_atomic_int_dec_and_test (&array->ref_count)) + flags |= PRESERVE_WRAPPER; + + return ptr_array_free (farray, flags); +} + +static gpointer * +ptr_array_free (GPtrArray *farray, + ArrayFreeFlags flags) +{ + GRealPtrArray *array = (GRealPtrArray*) farray; + gpointer *segment; + + if (flags & FREE_SEGMENT) + { + if (array->element_free_func != NULL) + g_ptr_array_foreach (farray, (GFunc) array->element_free_func, NULL); + g_free (array->pdata); + segment = NULL; + } + else + segment = array->pdata; + + if (flags & PRESERVE_WRAPPER) + { + array->pdata = NULL; + array->len = 0; + array->alloc = 0; + } + else + { + g_slice_free1 (sizeof (GRealPtrArray), array); + } + + return segment; +} + +static void +g_ptr_array_maybe_expand (GRealPtrArray *array, + gint len) +{ + if ((array->len + len) > array->alloc) + { + guint old_alloc = array->alloc; + array->alloc = g_nearest_pow (array->len + len); + array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE); + array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc); + if (G_UNLIKELY (g_mem_gc_friendly)) + for ( ; old_alloc < array->alloc; old_alloc++) + array->pdata [old_alloc] = NULL; + } +} + +/** + * g_ptr_array_set_size: + * @array: a #GPtrArray. + * @length: the new length of the pointer array. + * + * Sets the size of the array. When making the array larger, + * newly-added elements will be set to %NULL. When making it smaller, + * if @array has a non-%NULL #GDestroyNotify function then it will be + * called for the removed elements. + **/ +void +g_ptr_array_set_size (GPtrArray *farray, + gint length) +{ + GRealPtrArray* array = (GRealPtrArray*) farray; + + g_return_if_fail (array); + + if (length > array->len) + { + int i; + g_ptr_array_maybe_expand (array, (length - array->len)); + /* This is not + * memset (array->pdata + array->len, 0, + * sizeof (gpointer) * (length - array->len)); + * to make it really portable. Remember (void*)NULL needn't be + * bitwise zero. It of course is silly not to use memset (..,0,..). + */ + for (i = array->len; i < length; i++) + array->pdata[i] = NULL; + } + else if (length < array->len) + g_ptr_array_remove_range (farray, length, array->len - length); + + array->len = length; +} + +/** + * g_ptr_array_remove_index: + * @array: a #GPtrArray. + * @index_: the index of the pointer to remove. + * @Returns: the pointer which was removed. + * + * Removes the pointer at the given index from the pointer array. The + * following elements are moved down one place. If @array has a + * non-%NULL #GDestroyNotify function it is called for the removed + * element. + **/ +gpointer +g_ptr_array_remove_index (GPtrArray *farray, + guint index_) +{ + GRealPtrArray* array = (GRealPtrArray*) farray; + gpointer result; + + g_return_val_if_fail (array, NULL); + + g_return_val_if_fail (index_ < array->len, NULL); + + result = array->pdata[index_]; + + if (array->element_free_func != NULL) + array->element_free_func (array->pdata[index_]); + + if (index_ != array->len - 1) + g_memmove (array->pdata + index_, array->pdata + index_ + 1, + sizeof (gpointer) * (array->len - index_ - 1)); + + array->len -= 1; + + if (G_UNLIKELY (g_mem_gc_friendly)) + array->pdata[array->len] = NULL; + + return result; +} + +/** + * g_ptr_array_remove_index_fast: + * @array: a #GPtrArray. + * @index_: the index of the pointer to remove. + * @Returns: the pointer which was removed. + * + * Removes the pointer at the given index from the pointer array. The + * last element in the array is used to fill in the space, so this + * function does not preserve the order of the array. But it is faster + * than g_ptr_array_remove_index(). If @array has a non-%NULL + * #GDestroyNotify function it is called for the removed element. + **/ +gpointer +g_ptr_array_remove_index_fast (GPtrArray *farray, + guint index_) +{ + GRealPtrArray* array = (GRealPtrArray*) farray; + gpointer result; + + g_return_val_if_fail (array, NULL); + + g_return_val_if_fail (index_ < array->len, NULL); + + result = array->pdata[index_]; + + if (array->element_free_func != NULL) + array->element_free_func (array->pdata[index_]); + + if (index_ != array->len - 1) + array->pdata[index_] = array->pdata[array->len - 1]; + + array->len -= 1; + + if (G_UNLIKELY (g_mem_gc_friendly)) + array->pdata[array->len] = NULL; + + return result; +} + +/** + * g_ptr_array_remove_range: + * @array: a @GPtrArray. + * @index_: the index of the first pointer to remove. + * @length: the number of pointers to remove. + * + * Removes the given number of pointers starting at the given index + * from a #GPtrArray. The following elements are moved to close the + * gap. If @array has a non-%NULL #GDestroyNotify function it is called + * for the removed elements. + * + * Since: 2.4 + **/ +void +g_ptr_array_remove_range (GPtrArray *farray, + guint index_, + guint length) +{ + GRealPtrArray* array = (GRealPtrArray*) farray; + guint n; + + g_return_if_fail (array); + g_return_if_fail (index_ < array->len); + g_return_if_fail (index_ + length <= array->len); + + if (array->element_free_func != NULL) + { + for (n = index_; n < index_ + length; n++) + array->element_free_func (array->pdata[n]); + } + + if (index_ + length != array->len) + { + g_memmove (&array->pdata[index_], + &array->pdata[index_ + length], + (array->len - (index_ + length)) * sizeof (gpointer)); + } + + array->len -= length; + if (G_UNLIKELY (g_mem_gc_friendly)) + { + guint i; + for (i = 0; i < length; i++) + array->pdata[array->len + i] = NULL; + } +} + +/** + * g_ptr_array_remove: + * @array: a #GPtrArray. + * @data: the pointer to remove. + * @Returns: %TRUE if the pointer is removed. %FALSE if the pointer is + * not found in the array. + * + * Removes the first occurrence of the given pointer from the pointer + * array. The following elements are moved down one place. If @array + * has a non-%NULL #GDestroyNotify function it is called for the + * removed element. + * + * It returns %TRUE if the pointer was removed, or %FALSE if the + * pointer was not found. + **/ +gboolean +g_ptr_array_remove (GPtrArray *farray, + gpointer data) +{ + GRealPtrArray* array = (GRealPtrArray*) farray; + guint i; + + g_return_val_if_fail (array, FALSE); + + for (i = 0; i < array->len; i += 1) + { + if (array->pdata[i] == data) + { + g_ptr_array_remove_index (farray, i); + return TRUE; + } + } + + return FALSE; +} + +/** + * g_ptr_array_remove_fast: + * @array: a #GPtrArray. + * @data: the pointer to remove. + * @Returns: %TRUE if the pointer was found in the array. + * + * Removes the first occurrence of the given pointer from the pointer + * array. The last element in the array is used to fill in the space, + * so this function does not preserve the order of the array. But it is + * faster than g_ptr_array_remove(). If @array has a non-%NULL + * #GDestroyNotify function it is called for the removed element. + * + * It returns %TRUE if the pointer was removed, or %FALSE if the + * pointer was not found. + **/ +gboolean +g_ptr_array_remove_fast (GPtrArray *farray, + gpointer data) +{ + GRealPtrArray* array = (GRealPtrArray*) farray; + guint i; + + g_return_val_if_fail (array, FALSE); + + for (i = 0; i < array->len; i += 1) + { + if (array->pdata[i] == data) + { + g_ptr_array_remove_index_fast (farray, i); + return TRUE; + } + } + + return FALSE; +} + +/** + * g_ptr_array_add: + * @array: a #GPtrArray. + * @data: the pointer to add. + * + * Adds a pointer to the end of the pointer array. The array will grow + * in size automatically if necessary. + **/ +void +g_ptr_array_add (GPtrArray *farray, + gpointer data) +{ + GRealPtrArray* array = (GRealPtrArray*) farray; + + g_return_if_fail (array); + + g_ptr_array_maybe_expand (array, 1); + + array->pdata[array->len++] = data; +} + +/** + * g_ptr_array_sort: + * @array: a #GPtrArray. + * @compare_func: comparison function. + * + * Sorts the array, using @compare_func which should be a qsort()-style + * comparison function (returns less than zero for first arg is less + * than second arg, zero for equal, greater than zero if irst arg is + * greater than second arg). + * + * The comparison function for g_ptr_array_sort() doesn't + * take the pointers from the array as arguments, it takes pointers to + * the pointers in the array. + * + * This is guaranteed to be a stable sort since version 2.32. + **/ +void +g_ptr_array_sort (GPtrArray *array, + GCompareFunc compare_func) +{ + g_return_if_fail (array != NULL); + + /* Don't use qsort as we want a guaranteed stable sort */ + g_qsort_with_data (array->pdata, + array->len, + sizeof (gpointer), + (GCompareDataFunc)compare_func, + NULL); +} + +/** + * g_ptr_array_sort_with_data: + * @array: a #GPtrArray. + * @compare_func: comparison function. + * @user_data: data to pass to @compare_func. + * + * Like g_ptr_array_sort(), but the comparison function has an extra + * user data argument. + * + * The comparison function for g_ptr_array_sort_with_data() + * doesn't take the pointers from the array as arguments, it takes + * pointers to the pointers in the array. + * + * This is guaranteed to be a stable sort since version 2.32. + **/ +void +g_ptr_array_sort_with_data (GPtrArray *array, + GCompareDataFunc compare_func, + gpointer user_data) +{ + g_return_if_fail (array != NULL); + + g_qsort_with_data (array->pdata, + array->len, + sizeof (gpointer), + compare_func, + user_data); +} + +/** + * g_ptr_array_foreach: + * @array: a #GPtrArray + * @func: the function to call for each array element + * @user_data: user data to pass to the function + * + * Calls a function for each element of a #GPtrArray. + * + * Since: 2.4 + **/ +void +g_ptr_array_foreach (GPtrArray *array, + GFunc func, + gpointer user_data) +{ + guint i; + + g_return_if_fail (array); + + for (i = 0; i < array->len; i++) + (*func) (array->pdata[i], user_data); +} + +/** + * SECTION:arrays_byte + * @title: Byte Arrays + * @short_description: arrays of bytes + * + * #GByteArray is a mutable array of bytes based on #GArray, to provide arrays + * of bytes which grow automatically as elements are added. + * + * To create a new #GByteArray use g_byte_array_new(). To add elements to a + * #GByteArray, use g_byte_array_append(), and g_byte_array_prepend(). + * + * To set the size of a #GByteArray, use g_byte_array_set_size(). + * + * To free a #GByteArray, use g_byte_array_free(). + * + * + * Using a #GByteArray + * + * GByteArray *gbarray; + * gint i; + * + * gbarray = g_byte_array_new (); + * for (i = 0; i < 10000; i++) + * g_byte_array_append (gbarray, (guint8*) "abcd", 4); + * + * for (i = 0; i < 10000; i++) + * { + * g_assert (gbarray->data[4*i] == 'a'); + * g_assert (gbarray->data[4*i+1] == 'b'); + * g_assert (gbarray->data[4*i+2] == 'c'); + * g_assert (gbarray->data[4*i+3] == 'd'); + * } + * + * g_byte_array_free (gbarray, TRUE); + * + * + * + * See #GBytes if you are interested in an immutable object representing a + * sequence of bytes. + **/ + +/** + * GByteArray: + * @data: a pointer to the element data. The data may be moved as + * elements are added to the #GByteArray. + * @len: the number of elements in the #GByteArray. + * + * The GByteArray struct allows access to the + * public fields of a GByteArray. + **/ + +/** + * g_byte_array_new: + * @Returns: the new #GByteArray. + * + * Creates a new #GByteArray with a reference count of 1. + **/ +GByteArray* g_byte_array_new (void) +{ + return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, 0); +} + +/** + * g_byte_array_new_take: + * @data: (array length=len): byte data for the array + * @len: length of @data + * + * Create byte array containing the data. The data will be owned by the array + * and will be freed with g_free(), i.e. it could be allocated using g_strdup(). + * + * Since: 2.32 + * + * Returns: (transfer full): a new #GByteArray + */ +GByteArray * +g_byte_array_new_take (guint8 *data, + gsize len) +{ + GByteArray *array; + GRealArray *real; + + array = g_byte_array_new (); + real = (GRealArray *)array; + g_assert (real->data == NULL); + g_assert (real->len == 0); + + real->data = data; + real->len = len; + + return array; +} + +/** + * g_byte_array_sized_new: + * @reserved_size: number of bytes preallocated. + * @Returns: the new #GByteArray. + * + * Creates a new #GByteArray with @reserved_size bytes preallocated. + * This avoids frequent reallocation, if you are going to add many + * bytes to the array. Note however that the size of the array is still + * 0. + **/ +GByteArray* g_byte_array_sized_new (guint reserved_size) +{ + return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, reserved_size); +} + +/** + * g_byte_array_free: + * @array: a #GByteArray. + * @free_segment: if %TRUE the actual byte data is freed as well. + * @Returns: the element data if @free_segment is %FALSE, otherwise + * %NULL. The element data should be freed using g_free(). + * + * Frees the memory allocated by the #GByteArray. If @free_segment is + * %TRUE it frees the actual byte data. If the reference count of + * @array is greater than one, the #GByteArray wrapper is preserved but + * the size of @array will be set to zero. + **/ +guint8* g_byte_array_free (GByteArray *array, + gboolean free_segment) +{ + return (guint8*) g_array_free ((GArray*) array, free_segment); +} + +/** + * g_byte_array_free_to_bytes: + * @array: (transfer full): a #GByteArray + * + * Transfers the data from the #GByteArray into a new immutable #GBytes. + * + * The #GByteArray is freed unless the reference count of @array is greater + * than one, the #GByteArray wrapper is preserved but the size of @array + * will be set to zero. + * + * This is identical to using g_bytes_new_take() and g_byte_array_free() + * together. + * + * Since: 2.32 + * + * Returns: (transfer full): a new immutable #GBytes representing same byte + * data that was in the array + */ +GBytes * +g_byte_array_free_to_bytes (GByteArray *array) +{ + gsize length; + + g_return_val_if_fail (array != NULL, NULL); + + length = array->len; + return g_bytes_new_take (g_byte_array_free (array, FALSE), length); +} + +/** + * g_byte_array_ref: + * @array: A #GByteArray. + * + * Atomically increments the reference count of @array by one. This + * function is MT-safe and may be called from any thread. + * + * Returns: The passed in #GByteArray. + * + * Since: 2.22 + **/ +GByteArray * +g_byte_array_ref (GByteArray *array) +{ + return (GByteArray *) g_array_ref ((GArray *) array); +} + +/** + * g_byte_array_unref: + * @array: A #GByteArray. + * + * Atomically decrements the reference count of @array by one. If the + * reference count drops to 0, all memory allocated by the array is + * released. This function is MT-safe and may be called from any + * thread. + * + * Since: 2.22 + **/ +void +g_byte_array_unref (GByteArray *array) +{ + g_array_unref ((GArray *) array); +} + +/** + * g_byte_array_append: + * @array: a #GByteArray. + * @data: the byte data to be added. + * @len: the number of bytes to add. + * @Returns: the #GByteArray. + * + * Adds the given bytes to the end of the #GByteArray. The array will + * grow in size automatically if necessary. + **/ +GByteArray* g_byte_array_append (GByteArray *array, + const guint8 *data, + guint len) +{ + g_array_append_vals ((GArray*) array, (guint8*)data, len); + + return array; +} + +/** + * g_byte_array_prepend: + * @array: a #GByteArray. + * @data: the byte data to be added. + * @len: the number of bytes to add. + * @Returns: the #GByteArray. + * + * Adds the given data to the start of the #GByteArray. The array will + * grow in size automatically if necessary. + **/ +GByteArray* g_byte_array_prepend (GByteArray *array, + const guint8 *data, + guint len) +{ + g_array_prepend_vals ((GArray*) array, (guint8*)data, len); + + return array; +} + +/** + * g_byte_array_set_size: + * @array: a #GByteArray. + * @length: the new size of the #GByteArray. + * @Returns: the #GByteArray. + * + * Sets the size of the #GByteArray, expanding it if necessary. + **/ +GByteArray* g_byte_array_set_size (GByteArray *array, + guint length) +{ + g_array_set_size ((GArray*) array, length); + + return array; +} + +/** + * g_byte_array_remove_index: + * @array: a #GByteArray. + * @index_: the index of the byte to remove. + * @Returns: the #GByteArray. + * + * Removes the byte at the given index from a #GByteArray. The + * following bytes are moved down one place. + **/ +GByteArray* g_byte_array_remove_index (GByteArray *array, + guint index_) +{ + g_array_remove_index ((GArray*) array, index_); + + return array; +} + +/** + * g_byte_array_remove_index_fast: + * @array: a #GByteArray. + * @index_: the index of the byte to remove. + * @Returns: the #GByteArray. + * + * Removes the byte at the given index from a #GByteArray. The last + * element in the array is used to fill in the space, so this function + * does not preserve the order of the #GByteArray. But it is faster + * than g_byte_array_remove_index(). + **/ +GByteArray* g_byte_array_remove_index_fast (GByteArray *array, + guint index_) +{ + g_array_remove_index_fast ((GArray*) array, index_); + + return array; +} + +/** + * g_byte_array_remove_range: + * @array: a @GByteArray. + * @index_: the index of the first byte to remove. + * @length: the number of bytes to remove. + * @Returns: the #GByteArray. + * + * Removes the given number of bytes starting at the given index from a + * #GByteArray. The following elements are moved to close the gap. + * + * Since: 2.4 + **/ +GByteArray* +g_byte_array_remove_range (GByteArray *array, + guint index_, + guint length) +{ + g_return_val_if_fail (array, NULL); + g_return_val_if_fail (index_ < array->len, NULL); + g_return_val_if_fail (index_ + length <= array->len, NULL); + + return (GByteArray *)g_array_remove_range ((GArray*) array, index_, length); +} + +/** + * g_byte_array_sort: + * @array: a #GByteArray. + * @compare_func: comparison function. + * + * Sorts a byte array, using @compare_func which should be a + * qsort()-style comparison function (returns less than zero for first + * arg is less than second arg, zero for equal, greater than zero if + * first arg is greater than second arg). + * + * If two array elements compare equal, their order in the sorted array + * is undefined. If you want equal elements to keep their order (i.e. + * you want a stable sort) you can write a comparison function that, + * if two elements would otherwise compare equal, compares them by + * their addresses. + **/ +void +g_byte_array_sort (GByteArray *array, + GCompareFunc compare_func) +{ + g_array_sort ((GArray *) array, compare_func); +} + +/** + * g_byte_array_sort_with_data: + * @array: a #GByteArray. + * @compare_func: comparison function. + * @user_data: data to pass to @compare_func. + * + * Like g_byte_array_sort(), but the comparison function takes an extra + * user data argument. + **/ +void +g_byte_array_sort_with_data (GByteArray *array, + GCompareDataFunc compare_func, + gpointer user_data) +{ + g_array_sort_with_data ((GArray *) array, compare_func, user_data); +} diff --git a/glib/glib/garray.h b/glib/glib/garray.h new file mode 100644 index 0000000..eb37b92 --- /dev/null +++ b/glib/glib/garray.h @@ -0,0 +1,187 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_ARRAY_H__ +#define __G_ARRAY_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GBytes GBytes; +typedef struct _GArray GArray; +typedef struct _GByteArray GByteArray; +typedef struct _GPtrArray GPtrArray; + +struct _GArray +{ + gchar *data; + guint len; +}; + +struct _GByteArray +{ + guint8 *data; + guint len; +}; + +struct _GPtrArray +{ + gpointer *pdata; + guint len; +}; + +/* Resizable arrays. remove fills any cleared spot and shortens the + * array, while preserving the order. remove_fast will distort the + * order by moving the last element to the position of the removed. + */ + +#define g_array_append_val(a,v) g_array_append_vals (a, &(v), 1) +#define g_array_prepend_val(a,v) g_array_prepend_vals (a, &(v), 1) +#define g_array_insert_val(a,i,v) g_array_insert_vals (a, i, &(v), 1) +#define g_array_index(a,t,i) (((t*) (void *) (a)->data) [(i)]) + +GArray* g_array_new (gboolean zero_terminated, + gboolean clear_, + guint element_size); +GArray* g_array_sized_new (gboolean zero_terminated, + gboolean clear_, + guint element_size, + guint reserved_size); +gchar* g_array_free (GArray *array, + gboolean free_segment); +GArray *g_array_ref (GArray *array); +void g_array_unref (GArray *array); +guint g_array_get_element_size (GArray *array); +GArray* g_array_append_vals (GArray *array, + gconstpointer data, + guint len); +GArray* g_array_prepend_vals (GArray *array, + gconstpointer data, + guint len); +GArray* g_array_insert_vals (GArray *array, + guint index_, + gconstpointer data, + guint len); +GArray* g_array_set_size (GArray *array, + guint length); +GArray* g_array_remove_index (GArray *array, + guint index_); +GArray* g_array_remove_index_fast (GArray *array, + guint index_); +GArray* g_array_remove_range (GArray *array, + guint index_, + guint length); +void g_array_sort (GArray *array, + GCompareFunc compare_func); +void g_array_sort_with_data (GArray *array, + GCompareDataFunc compare_func, + gpointer user_data); +void g_array_set_clear_func (GArray *array, + GDestroyNotify clear_func); + +/* Resizable pointer array. This interface is much less complicated + * than the above. Add appends a pointer. Remove fills any cleared + * spot and shortens the array. remove_fast will again distort order. + */ +#define g_ptr_array_index(array,index_) ((array)->pdata)[index_] +GPtrArray* g_ptr_array_new (void); +GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify element_free_func); +GPtrArray* g_ptr_array_sized_new (guint reserved_size); +GPtrArray* g_ptr_array_new_full (guint reserved_size, + GDestroyNotify element_free_func); +gpointer* g_ptr_array_free (GPtrArray *array, + gboolean free_seg); +GPtrArray* g_ptr_array_ref (GPtrArray *array); +void g_ptr_array_unref (GPtrArray *array); +void g_ptr_array_set_free_func (GPtrArray *array, + GDestroyNotify element_free_func); +void g_ptr_array_set_size (GPtrArray *array, + gint length); +gpointer g_ptr_array_remove_index (GPtrArray *array, + guint index_); +gpointer g_ptr_array_remove_index_fast (GPtrArray *array, + guint index_); +gboolean g_ptr_array_remove (GPtrArray *array, + gpointer data); +gboolean g_ptr_array_remove_fast (GPtrArray *array, + gpointer data); +void g_ptr_array_remove_range (GPtrArray *array, + guint index_, + guint length); +void g_ptr_array_add (GPtrArray *array, + gpointer data); +void g_ptr_array_sort (GPtrArray *array, + GCompareFunc compare_func); +void g_ptr_array_sort_with_data (GPtrArray *array, + GCompareDataFunc compare_func, + gpointer user_data); +void g_ptr_array_foreach (GPtrArray *array, + GFunc func, + gpointer user_data); + + +/* Byte arrays, an array of guint8. Implemented as a GArray, + * but type-safe. + */ + +GByteArray* g_byte_array_new (void); +GByteArray* g_byte_array_new_take (guint8 *data, + gsize len); +GByteArray* g_byte_array_sized_new (guint reserved_size); +guint8* g_byte_array_free (GByteArray *array, + gboolean free_segment); +GBytes* g_byte_array_free_to_bytes (GByteArray *array); +GByteArray *g_byte_array_ref (GByteArray *array); +void g_byte_array_unref (GByteArray *array); +GByteArray* g_byte_array_append (GByteArray *array, + const guint8 *data, + guint len); +GByteArray* g_byte_array_prepend (GByteArray *array, + const guint8 *data, + guint len); +GByteArray* g_byte_array_set_size (GByteArray *array, + guint length); +GByteArray* g_byte_array_remove_index (GByteArray *array, + guint index_); +GByteArray* g_byte_array_remove_index_fast (GByteArray *array, + guint index_); +GByteArray* g_byte_array_remove_range (GByteArray *array, + guint index_, + guint length); +void g_byte_array_sort (GByteArray *array, + GCompareFunc compare_func); +void g_byte_array_sort_with_data (GByteArray *array, + GCompareDataFunc compare_func, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_ARRAY_H__ */ diff --git a/glib/glib/gasyncqueue.c b/glib/glib/gasyncqueue.c new file mode 100644 index 0000000..31976bc --- /dev/null +++ b/glib/glib/gasyncqueue.c @@ -0,0 +1,802 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GAsyncQueue: asynchronous queue implementation, based on GQueue. + * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "gasyncqueue.h" +#include "gasyncqueueprivate.h" + +#include "gmain.h" +#include "gmem.h" +#include "gqueue.h" +#include "gtestutils.h" +#include "gtimer.h" +#include "gthread.h" +#include "deprecated/gthread.h" + + +/** + * SECTION:async_queues + * @title: Asynchronous Queues + * @short_description: asynchronous communication between threads + * @see_also: #GThreadPool + * + * Often you need to communicate between different threads. In general + * it's safer not to do this by shared memory, but by explicit message + * passing. These messages only make sense asynchronously for + * multi-threaded applications though, as a synchronous operation could + * as well be done in the same thread. + * + * Asynchronous queues are an exception from most other GLib data + * structures, as they can be used simultaneously from multiple threads + * without explicit locking and they bring their own builtin reference + * counting. This is because the nature of an asynchronous queue is that + * it will always be used by at least 2 concurrent threads. + * + * For using an asynchronous queue you first have to create one with + * g_async_queue_new(). #GAsyncQueue structs are reference counted, + * use g_async_queue_ref() and g_async_queue_unref() to manage your + * references. + * + * A thread which wants to send a message to that queue simply calls + * g_async_queue_push() to push the message to the queue. + * + * A thread which is expecting messages from an asynchronous queue + * simply calls g_async_queue_pop() for that queue. If no message is + * available in the queue at that point, the thread is now put to sleep + * until a message arrives. The message will be removed from the queue + * and returned. The functions g_async_queue_try_pop() and + * g_async_queue_timeout_pop() can be used to only check for the presence + * of messages or to only wait a certain time for messages respectively. + * + * For almost every function there exist two variants, one that locks + * the queue and one that doesn't. That way you can hold the queue lock + * (acquire it with g_async_queue_lock() and release it with + * g_async_queue_unlock()) over multiple queue accessing instructions. + * This can be necessary to ensure the integrity of the queue, but should + * only be used when really necessary, as it can make your life harder + * if used unwisely. Normally you should only use the locking function + * variants (those without the _unlocked suffix). + * + * In many cases, it may be more convenient to use #GThreadPool when + * you need to distribute work to a set of worker threads instead of + * using #GAsyncQueue manually. #GThreadPool uses a GAsyncQueue + * internally. + */ + +/** + * GAsyncQueue: + * + * The GAsyncQueue struct is an opaque data structure which represents + * an asynchronous queue. It should only be accessed through the + * g_async_queue_* functions. + */ +struct _GAsyncQueue +{ + GMutex mutex; + GCond cond; + GQueue queue; + GDestroyNotify item_free_func; + guint waiting_threads; + gint ref_count; +}; + +typedef struct +{ + GCompareDataFunc func; + gpointer user_data; +} SortData; + +/** + * g_async_queue_new: + * + * Creates a new asynchronous queue. + * + * Return value: a new #GAsyncQueue. Free with g_async_queue_unref() + */ +GAsyncQueue * +g_async_queue_new (void) +{ + return g_async_queue_new_full (NULL); +} + +/** + * g_async_queue_new_full: + * @item_free_func: function to free queue elements + * + * Creates a new asynchronous queue and sets up a destroy notify + * function that is used to free any remaining queue items when + * the queue is destroyed after the final unref. + * + * Return value: a new #GAsyncQueue. Free with g_async_queue_unref() + * + * Since: 2.16 + */ +GAsyncQueue * +g_async_queue_new_full (GDestroyNotify item_free_func) +{ + GAsyncQueue *queue; + + queue = g_new (GAsyncQueue, 1); + g_mutex_init (&queue->mutex); + g_cond_init (&queue->cond); + g_queue_init (&queue->queue); + queue->waiting_threads = 0; + queue->ref_count = 1; + queue->item_free_func = item_free_func; + + return queue; +} + +/** + * g_async_queue_ref: + * @queue: a #GAsyncQueue + * + * Increases the reference count of the asynchronous @queue by 1. + * You do not need to hold the lock to call this function. + * + * Returns: the @queue that was passed in (since 2.6) + */ +GAsyncQueue * +g_async_queue_ref (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + + g_atomic_int_inc (&queue->ref_count); + + return queue; +} + +/** + * g_async_queue_ref_unlocked: + * @queue: a #GAsyncQueue + * + * Increases the reference count of the asynchronous @queue by 1. + * + * @Deprecated: Since 2.8, reference counting is done atomically + * so g_async_queue_ref() can be used regardless of the @queue's + * lock. + */ +void +g_async_queue_ref_unlocked (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + g_atomic_int_inc (&queue->ref_count); +} + +/** + * g_async_queue_unref_and_unlock: + * @queue: a #GAsyncQueue + * + * Decreases the reference count of the asynchronous @queue by 1 + * and releases the lock. This function must be called while holding + * the @queue's lock. If the reference count went to 0, the @queue + * will be destroyed and the memory allocated will be freed. + * + * @Deprecated: Since 2.8, reference counting is done atomically + * so g_async_queue_unref() can be used regardless of the @queue's + * lock. + */ +void +g_async_queue_unref_and_unlock (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + g_mutex_unlock (&queue->mutex); + g_async_queue_unref (queue); +} + +/** + * g_async_queue_unref: + * @queue: a #GAsyncQueue. + * + * Decreases the reference count of the asynchronous @queue by 1. + * + * If the reference count went to 0, the @queue will be destroyed + * and the memory allocated will be freed. So you are not allowed + * to use the @queue afterwards, as it might have disappeared. + * You do not need to hold the lock to call this function. + */ +void +g_async_queue_unref (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + if (g_atomic_int_dec_and_test (&queue->ref_count)) + { + g_return_if_fail (queue->waiting_threads == 0); + g_mutex_clear (&queue->mutex); + g_cond_clear (&queue->cond); + if (queue->item_free_func) + g_queue_foreach (&queue->queue, (GFunc) queue->item_free_func, NULL); + g_queue_clear (&queue->queue); + g_free (queue); + } +} + +/** + * g_async_queue_lock: + * @queue: a #GAsyncQueue + * + * Acquires the @queue's lock. If another thread is already + * holding the lock, this call will block until the lock + * becomes available. + * + * Call g_async_queue_unlock() to drop the lock again. + * + * While holding the lock, you can only call the + * g_async_queue_*_unlocked() functions + * on @queue. Otherwise, deadlock may occur. + */ +void +g_async_queue_lock (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + g_mutex_lock (&queue->mutex); +} + +/** + * g_async_queue_unlock: + * @queue: a #GAsyncQueue + * + * Releases the queue's lock. + * + * Calling this function when you have not acquired + * the with g_async_queue_lock() leads to undefined + * behaviour. + */ +void +g_async_queue_unlock (GAsyncQueue *queue) +{ + g_return_if_fail (queue); + + g_mutex_unlock (&queue->mutex); +} + +/** + * g_async_queue_push: + * @queue: a #GAsyncQueue + * @data: @data to push into the @queue + * + * Pushes the @data into the @queue. @data must not be %NULL. + */ +void +g_async_queue_push (GAsyncQueue *queue, + gpointer data) +{ + g_return_if_fail (queue); + g_return_if_fail (data); + + g_mutex_lock (&queue->mutex); + g_async_queue_push_unlocked (queue, data); + g_mutex_unlock (&queue->mutex); +} + +/** + * g_async_queue_push_unlocked: + * @queue: a #GAsyncQueue + * @data: @data to push into the @queue + * + * Pushes the @data into the @queue. @data must not be %NULL. + * + * This function must be called while holding the @queue's lock. + */ +void +g_async_queue_push_unlocked (GAsyncQueue *queue, + gpointer data) +{ + g_return_if_fail (queue); + g_return_if_fail (data); + + g_queue_push_head (&queue->queue, data); + if (queue->waiting_threads > 0) + g_cond_signal (&queue->cond); +} + +/** + * g_async_queue_push_sorted: + * @queue: a #GAsyncQueue + * @data: the @data to push into the @queue + * @func: the #GCompareDataFunc is used to sort @queue + * @user_data: user data passed to @func. + * + * Inserts @data into @queue using @func to determine the new + * position. + * + * This function requires that the @queue is sorted before pushing on + * new elements, see g_async_queue_sort(). + * + * This function will lock @queue before it sorts the queue and unlock + * it when it is finished. + * + * For an example of @func see g_async_queue_sort(). + * + * Since: 2.10 + */ +void +g_async_queue_push_sorted (GAsyncQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data) +{ + g_return_if_fail (queue != NULL); + + g_mutex_lock (&queue->mutex); + g_async_queue_push_sorted_unlocked (queue, data, func, user_data); + g_mutex_unlock (&queue->mutex); +} + +static gint +g_async_queue_invert_compare (gpointer v1, + gpointer v2, + SortData *sd) +{ + return -sd->func (v1, v2, sd->user_data); +} + +/** + * g_async_queue_push_sorted_unlocked: + * @queue: a #GAsyncQueue + * @data: the @data to push into the @queue + * @func: the #GCompareDataFunc is used to sort @queue + * @user_data: user data passed to @func. + * + * Inserts @data into @queue using @func to determine the new + * position. + * + * The sort function @func is passed two elements of the @queue. + * It should return 0 if they are equal, a negative value if the + * first element should be higher in the @queue or a positive value + * if the first element should be lower in the @queue than the second + * element. + * + * This function requires that the @queue is sorted before pushing on + * new elements, see g_async_queue_sort(). + * + * This function must be called while holding the @queue's lock. + * + * For an example of @func see g_async_queue_sort(). + * + * Since: 2.10 + */ +void +g_async_queue_push_sorted_unlocked (GAsyncQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data) +{ + SortData sd; + + g_return_if_fail (queue != NULL); + + sd.func = func; + sd.user_data = user_data; + + g_queue_insert_sorted (&queue->queue, + data, + (GCompareDataFunc)g_async_queue_invert_compare, + &sd); + if (queue->waiting_threads > 0) + g_cond_signal (&queue->cond); +} + +static gpointer +g_async_queue_pop_intern_unlocked (GAsyncQueue *queue, + gboolean wait, + gint64 end_time) +{ + gpointer retval; + + if (!g_queue_peek_tail_link (&queue->queue) && wait) + { + queue->waiting_threads++; + while (!g_queue_peek_tail_link (&queue->queue)) + { + if (end_time == -1) + g_cond_wait (&queue->cond, &queue->mutex); + else + { + if (!g_cond_wait_until (&queue->cond, &queue->mutex, end_time)) + break; + } + } + queue->waiting_threads--; + } + + retval = g_queue_pop_tail (&queue->queue); + + g_assert (retval || !wait || end_time > 0); + + return retval; +} + +/** + * g_async_queue_pop: + * @queue: a #GAsyncQueue + * + * Pops data from the @queue. If @queue is empty, this function + * blocks until data becomes available. + * + * Return value: data from the queue + */ +gpointer +g_async_queue_pop (GAsyncQueue *queue) +{ + gpointer retval; + + g_return_val_if_fail (queue, NULL); + + g_mutex_lock (&queue->mutex); + retval = g_async_queue_pop_intern_unlocked (queue, TRUE, -1); + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_pop_unlocked: + * @queue: a #GAsyncQueue + * + * Pops data from the @queue. If @queue is empty, this function + * blocks until data becomes available. + * + * This function must be called while holding the @queue's lock. + * + * Return value: data from the queue. + */ +gpointer +g_async_queue_pop_unlocked (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + + return g_async_queue_pop_intern_unlocked (queue, TRUE, -1); +} + +/** + * g_async_queue_try_pop: + * @queue: a #GAsyncQueue + * + * Tries to pop data from the @queue. If no data is available, + * %NULL is returned. + * + * Return value: data from the queue or %NULL, when no data is + * available immediately. + */ +gpointer +g_async_queue_try_pop (GAsyncQueue *queue) +{ + gpointer retval; + + g_return_val_if_fail (queue, NULL); + + g_mutex_lock (&queue->mutex); + retval = g_async_queue_pop_intern_unlocked (queue, FALSE, -1); + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_try_pop_unlocked: + * @queue: a #GAsyncQueue + * + * Tries to pop data from the @queue. If no data is available, + * %NULL is returned. + * + * This function must be called while holding the @queue's lock. + * + * Return value: data from the queue or %NULL, when no data is + * available immediately. + */ +gpointer +g_async_queue_try_pop_unlocked (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + + return g_async_queue_pop_intern_unlocked (queue, FALSE, -1); +} + +/** + * g_async_queue_timeout_pop: + * @queue: a #GAsyncQueue + * @timeout: the number of microseconds to wait + * + * Pops data from the @queue. If the queue is empty, blocks for + * @timeout microseconds, or until data becomes available. + * + * If no data is received before the timeout, %NULL is returned. + * + * Return value: data from the queue or %NULL, when no data is + * received before the timeout. + */ +gpointer +g_async_queue_timeout_pop (GAsyncQueue *queue, + guint64 timeout) +{ + gint64 end_time = g_get_monotonic_time () + timeout; + gpointer retval; + + g_mutex_lock (&queue->mutex); + retval = g_async_queue_pop_intern_unlocked (queue, TRUE, end_time); + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_timeout_pop_unlocked: + * @queue: a #GAsyncQueue + * @timeout: the number of microseconds to wait + * + * Pops data from the @queue. If the queue is empty, blocks for + * @timeout microseconds, or until data becomes available. + * + * If no data is received before the timeout, %NULL is returned. + * + * This function must be called while holding the @queue's lock. + * + * Return value: data from the queue or %NULL, when no data is + * received before the timeout. + */ +gpointer +g_async_queue_timeout_pop_unlocked (GAsyncQueue *queue, + guint64 timeout) +{ + gint64 end_time = g_get_monotonic_time () + timeout; + + return g_async_queue_pop_intern_unlocked (queue, TRUE, end_time); +} + +/** + * g_async_queue_timed_pop: + * @queue: a #GAsyncQueue + * @end_time: a #GTimeVal, determining the final time + * + * Pops data from the @queue. If the queue is empty, blocks until + * @end_time or until data becomes available. + * + * If no data is received before @end_time, %NULL is returned. + * + * To easily calculate @end_time, a combination of g_get_current_time() + * and g_time_val_add() can be used. + * + * Return value: data from the queue or %NULL, when no data is + * received before @end_time. + * + * Deprecated: use g_async_queue_timeout_pop(). + */ +gpointer +g_async_queue_timed_pop (GAsyncQueue *queue, + GTimeVal *end_time) +{ + gint64 m_end_time; + gpointer retval; + + g_return_val_if_fail (queue, NULL); + + if (end_time != NULL) + { + m_end_time = g_get_monotonic_time () + + ((gint64)end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec - + g_get_real_time ()); + } + else + m_end_time = -1; + + g_mutex_lock (&queue->mutex); + retval = g_async_queue_pop_intern_unlocked (queue, TRUE, m_end_time); + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_timed_pop_unlocked: + * @queue: a #GAsyncQueue + * @end_time: a #GTimeVal, determining the final time + * + * Pops data from the @queue. If the queue is empty, blocks until + * @end_time or until data becomes available. + * + * If no data is received before @end_time, %NULL is returned. + * + * To easily calculate @end_time, a combination of g_get_current_time() + * and g_time_val_add() can be used. + * + * This function must be called while holding the @queue's lock. + * + * Return value: data from the queue or %NULL, when no data is + * received before @end_time. + * + * Deprecated: use g_async_queue_timeout_pop_unlocked(). + */ +gpointer +g_async_queue_timed_pop_unlocked (GAsyncQueue *queue, + GTimeVal *end_time) +{ + gint64 m_end_time; + + g_return_val_if_fail (queue, NULL); + + if (end_time != NULL) + { + m_end_time = g_get_monotonic_time () + + (end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec - + g_get_real_time ()); + } + else + m_end_time = -1; + + return g_async_queue_pop_intern_unlocked (queue, TRUE, m_end_time); +} + +/** + * g_async_queue_length: + * @queue: a #GAsyncQueue. + * + * Returns the length of the queue. + * + * Actually this function returns the number of data items in + * the queue minus the number of waiting threads, so a negative + * value means waiting threads, and a positive value means available + * entries in the @queue. A return value of 0 could mean n entries + * in the queue and n threads waiting. This can happen due to locking + * of the queue or due to scheduling. + * + * Return value: the length of the @queue + */ +gint +g_async_queue_length (GAsyncQueue *queue) +{ + gint retval; + + g_return_val_if_fail (queue, 0); + + g_mutex_lock (&queue->mutex); + retval = queue->queue.length - queue->waiting_threads; + g_mutex_unlock (&queue->mutex); + + return retval; +} + +/** + * g_async_queue_length_unlocked: + * @queue: a #GAsyncQueue + * + * Returns the length of the queue. + * + * Actually this function returns the number of data items in + * the queue minus the number of waiting threads, so a negative + * value means waiting threads, and a positive value means available + * entries in the @queue. A return value of 0 could mean n entries + * in the queue and n threads waiting. This can happen due to locking + * of the queue or due to scheduling. + * + * This function must be called while holding the @queue's lock. + * + * Return value: the length of the @queue. + */ +gint +g_async_queue_length_unlocked (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, 0); + + return queue->queue.length - queue->waiting_threads; +} + +/** + * g_async_queue_sort: + * @queue: a #GAsyncQueue + * @func: the #GCompareDataFunc is used to sort @queue + * @user_data: user data passed to @func + * + * Sorts @queue using @func. + * + * The sort function @func is passed two elements of the @queue. + * It should return 0 if they are equal, a negative value if the + * first element should be higher in the @queue or a positive value + * if the first element should be lower in the @queue than the second + * element. + * + * This function will lock @queue before it sorts the queue and unlock + * it when it is finished. + * + * If you were sorting a list of priority numbers to make sure the + * lowest priority would be at the top of the queue, you could use: + * |[ + * gint32 id1; + * gint32 id2; + * + * id1 = GPOINTER_TO_INT (element1); + * id2 = GPOINTER_TO_INT (element2); + * + * return (id1 > id2 ? +1 : id1 == id2 ? 0 : -1); + * ]| + * + * Since: 2.10 + */ +void +g_async_queue_sort (GAsyncQueue *queue, + GCompareDataFunc func, + gpointer user_data) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (func != NULL); + + g_mutex_lock (&queue->mutex); + g_async_queue_sort_unlocked (queue, func, user_data); + g_mutex_unlock (&queue->mutex); +} + +/** + * g_async_queue_sort_unlocked: + * @queue: a #GAsyncQueue + * @func: the #GCompareDataFunc is used to sort @queue + * @user_data: user data passed to @func + * + * Sorts @queue using @func. + * + * The sort function @func is passed two elements of the @queue. + * It should return 0 if they are equal, a negative value if the + * first element should be higher in the @queue or a positive value + * if the first element should be lower in the @queue than the second + * element. + * + * This function must be called while holding the @queue's lock. + * + * Since: 2.10 + */ +void +g_async_queue_sort_unlocked (GAsyncQueue *queue, + GCompareDataFunc func, + gpointer user_data) +{ + SortData sd; + + g_return_if_fail (queue != NULL); + g_return_if_fail (func != NULL); + + sd.func = func; + sd.user_data = user_data; + + g_queue_sort (&queue->queue, + (GCompareDataFunc)g_async_queue_invert_compare, + &sd); +} + +/* + * Private API + */ + +GMutex * +_g_async_queue_get_mutex (GAsyncQueue *queue) +{ + g_return_val_if_fail (queue, NULL); + + return &queue->mutex; +} diff --git a/glib/glib/gasyncqueue.h b/glib/glib/gasyncqueue.h new file mode 100644 index 0000000..f0d6d95 --- /dev/null +++ b/glib/glib/gasyncqueue.h @@ -0,0 +1,91 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_ASYNCQUEUE_H__ +#define __G_ASYNCQUEUE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GAsyncQueue GAsyncQueue; + +GAsyncQueue *g_async_queue_new (void); +GAsyncQueue *g_async_queue_new_full (GDestroyNotify item_free_func); +void g_async_queue_lock (GAsyncQueue *queue); +void g_async_queue_unlock (GAsyncQueue *queue); +GAsyncQueue *g_async_queue_ref (GAsyncQueue *queue); +void g_async_queue_unref (GAsyncQueue *queue); + +GLIB_DEPRECATED_FOR(g_async_queue_ref) +void g_async_queue_ref_unlocked (GAsyncQueue *queue); + +GLIB_DEPRECATED_FOR(g_async_queue_unref) +void g_async_queue_unref_and_unlock (GAsyncQueue *queue); + +void g_async_queue_push (GAsyncQueue *queue, + gpointer data); +void g_async_queue_push_unlocked (GAsyncQueue *queue, + gpointer data); +void g_async_queue_push_sorted (GAsyncQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data); +void g_async_queue_push_sorted_unlocked (GAsyncQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data); +gpointer g_async_queue_pop (GAsyncQueue *queue); +gpointer g_async_queue_pop_unlocked (GAsyncQueue *queue); +gpointer g_async_queue_try_pop (GAsyncQueue *queue); +gpointer g_async_queue_try_pop_unlocked (GAsyncQueue *queue); +gpointer g_async_queue_timeout_pop (GAsyncQueue *queue, + guint64 timeout); +gpointer g_async_queue_timeout_pop_unlocked (GAsyncQueue *queue, + guint64 timeout); +gint g_async_queue_length (GAsyncQueue *queue); +gint g_async_queue_length_unlocked (GAsyncQueue *queue); +void g_async_queue_sort (GAsyncQueue *queue, + GCompareDataFunc func, + gpointer user_data); +void g_async_queue_sort_unlocked (GAsyncQueue *queue, + GCompareDataFunc func, + gpointer user_data); + +GLIB_DEPRECATED_FOR(g_async_queue_timeout_pop) +gpointer g_async_queue_timed_pop (GAsyncQueue *queue, + GTimeVal *end_time); +GLIB_DEPRECATED_FOR(g_async_queue_timeout_pop_unlocked) +gpointer g_async_queue_timed_pop_unlocked (GAsyncQueue *queue, + GTimeVal *end_time); + +G_END_DECLS + +#endif /* __G_ASYNCQUEUE_H__ */ diff --git a/glib/glib/gasyncqueueprivate.h b/glib/glib/gasyncqueueprivate.h new file mode 100644 index 0000000..3ecb29a --- /dev/null +++ b/glib/glib/gasyncqueueprivate.h @@ -0,0 +1,31 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_ASYNCQUEUEPRIVATE_H__ +#define __G_ASYNCQUEUEPRIVATE_H__ + +#include "gasyncqueue.h" + +G_BEGIN_DECLS + +GMutex *_g_async_queue_get_mutex (GAsyncQueue *queue); + +G_END_DECLS + +#endif /* __G_ASYNCQUEUEPRIVATE_H__ */ diff --git a/glib/glib/gatomic.c b/glib/glib/gatomic.c new file mode 100644 index 0000000..2df2bcc --- /dev/null +++ b/glib/glib/gatomic.c @@ -0,0 +1,871 @@ +/* + * Copyright © 2011 Ryan Lortie + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gatomic.h" + +/** + * SECTION:atomic_operations + * @title: Atomic Operations + * @short_description: basic atomic integer and pointer operations + * @see_also: #GMutex + * + * The following is a collection of compiler macros to provide atomic + * access to integer and pointer-sized values. + * + * The macros that have 'int' in the name will operate on pointers to + * #gint and #guint. The macros with 'pointer' in the name will operate + * on pointers to any pointer-sized value, including #gsize. There is + * no support for 64bit operations on platforms with 32bit pointers + * because it is not generally possible to perform these operations + * atomically. + * + * The get, set and exchange operations for integers and pointers + * nominally operate on #gint and #gpointer, respectively. Of the + * arithmetic operations, the 'add' operation operates on (and returns) + * signed integer values (#gint and #gssize) and the 'and', 'or', and + * 'xor' operations operate on (and return) unsigned integer values + * (#guint and #gsize). + * + * All of the operations act as a full compiler and (where appropriate) + * hardware memory barrier. Acquire and release or producer and + * consumer barrier semantics are not available through this API. + * + * It is very important that all accesses to a particular integer or + * pointer be performed using only this API and that different sizes of + * operation are not mixed or used on overlapping memory regions. Never + * read or assign directly from or to a value -- always use this API. + * + * For simple reference counting purposes you should use + * g_atomic_int_inc() and g_atomic_int_dec_and_test(). Other uses that + * fall outside of simple reference counting patterns are prone to + * subtle bugs and occasionally undefined behaviour. It is also worth + * noting that since all of these operations require global + * synchronisation of the entire machine, they can be quite slow. In + * the case of performing multiple atomic operations it can often be + * faster to simply acquire a mutex lock around the critical area, + * perform the operations normally and then release the lock. + **/ + +/** + * G_ATOMIC_LOCK_FREE: + * + * This macro is defined if the atomic operations of GLib are + * implemented using real hardware atomic operations. This means that + * the GLib atomic API can be used between processes and safely mixed + * with other (hardware) atomic APIs. + * + * If this macro is not defined, the atomic operations may be + * emulated using a mutex. In that case, the GLib atomic operations are + * only atomic relative to themselves and within a single process. + **/ + +/* NOTE CAREFULLY: + * + * This file is the lowest-level part of GLib. + * + * Other lowlevel parts of GLib (threads, slice allocator, g_malloc, + * messages, etc) call into these functions and macros to get work done. + * + * As such, these functions can not call back into any part of GLib + * without risking recursion. + */ + +#ifdef G_ATOMIC_LOCK_FREE + +/* if G_ATOMIC_LOCK_FREE was defined by ./configure then we MUST + * implement the atomic operations in a lock-free manner. + */ + +#if defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) +/** + * g_atomic_int_get: + * @atomic: a pointer to a #gint or #guint + * + * Gets the current value of @atomic. + * + * This call acts as a full compiler and hardware + * memory barrier (before the get). + * + * Returns: the value of the integer + * + * Since: 2.4 + **/ +gint +(g_atomic_int_get) (volatile gint *atomic) +{ + return g_atomic_int_get (atomic); +} + +/** + * g_atomic_int_set: + * @atomic: a pointer to a #gint or #guint + * @newval: a new value to store + * + * Sets the value of @atomic to @newval. + * + * This call acts as a full compiler and hardware + * memory barrier (after the set). + * + * Since: 2.4 + */ +void +(g_atomic_int_set) (volatile gint *atomic, + gint newval) +{ + g_atomic_int_set (atomic, newval); +} + +/** + * g_atomic_int_inc: + * @atomic: a pointer to a #gint or #guint + * + * Increments the value of @atomic by 1. + * + * Think of this operation as an atomic version of + * { *@atomic += 1; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Since: 2.4 + **/ +void +(g_atomic_int_inc) (volatile gint *atomic) +{ + g_atomic_int_inc (atomic); +} + +/** + * g_atomic_int_dec_and_test: + * @atomic: a pointer to a #gint or #guint + * + * Decrements the value of @atomic by 1. + * + * Think of this operation as an atomic version of + * { *@atomic -= 1; return (*@atomic == 0); } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: %TRUE if the resultant value is zero + * + * Since: 2.4 + **/ +gboolean +(g_atomic_int_dec_and_test) (volatile gint *atomic) +{ + return g_atomic_int_dec_and_test (atomic); +} + +/** + * g_atomic_int_compare_and_exchange: + * @atomic: a pointer to a #gint or #guint + * @oldval: the value to compare with + * @newval: the value to conditionally replace with + * + * Compares @atomic to @oldval and, if equal, sets it to @newval. + * If @atomic was not equal to @oldval then no change occurs. + * + * This compare and exchange is done atomically. + * + * Think of this operation as an atomic version of + * { if (*@atomic == @oldval) { *@atomic = @newval; return TRUE; } else return FALSE; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: %TRUE if the exchange took place + * + * Since: 2.4 + **/ +gboolean +(g_atomic_int_compare_and_exchange) (volatile gint *atomic, + gint oldval, + gint newval) +{ + return g_atomic_int_compare_and_exchange (atomic, oldval, newval); +} + +/** + * g_atomic_int_add: + * @atomic: a pointer to a #gint or #guint + * @val: the value to add + * + * Atomically adds @val to the value of @atomic. + * + * Think of this operation as an atomic version of + * { tmp = *atomic; *@atomic += @val; return tmp; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Before version 2.30, this function did not return a value + * (but g_atomic_int_exchange_and_add() did, and had the same meaning). + * + * Returns: the value of @atomic before the add, signed + * + * Since: 2.4 + **/ +gint +(g_atomic_int_add) (volatile gint *atomic, + gint val) +{ + return g_atomic_int_add (atomic, val); +} + +/** + * g_atomic_int_and: + * @atomic: a pointer to a #gint or #guint + * @val: the value to 'and' + * + * Performs an atomic bitwise 'and' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * This call acts as a full compiler and hardware memory barrier. + * + * Think of this operation as an atomic version of + * { tmp = *atomic; *@atomic &= @val; return tmp; } + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +guint +(g_atomic_int_and) (volatile guint *atomic, + guint val) +{ + return g_atomic_int_and (atomic, val); +} + +/** + * g_atomic_int_or: + * @atomic: a pointer to a #gint or #guint + * @val: the value to 'or' + * + * Performs an atomic bitwise 'or' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * { tmp = *atomic; *@atomic |= @val; return tmp; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +guint +(g_atomic_int_or) (volatile guint *atomic, + guint val) +{ + return g_atomic_int_or (atomic, val); +} + +/** + * g_atomic_int_xor: + * @atomic: a pointer to a #gint or #guint + * @val: the value to 'xor' + * + * Performs an atomic bitwise 'xor' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * { tmp = *atomic; *@atomic ^= @val; return tmp; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +guint +(g_atomic_int_xor) (volatile guint *atomic, + guint val) +{ + return g_atomic_int_xor (atomic, val); +} + + +/** + * g_atomic_pointer_get: + * @atomic: a pointer to a #gpointer-sized value + * + * Gets the current value of @atomic. + * + * This call acts as a full compiler and hardware + * memory barrier (before the get). + * + * Returns: the value of the pointer + * + * Since: 2.4 + **/ +gpointer +(g_atomic_pointer_get) (volatile void *atomic) +{ + return g_atomic_pointer_get ((volatile gpointer *) atomic); +} + +/** + * g_atomic_pointer_set: + * @atomic: a pointer to a #gpointer-sized value + * @newval: a new value to store + * + * Sets the value of @atomic to @newval. + * + * This call acts as a full compiler and hardware + * memory barrier (after the set). + * + * Since: 2.4 + **/ +void +(g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) +{ + g_atomic_pointer_set ((volatile gpointer *) atomic, newval); +} + +/** + * g_atomic_pointer_compare_and_exchange: + * @atomic: a pointer to a #gpointer-sized value + * @oldval: the value to compare with + * @newval: the value to conditionally replace with + * + * Compares @atomic to @oldval and, if equal, sets it to @newval. + * If @atomic was not equal to @oldval then no change occurs. + * + * This compare and exchange is done atomically. + * + * Think of this operation as an atomic version of + * { if (*@atomic == @oldval) { *@atomic = @newval; return TRUE; } else return FALSE; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: %TRUE if the exchange took place + * + * Since: 2.4 + **/ +gboolean +(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, + gpointer oldval, + gpointer newval) +{ + return g_atomic_pointer_compare_and_exchange ((volatile gpointer *) atomic, + oldval, newval); +} + +/** + * g_atomic_pointer_add: + * @atomic: a pointer to a #gpointer-sized value + * @val: the value to add + * + * Atomically adds @val to the value of @atomic. + * + * Think of this operation as an atomic version of + * { tmp = *atomic; *@atomic += @val; return tmp; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: the value of @atomic before the add, signed + * + * Since: 2.30 + **/ +gssize +(g_atomic_pointer_add) (volatile void *atomic, + gssize val) +{ + return g_atomic_pointer_add ((volatile gpointer *) atomic, val); +} + +/** + * g_atomic_pointer_and: + * @atomic: a pointer to a #gpointer-sized value + * @val: the value to 'and' + * + * Performs an atomic bitwise 'and' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * { tmp = *atomic; *@atomic &= @val; return tmp; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +gsize +(g_atomic_pointer_and) (volatile void *atomic, + gsize val) +{ + return g_atomic_pointer_and ((volatile gpointer *) atomic, val); +} + +/** + * g_atomic_pointer_or: + * @atomic: a pointer to a #gpointer-sized value + * @val: the value to 'or' + * + * Performs an atomic bitwise 'or' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * { tmp = *atomic; *@atomic |= @val; return tmp; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +gsize +(g_atomic_pointer_or) (volatile void *atomic, + gsize val) +{ + return g_atomic_pointer_or ((volatile gpointer *) atomic, val); +} + +/** + * g_atomic_pointer_xor: + * @atomic: a pointer to a #gpointer-sized value + * @val: the value to 'xor' + * + * Performs an atomic bitwise 'xor' of the value of @atomic and @val, + * storing the result back in @atomic. + * + * Think of this operation as an atomic version of + * { tmp = *atomic; *@atomic ^= @val; return tmp; } + * + * This call acts as a full compiler and hardware memory barrier. + * + * Returns: the value of @atomic before the operation, unsigned + * + * Since: 2.30 + **/ +gsize +(g_atomic_pointer_xor) (volatile void *atomic, + gsize val) +{ + return g_atomic_pointer_xor ((volatile gpointer *) atomic, val); +} + +#elif defined (G_PLATFORM_WIN32) + +#include +#if !defined(_M_AMD64) && !defined (_M_IA64) && !defined(_M_X64) +#define InterlockedAnd _InterlockedAnd +#define InterlockedOr _InterlockedOr +#define InterlockedXor _InterlockedXor +#endif + +/* + * http://msdn.microsoft.com/en-us/library/ms684122(v=vs.85).aspx + */ +gint +(g_atomic_int_get) (volatile gint *atomic) +{ + MemoryBarrier (); + return *atomic; +} + +void +(g_atomic_int_set) (volatile gint *atomic, + gint newval) +{ + *atomic = newval; + MemoryBarrier (); +} + +void +(g_atomic_int_inc) (volatile gint *atomic) +{ + InterlockedIncrement (atomic); +} + +gboolean +(g_atomic_int_dec_and_test) (volatile gint *atomic) +{ + return InterlockedDecrement (atomic) == 0; +} + +gboolean +(g_atomic_int_compare_and_exchange) (volatile gint *atomic, + gint oldval, + gint newval) +{ + return InterlockedCompareExchange (atomic, newval, oldval) == oldval; +} + +gint +(g_atomic_int_add) (volatile gint *atomic, + gint val) +{ + return InterlockedExchangeAdd (atomic, val); +} + +guint +(g_atomic_int_and) (volatile guint *atomic, + guint val) +{ + return InterlockedAnd (atomic, val); +} + +guint +(g_atomic_int_or) (volatile guint *atomic, + guint val) +{ + return InterlockedOr (atomic, val); +} + +guint +(g_atomic_int_xor) (volatile guint *atomic, + guint val) +{ + return InterlockedXor (atomic, val); +} + + +gpointer +(g_atomic_pointer_get) (volatile void *atomic) +{ + volatile gpointer *ptr = atomic; + + MemoryBarrier (); + return *ptr; +} + +void +(g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) +{ + volatile gpointer *ptr = atomic; + + *ptr = newval; + MemoryBarrier (); +} + +gboolean +(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, + gpointer oldval, + gpointer newval) +{ + return InterlockedCompareExchangePointer (atomic, newval, oldval) == oldval; +} + +gssize +(g_atomic_pointer_add) (volatile void *atomic, + gssize val) +{ +#if GLIB_SIZEOF_VOID_P == 8 + return InterlockedExchangeAdd64 (atomic, val); +#else + return InterlockedExchangeAdd (atomic, val); +#endif +} + +gsize +(g_atomic_pointer_and) (volatile void *atomic, + gsize val) +{ +#if GLIB_SIZEOF_VOID_P == 8 + return InterlockedAnd64 (atomic, val); +#else + return InterlockedAnd (atomic, val); +#endif +} + +gsize +(g_atomic_pointer_or) (volatile void *atomic, + gsize val) +{ +#if GLIB_SIZEOF_VOID_P == 8 + return InterlockedOr64 (atomic, val); +#else + return InterlockedOr (atomic, val); +#endif +} + +gsize +(g_atomic_pointer_xor) (volatile void *atomic, + gsize val) +{ +#if GLIB_SIZEOF_VOID_P == 8 + return InterlockedXor64 (atomic, val); +#else + return InterlockedXor (atomic, val); +#endif +} +#else + +/* This error occurs when ./configure decided that we should be capable + * of lock-free atomics but we find at compile-time that we are not. + */ +#error G_ATOMIC_LOCK_FREE defined, but incapable of lock-free atomics. + +#endif /* defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) */ + +#else /* G_ATOMIC_LOCK_FREE */ + +/* We are not permitted to call into any GLib functions from here, so we + * can not use GMutex. + * + * Fortunately, we already take care of the Windows case above, and all + * non-Windows platforms on which glib runs have pthreads. Use those. + */ +#include + +static pthread_mutex_t g_atomic_lock = PTHREAD_MUTEX_INITIALIZER; + +gint +(g_atomic_int_get) (volatile gint *atomic) +{ + gint value; + + pthread_mutex_lock (&g_atomic_lock); + value = *atomic; + pthread_mutex_unlock (&g_atomic_lock); + + return value; +} + +void +(g_atomic_int_set) (volatile gint *atomic, + gint value) +{ + pthread_mutex_lock (&g_atomic_lock); + *atomic = value; + pthread_mutex_unlock (&g_atomic_lock); +} + +void +(g_atomic_int_inc) (volatile gint *atomic) +{ + pthread_mutex_lock (&g_atomic_lock); + (*atomic)++; + pthread_mutex_unlock (&g_atomic_lock); +} + +gboolean +(g_atomic_int_dec_and_test) (volatile gint *atomic) +{ + gboolean is_zero; + + pthread_mutex_lock (&g_atomic_lock); + is_zero = --(*atomic) == 0; + pthread_mutex_unlock (&g_atomic_lock); + + return is_zero; +} + +gboolean +(g_atomic_int_compare_and_exchange) (volatile gint *atomic, + gint oldval, + gint newval) +{ + gboolean success; + + pthread_mutex_lock (&g_atomic_lock); + + if ((success = (*atomic == oldval))) + *atomic = newval; + + pthread_mutex_unlock (&g_atomic_lock); + + return success; +} + +gint +(g_atomic_int_add) (volatile gint *atomic, + gint val) +{ + gint oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *atomic; + *atomic = oldval + val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +guint +(g_atomic_int_and) (volatile guint *atomic, + guint val) +{ + guint oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *atomic; + *atomic = oldval & val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +guint +(g_atomic_int_or) (volatile guint *atomic, + guint val) +{ + guint oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *atomic; + *atomic = oldval | val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +guint +(g_atomic_int_xor) (volatile guint *atomic, + guint val) +{ + guint oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *atomic; + *atomic = oldval ^ val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + + +gpointer +(g_atomic_pointer_get) (volatile void *atomic) +{ + volatile gpointer *ptr = atomic; + gpointer value; + + pthread_mutex_lock (&g_atomic_lock); + value = *ptr; + pthread_mutex_unlock (&g_atomic_lock); + + return value; +} + +void +(g_atomic_pointer_set) (volatile void *atomic, + gpointer newval) +{ + volatile gpointer *ptr = atomic; + + pthread_mutex_lock (&g_atomic_lock); + *ptr = newval; + pthread_mutex_unlock (&g_atomic_lock); +} + +gboolean +(g_atomic_pointer_compare_and_exchange) (volatile void *atomic, + gpointer oldval, + gpointer newval) +{ + volatile gpointer *ptr = atomic; + gboolean success; + + pthread_mutex_lock (&g_atomic_lock); + + if ((success = (*ptr == oldval))) + *ptr = newval; + + pthread_mutex_unlock (&g_atomic_lock); + + return success; +} + +gssize +(g_atomic_pointer_add) (volatile void *atomic, + gssize val) +{ + volatile gssize *ptr = atomic; + gssize oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *ptr; + *ptr = oldval + val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +gsize +(g_atomic_pointer_and) (volatile void *atomic, + gsize val) +{ + volatile gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *ptr; + *ptr = oldval & val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +gsize +(g_atomic_pointer_or) (volatile void *atomic, + gsize val) +{ + volatile gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *ptr; + *ptr = oldval | val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +gsize +(g_atomic_pointer_xor) (volatile void *atomic, + gsize val) +{ + volatile gsize *ptr = atomic; + gsize oldval; + + pthread_mutex_lock (&g_atomic_lock); + oldval = *ptr; + *ptr = oldval ^ val; + pthread_mutex_unlock (&g_atomic_lock); + + return oldval; +} + +#endif + +/** + * g_atomic_int_exchange_and_add: + * @atomic: a pointer to a #gint + * @val: the value to add + * + * This function existed before g_atomic_int_add() returned the prior + * value of the integer (which it now does). It is retained only for + * compatibility reasons. Don't use this function in new code. + * + * Returns: the value of @atomic before the add, signed + * Since: 2.4 + * Deprecated: 2.30: Use g_atomic_int_add() instead. + **/ +gint +g_atomic_int_exchange_and_add (volatile gint *atomic, + gint val) +{ + return (g_atomic_int_add) (atomic, val); +} diff --git a/glib/glib/gatomic.h b/glib/glib/gatomic.h new file mode 100644 index 0000000..5403f28 --- /dev/null +++ b/glib/glib/gatomic.h @@ -0,0 +1,216 @@ +/* + * Copyright © 2011 Ryan Lortie + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * Author: Ryan Lortie + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_ATOMIC_H__ +#define __G_ATOMIC_H__ + +#include + +G_BEGIN_DECLS + +gint g_atomic_int_get (volatile gint *atomic); +void g_atomic_int_set (volatile gint *atomic, + gint newval); +void g_atomic_int_inc (volatile gint *atomic); +gboolean g_atomic_int_dec_and_test (volatile gint *atomic); +gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic, + gint oldval, + gint newval); +gint g_atomic_int_add (volatile gint *atomic, + gint val); +guint g_atomic_int_and (volatile guint *atomic, + guint val); +guint g_atomic_int_or (volatile guint *atomic, + guint val); +guint g_atomic_int_xor (volatile guint *atomic, + guint val); + +gpointer g_atomic_pointer_get (volatile void *atomic); +void g_atomic_pointer_set (volatile void *atomic, + gpointer newval); +gboolean g_atomic_pointer_compare_and_exchange (volatile void *atomic, + gpointer oldval, + gpointer newval); +gssize g_atomic_pointer_add (volatile void *atomic, + gssize val); +gsize g_atomic_pointer_and (volatile void *atomic, + gsize val); +gsize g_atomic_pointer_or (volatile void *atomic, + gsize val); +gsize g_atomic_pointer_xor (volatile void *atomic, + gsize val); + +GLIB_DEPRECATED_IN_2_30_FOR(g_atomic_add) +gint g_atomic_int_exchange_and_add (volatile gint *atomic, + gint val); + +G_END_DECLS + +#if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + +#define g_atomic_int_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 0); \ + __sync_synchronize (); \ + (gint) *(atomic); \ + })) +#define g_atomic_int_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (newval) : 0); \ + *(atomic) = (newval); \ + __sync_synchronize (); \ + })) +#define g_atomic_int_inc(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 0); \ + (void) __sync_fetch_and_add ((atomic), 1); \ + })) +#define g_atomic_int_dec_and_test(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 0); \ + __sync_fetch_and_sub ((atomic), 1) == 1; \ + })) +#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 0); \ + (gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \ + })) +#define g_atomic_int_add(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 0); \ + (gint) __sync_fetch_and_add ((atomic), (val)); \ + })) +#define g_atomic_int_and(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 0); \ + (guint) __sync_fetch_and_and ((atomic), (val)); \ + })) +#define g_atomic_int_or(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 0); \ + (guint) __sync_fetch_and_or ((atomic), (val)); \ + })) +#define g_atomic_int_xor(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (val) : 0); \ + (guint) __sync_fetch_and_xor ((atomic), (val)); \ + })) + +#define g_atomic_pointer_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + __sync_synchronize (); \ + (gpointer) *(atomic); \ + })) +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + *(atomic) = (__typeof__ (*(atomic))) (gsize) (newval); \ + __sync_synchronize (); \ + })) +#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + (gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \ + })) +#define g_atomic_pointer_add(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + (void) (0 ? (val) ^ (val) : 0); \ + (gssize) __sync_fetch_and_add ((atomic), (val)); \ + })) +#define g_atomic_pointer_and(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + (void) (0 ? (val) ^ (val) : 0); \ + (gsize) __sync_fetch_and_and ((atomic), (val)); \ + })) +#define g_atomic_pointer_or(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + (void) (0 ? (val) ^ (val) : 0); \ + (gsize) __sync_fetch_and_or ((atomic), (val)); \ + })) +#define g_atomic_pointer_xor(atomic, val) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + (void) (0 ? (val) ^ (val) : 0); \ + (gsize) __sync_fetch_and_xor ((atomic), (val)); \ + })) + +#else /* defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) */ + +#define g_atomic_int_get(atomic) \ + (g_atomic_int_get ((gint *) (atomic))) +#define g_atomic_int_set(atomic, newval) \ + (g_atomic_int_set ((gint *) (atomic), (gint) (newval))) +#define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ + (g_atomic_int_compare_and_exchange ((gint *) (atomic), (oldval), (newval))) +#define g_atomic_int_add(atomic, val) \ + (g_atomic_int_add ((gint *) (atomic), (val))) +#define g_atomic_int_and(atomic, val) \ + (g_atomic_int_and ((guint *) (atomic), (val))) +#define g_atomic_int_or(atomic, val) \ + (g_atomic_int_or ((guint *) (atomic), (val))) +#define g_atomic_int_xor(atomic, val) \ + (g_atomic_int_xor ((guint *) (atomic), (val))) +#define g_atomic_int_inc(atomic) \ + (g_atomic_int_inc ((gint *) (atomic))) +#define g_atomic_int_dec_and_test(atomic) \ + (g_atomic_int_dec_and_test ((gint *) (atomic))) + +#define g_atomic_pointer_get(atomic) \ + (g_atomic_pointer_get (atomic)) +#define g_atomic_pointer_set(atomic, newval) \ + (g_atomic_pointer_set ((atomic), (gpointer) (newval))) +#define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ + (g_atomic_pointer_compare_and_exchange ((atomic), (gpointer) (oldval), (gpointer) (newval))) +#define g_atomic_pointer_add(atomic, val) \ + (g_atomic_pointer_add ((atomic), (gssize) (val))) +#define g_atomic_pointer_and(atomic, val) \ + (g_atomic_pointer_and ((atomic), (gsize) (val))) +#define g_atomic_pointer_or(atomic, val) \ + (g_atomic_pointer_or ((atomic), (gsize) (val))) +#define g_atomic_pointer_xor(atomic, val) \ + (g_atomic_pointer_xor ((atomic), (gsize) (val))) + +#endif /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */ + +#endif /* __G_ATOMIC_H__ */ diff --git a/glib/glib/gbacktrace.c b/glib/glib/gbacktrace.c new file mode 100644 index 0000000..957c482 --- /dev/null +++ b/glib/glib/gbacktrace.c @@ -0,0 +1,374 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe ; except for g_on_error_stack_trace, but who wants thread safety + * then + */ + +#include "config.h" +#include "glibconfig.h" + +#include +#include +#include +#include + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#ifdef HAVE_SYS_TIMES_H +#include +#endif +#include +#ifdef HAVE_SYS_WAIT_H +#include +#endif + +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ + +#include /* for bzero on BSD systems */ + +#ifdef G_OS_WIN32 +# define STRICT /* Strict typing, please */ +# define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */ +# include +# undef STRICT +#endif + +#include "gbacktrace.h" + +#include "gtypes.h" +#include "gmain.h" +#include "gprintfint.h" +#include "gutils.h" + + +#ifndef NO_FD_SET +# define SELECT_MASK fd_set +#else +# if defined(_IBMR2) +# define SELECT_MASK void +# else +# define SELECT_MASK int +# endif +#endif + + +#ifndef G_OS_WIN32 +static void stack_trace (char **args); +#endif + +extern volatile gboolean glib_on_error_halt; +volatile gboolean glib_on_error_halt = TRUE; + +/** + * g_on_error_query: + * @prg_name: the program name, needed by gdb + * for the [S]tack trace option. If @prg_name is %NULL, g_get_prgname() + * is called to get the program name (which will work correctly if + * gdk_init() or gtk_init() has been called) + * + * Prompts the user with + * [E]xit, [H]alt, show [S]tack trace or [P]roceed. + * This function is intended to be used for debugging use only. + * The following example shows how it can be used together with + * the g_log() functions. + * + * |[ + * #include <glib.h> + * + * static void + * log_handler (const gchar *log_domain, + * GLogLevelFlags log_level, + * const gchar *message, + * gpointer user_data) + * { + * g_log_default_handler (log_domain, log_level, message, user_data); + * + * g_on_error_query (MY_PROGRAM_NAME); + * } + * + * int + * main (int argc, char *argv[]) + * { + * g_log_set_handler (MY_LOG_DOMAIN, + * G_LOG_LEVEL_WARNING | + * G_LOG_LEVEL_ERROR | + * G_LOG_LEVEL_CRITICAL, + * log_handler, + * NULL); + * /* ... */ + * ]| + * + * If [E]xit is selected, the application terminates with a call + * to _exit(0). + * + * If [S]tack trace is selected, g_on_error_stack_trace() is called. + * This invokes gdb, which attaches to the current + * process and shows a stack trace. The prompt is then shown again. + * + * If [P]roceed is selected, the function returns. + * + * This function may cause different actions on non-UNIX platforms. + */ +void +g_on_error_query (const gchar *prg_name) +{ +#ifndef G_OS_WIN32 + static const gchar * const query1 = "[E]xit, [H]alt"; + static const gchar * const query2 = ", show [S]tack trace"; + static const gchar * const query3 = " or [P]roceed"; + gchar buf[16]; + + if (!prg_name) + prg_name = g_get_prgname (); + + retry: + + if (prg_name) + _g_fprintf (stdout, + "%s (pid:%u): %s%s%s: ", + prg_name, + (guint) getpid (), + query1, + query2, + query3); + else + _g_fprintf (stdout, + "(process:%u): %s%s: ", + (guint) getpid (), + query1, + query3); + fflush (stdout); + + if (isatty(0) && isatty(1)) + fgets (buf, 8, stdin); + else + strcpy (buf, "E\n"); + + if ((buf[0] == 'E' || buf[0] == 'e') + && buf[1] == '\n') + _exit (0); + else if ((buf[0] == 'P' || buf[0] == 'p') + && buf[1] == '\n') + return; + else if (prg_name + && (buf[0] == 'S' || buf[0] == 's') + && buf[1] == '\n') + { + g_on_error_stack_trace (prg_name); + goto retry; + } + else if ((buf[0] == 'H' || buf[0] == 'h') + && buf[1] == '\n') + { + while (glib_on_error_halt) + ; + glib_on_error_halt = TRUE; + return; + } + else + goto retry; +#else + if (!prg_name) + prg_name = g_get_prgname (); + + MessageBox (NULL, "g_on_error_query called, program terminating", + (prg_name && *prg_name) ? prg_name : NULL, + MB_OK|MB_ICONERROR); + _exit(0); +#endif +} + +/** + * g_on_error_stack_trace: + * @prg_name: the program name, needed by gdb + * for the [S]tack trace option. + * + * Invokes gdb, which attaches to the current + * process and shows a stack trace. Called by g_on_error_query() + * when the [S]tack trace option is selected. You can get the current + * process's "program name" with g_get_prgname(), assuming that you + * have called gtk_init() or gdk_init(). + * + * This function may cause different actions on non-UNIX platforms. + */ +void +g_on_error_stack_trace (const gchar *prg_name) +{ +#if defined(G_OS_UNIX) || defined(G_OS_BEOS) + pid_t pid; + gchar buf[16]; + gchar *args[4] = { "gdb", NULL, NULL, NULL }; + int status; + + if (!prg_name) + return; + + _g_sprintf (buf, "%u", (guint) getpid ()); + + args[1] = (gchar*) prg_name; + args[2] = buf; + + pid = fork (); + if (pid == 0) + { + stack_trace (args); + _exit (0); + } + else if (pid == (pid_t) -1) + { + perror ("unable to fork gdb"); + return; + } + + waitpid (pid, &status, 0); +#else + if (IsDebuggerPresent ()) + G_BREAKPOINT (); + else + abort (); +#endif +} + +#ifndef G_OS_WIN32 + +static gboolean stack_trace_done = FALSE; + +static void +stack_trace_sigchld (int signum) +{ + stack_trace_done = TRUE; +} + +static void +stack_trace (char **args) +{ + pid_t pid; + int in_fd[2]; + int out_fd[2]; + SELECT_MASK fdset; + SELECT_MASK readset; + struct timeval tv; + int sel, idx, state; + char buffer[256]; + char c; + + stack_trace_done = FALSE; + signal (SIGCHLD, stack_trace_sigchld); + + if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1)) + { + perror ("unable to open pipe"); + _exit (0); + } + + pid = fork (); + if (pid == 0) + { + close (0); dup (in_fd[0]); /* set the stdin to the in pipe */ + close (1); dup (out_fd[1]); /* set the stdout to the out pipe */ + close (2); dup (out_fd[1]); /* set the stderr to the out pipe */ + + execvp (args[0], args); /* exec gdb */ + perror ("exec failed"); + _exit (0); + } + else if (pid == (pid_t) -1) + { + perror ("unable to fork"); + _exit (0); + } + + FD_ZERO (&fdset); + FD_SET (out_fd[0], &fdset); + + write (in_fd[1], "backtrace\n", 10); + write (in_fd[1], "p x = 0\n", 8); + write (in_fd[1], "quit\n", 5); + + idx = 0; + state = 0; + + while (1) + { + readset = fdset; + tv.tv_sec = 1; + tv.tv_usec = 0; + + sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv); + if (sel == -1) + break; + + if ((sel > 0) && (FD_ISSET (out_fd[0], &readset))) + { + if (read (out_fd[0], &c, 1)) + { + switch (state) + { + case 0: + if (c == '#') + { + state = 1; + idx = 0; + buffer[idx++] = c; + } + break; + case 1: + buffer[idx++] = c; + if ((c == '\n') || (c == '\r')) + { + buffer[idx] = 0; + _g_fprintf (stdout, "%s", buffer); + state = 0; + idx = 0; + } + break; + default: + break; + } + } + } + else if (stack_trace_done) + break; + } + + close (in_fd[0]); + close (in_fd[1]); + close (out_fd[0]); + close (out_fd[1]); + _exit (0); +} + +#endif /* !G_OS_WIN32 */ diff --git a/glib/glib/gbacktrace.h b/glib/glib/gbacktrace.h new file mode 100644 index 0000000..f0a6eab --- /dev/null +++ b/glib/glib/gbacktrace.h @@ -0,0 +1,64 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_BACKTRACE_H__ +#define __G_BACKTRACE_H__ + +#include +#include + +G_BEGIN_DECLS + +void g_on_error_query (const gchar *prg_name); +void g_on_error_stack_trace (const gchar *prg_name); + +/** + * G_BREAKPOINT: + * + * Inserts a breakpoint instruction into the code. + * + * On x86 and alpha systems this is implemented as a soft interrupt + * and on other architectures it raises a SIGTRAP signal. + */ +#if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__) && __GNUC__ >= 2 +# define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("int $03"); }G_STMT_END +#elif (defined (_MSC_VER) || defined (__DMC__)) && defined (_M_IX86) +# define G_BREAKPOINT() G_STMT_START{ __asm int 3h }G_STMT_END +#elif defined (_MSC_VER) +# define G_BREAKPOINT() G_STMT_START{ __debugbreak(); }G_STMT_END +#elif defined (__alpha__) && !defined(__osf__) && defined (__GNUC__) && __GNUC__ >= 2 +# define G_BREAKPOINT() G_STMT_START{ __asm__ __volatile__ ("bpt"); }G_STMT_END +#else /* !__i386__ && !__alpha__ */ +# define G_BREAKPOINT() G_STMT_START{ raise (SIGTRAP); }G_STMT_END +#endif /* __i386__ */ + +G_END_DECLS + +#endif /* __G_BACKTRACE_H__ */ diff --git a/glib/glib/gbase64.c b/glib/glib/gbase64.c new file mode 100644 index 0000000..d0ab0ea --- /dev/null +++ b/glib/glib/gbase64.c @@ -0,0 +1,445 @@ +/* gbase64.c - Base64 encoding/decoding + * + * Copyright (C) 2006 Alexander Larsson + * Copyright (C) 2000-2003 Ximian Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * This is based on code in camel, written by: + * Michael Zucchi + * Jeffrey Stedfast + */ + +#include "config.h" + +#include + +#include "gbase64.h" +#include "gtestutils.h" +#include "glibintl.h" + + +/** + * SECTION:base64 + * @title: Base64 Encoding + * @short_description: encodes and decodes data in Base64 format + * + * Base64 is an encoding that allows a sequence of arbitrary bytes to be + * encoded as a sequence of printable ASCII characters. For the definition + * of Base64, see RFC + * 1421 or RFC + * 2045. Base64 is most commonly used as a MIME transfer encoding + * for email. + * + * GLib supports incremental encoding using g_base64_encode_step() and + * g_base64_encode_close(). Incremental decoding can be done with + * g_base64_decode_step(). To encode or decode data in one go, use + * g_base64_encode() or g_base64_decode(). To avoid memory allocation when + * decoding, you can use g_base64_decode_inplace(). + * + * Support for Base64 encoding has been added in GLib 2.12. + */ + +static const char base64_alphabet[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +/** + * g_base64_encode_step: + * @in: (array length=len) (element-type guint8): the binary data to encode + * @len: the length of @in + * @break_lines: whether to break long lines + * @out: (out) (array) (element-type guint8): pointer to destination buffer + * @state: (inout): Saved state between steps, initialize to 0 + * @save: (inout): Saved state between steps, initialize to 0 + * + * Incrementally encode a sequence of binary data into its Base-64 stringified + * representation. By calling this function multiple times you can convert + * data in chunks to avoid having to have the full encoded data in memory. + * + * When all of the data has been converted you must call + * g_base64_encode_close() to flush the saved state. + * + * The output buffer must be large enough to fit all the data that will + * be written to it. Due to the way base64 encodes you will need + * at least: (@len / 3 + 1) * 4 + 4 bytes (+ 4 may be needed in case of + * non-zero state). If you enable line-breaking you will need at least: + * ((@len / 3 + 1) * 4 + 4) / 72 + 1 bytes of extra space. + * + * @break_lines is typically used when putting base64-encoded data in emails. + * It breaks the lines at 72 columns instead of putting all of the text on + * the same line. This avoids problems with long lines in the email system. + * Note however that it breaks the lines with LF + * characters, not CR LF sequences, so the result cannot + * be passed directly to SMTP or certain other protocols. + * + * Return value: The number of bytes of output that was written + * + * Since: 2.12 + */ +gsize +g_base64_encode_step (const guchar *in, + gsize len, + gboolean break_lines, + gchar *out, + gint *state, + gint *save) +{ + char *outptr; + const guchar *inptr; + + g_return_val_if_fail (in != NULL, 0); + g_return_val_if_fail (out != NULL, 0); + g_return_val_if_fail (state != NULL, 0); + g_return_val_if_fail (save != NULL, 0); + + if (len <= 0) + return 0; + + inptr = in; + outptr = out; + + if (len + ((char *) save) [0] > 2) + { + const guchar *inend = in+len-2; + int c1, c2, c3; + int already; + + already = *state; + + switch (((char *) save) [0]) + { + case 1: + c1 = ((unsigned char *) save) [1]; + goto skip1; + case 2: + c1 = ((unsigned char *) save) [1]; + c2 = ((unsigned char *) save) [2]; + goto skip2; + } + + /* + * yes, we jump into the loop, no i'm not going to change it, + * it's beautiful! + */ + while (inptr < inend) + { + c1 = *inptr++; + skip1: + c2 = *inptr++; + skip2: + c3 = *inptr++; + *outptr++ = base64_alphabet [ c1 >> 2 ]; + *outptr++ = base64_alphabet [ c2 >> 4 | + ((c1&0x3) << 4) ]; + *outptr++ = base64_alphabet [ ((c2 &0x0f) << 2) | + (c3 >> 6) ]; + *outptr++ = base64_alphabet [ c3 & 0x3f ]; + /* this is a bit ugly ... */ + if (break_lines && (++already) >= 19) + { + *outptr++ = '\n'; + already = 0; + } + } + + ((char *)save)[0] = 0; + len = 2 - (inptr - inend); + *state = already; + } + + if (len>0) + { + char *saveout; + + /* points to the slot for the next char to save */ + saveout = & (((char *)save)[1]) + ((char *)save)[0]; + + /* len can only be 0 1 or 2 */ + switch(len) + { + case 2: *saveout++ = *inptr++; + case 1: *saveout++ = *inptr++; + } + ((char *)save)[0] += len; + } + + return outptr - out; +} + +/** + * g_base64_encode_close: + * @break_lines: whether to break long lines + * @out: (out) (array) (element-type guint8): pointer to destination buffer + * @state: (inout): Saved state from g_base64_encode_step() + * @save: (inout): Saved state from g_base64_encode_step() + * + * Flush the status from a sequence of calls to g_base64_encode_step(). + * + * The output buffer must be large enough to fit all the data that will + * be written to it. It will need up to 4 bytes, or up to 5 bytes if + * line-breaking is enabled. + * + * Return value: The number of bytes of output that was written + * + * Since: 2.12 + */ +gsize +g_base64_encode_close (gboolean break_lines, + gchar *out, + gint *state, + gint *save) +{ + int c1, c2; + char *outptr = out; + + g_return_val_if_fail (out != NULL, 0); + g_return_val_if_fail (state != NULL, 0); + g_return_val_if_fail (save != NULL, 0); + + c1 = ((unsigned char *) save) [1]; + c2 = ((unsigned char *) save) [2]; + + switch (((char *) save) [0]) + { + case 2: + outptr [2] = base64_alphabet[ ( (c2 &0x0f) << 2 ) ]; + g_assert (outptr [2] != 0); + goto skip; + case 1: + outptr[2] = '='; + skip: + outptr [0] = base64_alphabet [ c1 >> 2 ]; + outptr [1] = base64_alphabet [ c2 >> 4 | ( (c1&0x3) << 4 )]; + outptr [3] = '='; + outptr += 4; + break; + } + if (break_lines) + *outptr++ = '\n'; + + *save = 0; + *state = 0; + + return outptr - out; +} + +/** + * g_base64_encode: + * @data: (array length=len) (element-type guint8): the binary data to encode + * @len: the length of @data + * + * Encode a sequence of binary data into its Base-64 stringified + * representation. + * + * Return value: (transfer full): a newly allocated, zero-terminated Base-64 + * encoded string representing @data. The returned string must + * be freed with g_free(). + * + * Since: 2.12 + */ +gchar * +g_base64_encode (const guchar *data, + gsize len) +{ + gchar *out; + gint state = 0, outlen; + gint save = 0; + + g_return_val_if_fail (data != NULL || len == 0, NULL); + + /* We can use a smaller limit here, since we know the saved state is 0, + +1 is needed for trailing \0, also check for unlikely integer overflow */ + if (len >= ((G_MAXSIZE - 1) / 4 - 1) * 3) + g_error("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)", + G_STRLOC, len); + + out = g_malloc ((len / 3 + 1) * 4 + 1); + + outlen = g_base64_encode_step (data, len, FALSE, out, &state, &save); + outlen += g_base64_encode_close (FALSE, out + outlen, &state, &save); + out[outlen] = '\0'; + + return (gchar *) out; +} + +static const unsigned char mime_base64_rank[256] = { + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255, 0,255,255, + 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255, + 255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, + 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255, +}; + +/** + * g_base64_decode_step: + * @in: (array length=len) (element-type guint8): binary input data + * @len: max length of @in data to decode + * @out: (out) (array) (element-type guint8): output buffer + * @state: (inout): Saved state between steps, initialize to 0 + * @save: (inout): Saved state between steps, initialize to 0 + * + * Incrementally decode a sequence of binary data from its Base-64 stringified + * representation. By calling this function multiple times you can convert + * data in chunks to avoid having to have the full encoded data in memory. + * + * The output buffer must be large enough to fit all the data that will + * be written to it. Since base64 encodes 3 bytes in 4 chars you need + * at least: (@len / 4) * 3 + 3 bytes (+ 3 may be needed in case of non-zero + * state). + * + * Return value: The number of bytes of output that was written + * + * Since: 2.12 + **/ +gsize +g_base64_decode_step (const gchar *in, + gsize len, + guchar *out, + gint *state, + guint *save) +{ + const guchar *inptr; + guchar *outptr; + const guchar *inend; + guchar c, rank; + guchar last[2]; + unsigned int v; + int i; + + g_return_val_if_fail (in != NULL, 0); + g_return_val_if_fail (out != NULL, 0); + g_return_val_if_fail (state != NULL, 0); + g_return_val_if_fail (save != NULL, 0); + + if (len <= 0) + return 0; + + inend = (const guchar *)in+len; + outptr = out; + + /* convert 4 base64 bytes to 3 normal bytes */ + v=*save; + i=*state; + inptr = (const guchar *)in; + last[0] = last[1] = 0; + while (inptr < inend) + { + c = *inptr++; + rank = mime_base64_rank [c]; + if (rank != 0xff) + { + last[1] = last[0]; + last[0] = c; + v = (v<<6) | rank; + i++; + if (i==4) + { + *outptr++ = v>>16; + if (last[1] != '=') + *outptr++ = v>>8; + if (last[0] != '=') + *outptr++ = v; + i=0; + } + } + } + + *save = v; + *state = i; + + return outptr - out; +} + +/** + * g_base64_decode: + * @text: zero-terminated string with base64 text to decode + * @out_len: (out): The length of the decoded data is written here + * + * Decode a sequence of Base-64 encoded text into binary data + * + * Return value: (transfer full) (array length=out_len) (element-type guint8): + * newly allocated buffer containing the binary data + * that @text represents. The returned buffer must + * be freed with g_free(). + * + * Since: 2.12 + */ +guchar * +g_base64_decode (const gchar *text, + gsize *out_len) +{ + guchar *ret; + gsize input_length; + gint state = 0; + guint save = 0; + + g_return_val_if_fail (text != NULL, NULL); + g_return_val_if_fail (out_len != NULL, NULL); + + input_length = strlen (text); + + /* We can use a smaller limit here, since we know the saved state is 0, + +1 used to avoid calling g_malloc0(0), and hence returning NULL */ + ret = g_malloc0 ((input_length / 4) * 3 + 1); + + *out_len = g_base64_decode_step (text, input_length, ret, &state, &save); + + return ret; +} + +/** + * g_base64_decode_inplace: + * @text: (inout) (array length=out_len) (element-type guint8): zero-terminated + * string with base64 text to decode + * @out_len: (inout): The length of the decoded data is written here + * + * Decode a sequence of Base-64 encoded text into binary data + * by overwriting the input data. + * + * Return value: (transfer none): The binary data that @text responds. This pointer + * is the same as the input @text. + * + * Since: 2.20 + */ +guchar * +g_base64_decode_inplace (gchar *text, + gsize *out_len) +{ + gint input_length, state = 0; + guint save = 0; + + g_return_val_if_fail (text != NULL, NULL); + g_return_val_if_fail (out_len != NULL, NULL); + + input_length = strlen (text); + + g_return_val_if_fail (input_length > 1, NULL); + + *out_len = g_base64_decode_step (text, input_length, (guchar *) text, &state, &save); + + return (guchar *) text; +} diff --git a/glib/glib/gbase64.h b/glib/glib/gbase64.h new file mode 100644 index 0000000..88ce6d8 --- /dev/null +++ b/glib/glib/gbase64.h @@ -0,0 +1,57 @@ +/* gbase64.h - Base64 coding functions + * + * Copyright (C) 2005 Alexander Larsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_BASE64_H__ +#define __G_BASE64_H__ + +#include + +G_BEGIN_DECLS + +gsize g_base64_encode_step (const guchar *in, + gsize len, + gboolean break_lines, + gchar *out, + gint *state, + gint *save); +gsize g_base64_encode_close (gboolean break_lines, + gchar *out, + gint *state, + gint *save); +gchar* g_base64_encode (const guchar *data, + gsize len) G_GNUC_MALLOC; +gsize g_base64_decode_step (const gchar *in, + gsize len, + guchar *out, + gint *state, + guint *save); +guchar *g_base64_decode (const gchar *text, + gsize *out_len) G_GNUC_MALLOC; +guchar *g_base64_decode_inplace (gchar *text, + gsize *out_len); + + +G_END_DECLS + +#endif /* __G_BASE64_H__ */ diff --git a/glib/glib/gbitlock.c b/glib/glib/gbitlock.c new file mode 100644 index 0000000..7b879be --- /dev/null +++ b/glib/glib/gbitlock.c @@ -0,0 +1,536 @@ +/* + * Copyright © 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#include "gbitlock.h" + +#include +#include +#include +#include +#include + +#include "gthreadprivate.h" +#include "config.h" + +#undef HAVE_FUTEX +#ifdef G_BIT_LOCK_FORCE_FUTEX_EMULATION +#endif + +#ifndef HAVE_FUTEX +static GMutex g_futex_mutex; +static GSList *g_futex_address_list = NULL; +#endif + +#ifdef HAVE_FUTEX +/* + * We have headers for futex(2) on the build machine. This does not + * imply that every system that ever runs the resulting glib will have + * kernel support for futex, but you'd have to have a pretty old + * kernel in order for that not to be the case. + * + * If anyone actually gets bit by this, please file a bug. :) + */ +#include +#include +#include + +/* < private > + * g_futex_wait: + * @address: a pointer to an integer + * @value: the value that should be at @address + * + * Atomically checks that the value stored at @address is equal to + * @value and then blocks. If the value stored at @address is not + * equal to @value then this function returns immediately. + * + * To unblock, call g_futex_wake() on @address. + * + * This call may spuriously unblock (for example, in response to the + * process receiving a signal) but this is not guaranteed. Unlike the + * Linux system call of a similar name, there is no guarantee that a + * waiting process will unblock due to a g_futex_wake() call in a + * separate process. + */ +static void +g_futex_wait (const volatile gint *address, + gint value) +{ + syscall (__NR_futex, address, (gsize) FUTEX_WAIT, (gsize) value, NULL); +} + +/* < private > + * g_futex_wake: + * @address: a pointer to an integer + * + * Nominally, wakes one thread that is blocked in g_futex_wait() on + * @address (if any thread is currently waiting). + * + * As mentioned in the documention for g_futex_wait(), spurious + * wakeups may occur. As such, this call may result in more than one + * thread being woken up. + */ +static void +g_futex_wake (const volatile gint *address) +{ + syscall (__NR_futex, address, (gsize) FUTEX_WAKE, (gsize) 1, NULL); +} + +#else + +/* emulate futex(2) */ +typedef struct +{ + const volatile gint *address; + gint ref_count; + GCond wait_queue; +} WaitAddress; + +static WaitAddress * +g_futex_find_address (const volatile gint *address) +{ + GSList *node; + + for (node = g_futex_address_list; node; node = node->next) + { + WaitAddress *waiter = node->data; + + if (waiter->address == address) + return waiter; + } + + return NULL; +} + +static void +g_futex_wait (const volatile gint *address, + gint value) +{ + g_mutex_lock (&g_futex_mutex); + if G_LIKELY (g_atomic_int_get (address) == value) + { + WaitAddress *waiter; + + if ((waiter = g_futex_find_address (address)) == NULL) + { + waiter = g_slice_new (WaitAddress); + waiter->address = address; + g_cond_init (&waiter->wait_queue); + waiter->ref_count = 0; + g_futex_address_list = + g_slist_prepend (g_futex_address_list, waiter); + } + + waiter->ref_count++; + g_cond_wait (&waiter->wait_queue, &g_futex_mutex); + + if (!--waiter->ref_count) + { + g_futex_address_list = + g_slist_remove (g_futex_address_list, waiter); + g_cond_clear (&waiter->wait_queue); + g_slice_free (WaitAddress, waiter); + } + } + g_mutex_unlock (&g_futex_mutex); +} + +static void +g_futex_wake (const volatile gint *address) +{ + WaitAddress *waiter; + + /* need to lock here for two reasons: + * 1) need to acquire/release lock to ensure waiter is not in + * the process of registering a wait + * 2) need to -stay- locked until the end to ensure a wake() + * in another thread doesn't cause 'waiter' to stop existing + */ + g_mutex_lock (&g_futex_mutex); + if ((waiter = g_futex_find_address (address))) + g_cond_signal (&waiter->wait_queue); + g_mutex_unlock (&g_futex_mutex); +} +#endif + +#define CONTENTION_CLASSES 11 +static volatile gint g_bit_lock_contended[CONTENTION_CLASSES]; + +#if (defined (i386) || defined (__amd64__)) + #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + #define USE_ASM_GOTO 1 + #endif +#endif + +/** + * g_bit_lock: + * @address: a pointer to an integer + * @lock_bit: a bit value between 0 and 31 + * + * Sets the indicated @lock_bit in @address. If the bit is already + * set, this call will block until g_bit_unlock() unsets the + * corresponding bit. + * + * Attempting to lock on two different bits within the same integer is + * not supported and will very probably cause deadlocks. + * + * The value of the bit that is set is (1u << @bit). If @bit is not + * between 0 and 31 then the result is undefined. + * + * This function accesses @address atomically. All other accesses to + * @address must be atomic in order for this function to work + * reliably. + * + * Since: 2.24 + **/ +void +g_bit_lock (volatile gint *address, + gint lock_bit) +{ +#ifdef USE_ASM_GOTO + retry: + asm volatile goto ("lock bts %1, (%0)\n" + "jc %l[contended]" + : /* no output */ + : "r" (address), "r" (lock_bit) + : "cc", "memory" + : contended); + return; + + contended: + { + guint mask = 1u << lock_bit; + guint v; + + v = g_atomic_int_get (address); + if (v & mask) + { + guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); + + g_atomic_int_add (&g_bit_lock_contended[class], +1); + g_futex_wait (address, v); + g_atomic_int_add (&g_bit_lock_contended[class], -1); + } + } + goto retry; +#else + guint mask = 1u << lock_bit; + guint v; + + retry: + v = g_atomic_int_or (address, mask); + if (v & mask) + /* already locked */ + { + guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); + + g_atomic_int_add (&g_bit_lock_contended[class], +1); + g_futex_wait (address, v); + g_atomic_int_add (&g_bit_lock_contended[class], -1); + + goto retry; + } +#endif +} + +/** + * g_bit_trylock: + * @address: a pointer to an integer + * @lock_bit: a bit value between 0 and 31 + * + * Sets the indicated @lock_bit in @address, returning %TRUE if + * successful. If the bit is already set, returns %FALSE immediately. + * + * Attempting to lock on two different bits within the same integer is + * not supported. + * + * The value of the bit that is set is (1u << @bit). If @bit is not + * between 0 and 31 then the result is undefined. + * + * This function accesses @address atomically. All other accesses to + * @address must be atomic in order for this function to work + * reliably. + * + * Returns: %TRUE if the lock was acquired + * + * Since: 2.24 + **/ +gboolean +g_bit_trylock (volatile gint *address, + gint lock_bit) +{ +#ifdef USE_ASM_GOTO + gboolean result; + + asm volatile ("lock bts %2, (%1)\n" + "setnc %%al\n" + "movzx %%al, %0" + : "=r" (result) + : "r" (address), "r" (lock_bit) + : "cc", "memory"); + + return result; +#else + guint mask = 1u << lock_bit; + guint v; + + v = g_atomic_int_or (address, mask); + + return ~v & mask; +#endif +} + +/** + * g_bit_unlock: + * @address: a pointer to an integer + * @lock_bit: a bit value between 0 and 31 + * + * Clears the indicated @lock_bit in @address. If another thread is + * currently blocked in g_bit_lock() on this same bit then it will be + * woken up. + * + * This function accesses @address atomically. All other accesses to + * @address must be atomic in order for this function to work + * reliably. + * + * Since: 2.24 + **/ +void +g_bit_unlock (volatile gint *address, + gint lock_bit) +{ +#ifdef USE_ASM_GOTO + asm volatile ("lock btr %1, (%0)" + : /* no output */ + : "r" (address), "r" (lock_bit) + : "cc", "memory"); +#else + guint mask = 1u << lock_bit; + + g_atomic_int_and (address, ~mask); +#endif + + { + guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); + + if (g_atomic_int_get (&g_bit_lock_contended[class])) + g_futex_wake (address); + } +} + + +/* We emulate pointer-sized futex(2) because the kernel API only + * supports integers. + * + * We assume that the 'interesting' part is always the lower order bits. + * This assumption holds because pointer bitlocks are restricted to + * using the low order bits of the pointer as the lock. + * + * On 32 bits, there is nothing to do since the pointer size is equal to + * the integer size. On little endian the lower-order bits don't move, + * so do nothing. Only on 64bit big endian do we need to do a bit of + * pointer arithmetic: the low order bits are shifted by 4 bytes. We + * have a helper function that always does the right thing here. + * + * Since we always consider the low-order bits of the integer value, a + * simple cast from (gsize) to (guint) always takes care of that. + * + * After that, pointer-sized futex becomes as simple as: + * + * g_futex_wait (g_futex_int_address (address), (guint) value); + * + * and + * + * g_futex_wake (g_futex_int_address (int_address)); + */ +static const volatile gint * +g_futex_int_address (const volatile void *address) +{ + const volatile gint *int_address = address; + + /* this implementation makes these (reasonable) assumptions: */ + G_STATIC_ASSERT (G_BYTE_ORDER == G_LITTLE_ENDIAN || + (G_BYTE_ORDER == G_BIG_ENDIAN && + sizeof (int) == 4 && + (sizeof (gpointer) == 4 || sizeof (gpointer) == 8))); + +#if G_BYTE_ORDER == G_BIG_ENDIAN && GLIB_SIZEOF_VOID_P == 8 + int_address++; +#endif + + return int_address; +} + +/** + * g_pointer_bit_lock: + * @address: a pointer to a #gpointer-sized value + * @lock_bit: a bit value between 0 and 31 + * + * This is equivalent to g_bit_lock, but working on pointers (or other + * pointer-sized values). + * + * For portability reasons, you may only lock on the bottom 32 bits of + * the pointer. + * + * Since: 2.30 + **/ +void +(g_pointer_bit_lock) (volatile void *address, + gint lock_bit) +{ + g_return_if_fail (lock_bit < 32); + + { +#ifdef USE_ASM_GOTO + retry: + asm volatile goto ("lock bts %1, (%0)\n" + "jc %l[contended]" + : /* no output */ + : "r" (address), "r" ((gsize) lock_bit) + : "cc", "memory" + : contended); + return; + + contended: + { + volatile gsize *pointer_address = address; + gsize mask = 1u << lock_bit; + gsize v; + + v = (gsize) g_atomic_pointer_get (pointer_address); + if (v & mask) + { + guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); + + g_atomic_int_add (&g_bit_lock_contended[class], +1); + g_futex_wait (g_futex_int_address (address), v); + g_atomic_int_add (&g_bit_lock_contended[class], -1); + } + } + goto retry; +#else + volatile gsize *pointer_address = address; + gsize mask = 1u << lock_bit; + gsize v; + + retry: + v = g_atomic_pointer_or (pointer_address, mask); + if (v & mask) + /* already locked */ + { + guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); + + g_atomic_int_add (&g_bit_lock_contended[class], +1); + g_futex_wait (g_futex_int_address (address), (guint) v); + g_atomic_int_add (&g_bit_lock_contended[class], -1); + + goto retry; + } +#endif + } +} + +/** + * g_pointer_bit_trylock: + * @address: a pointer to a #gpointer-sized value + * @lock_bit: a bit value between 0 and 31 + * + * This is equivalent to g_bit_trylock, but working on pointers (or + * other pointer-sized values). + * + * For portability reasons, you may only lock on the bottom 32 bits of + * the pointer. + * + * Returns: %TRUE if the lock was acquired + * + * Since: 2.30 + **/ +gboolean +(g_pointer_bit_trylock) (volatile void *address, + gint lock_bit) +{ + g_return_val_if_fail (lock_bit < 32, FALSE); + + { +#ifdef USE_ASM_GOTO + gboolean result; + + asm volatile ("lock bts %2, (%1)\n" + "setnc %%al\n" + "movzx %%al, %0" + : "=r" (result) + : "r" (address), "r" ((gsize) lock_bit) + : "cc", "memory"); + + return result; +#else + volatile gsize *pointer_address = address; + gsize mask = 1u << lock_bit; + gsize v; + + g_return_val_if_fail (lock_bit < 32, FALSE); + + v = g_atomic_pointer_or (pointer_address, mask); + + return ~v & mask; +#endif + } +} + +/** + * g_pointer_bit_unlock: + * @address: a pointer to a #gpointer-sized value + * @lock_bit: a bit value between 0 and 31 + * + * This is equivalent to g_bit_unlock, but working on pointers (or other + * pointer-sized values). + * + * For portability reasons, you may only lock on the bottom 32 bits of + * the pointer. + * + * Since: 2.30 + **/ +void +(g_pointer_bit_unlock) (volatile void *address, + gint lock_bit) +{ + g_return_if_fail (lock_bit < 32); + + { +#ifdef USE_ASM_GOTO + asm volatile ("lock btr %1, (%0)" + : /* no output */ + : "r" (address), "r" ((gsize) lock_bit) + : "cc", "memory"); +#else + volatile gsize *pointer_address = address; + gsize mask = 1u << lock_bit; + + g_atomic_pointer_and (pointer_address, ~mask); +#endif + + { + guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended); + if (g_atomic_int_get (&g_bit_lock_contended[class])) + g_futex_wake (g_futex_int_address (address)); + } + } +} diff --git a/glib/glib/gbitlock.h b/glib/glib/gbitlock.h new file mode 100644 index 0000000..641ee69 --- /dev/null +++ b/glib/glib/gbitlock.h @@ -0,0 +1,72 @@ +/* + * Copyright © 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#ifndef __G_BITLOCK_H__ +#define __G_BITLOCK_H__ + +#include + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +G_BEGIN_DECLS + +void g_bit_lock (volatile gint *address, + gint lock_bit); +gboolean g_bit_trylock (volatile gint *address, + gint lock_bit); +void g_bit_unlock (volatile gint *address, + gint lock_bit); + +void g_pointer_bit_lock (volatile void *address, + gint lock_bit); +gboolean g_pointer_bit_trylock (volatile void *address, + gint lock_bit); +void g_pointer_bit_unlock (volatile void *address, + gint lock_bit); + +#ifdef __GNUC__ + +#define g_pointer_bit_lock(address, lock_bit) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ + g_pointer_bit_lock ((address), (lock_bit)); \ + })) + +#define g_pointer_bit_trylock(address, lock_bit) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ + g_pointer_bit_trylock ((address), (lock_bit)); \ + })) + +#define g_pointer_bit_unlock(address, lock_bit) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(address) == sizeof (gpointer)); \ + g_pointer_bit_unlock ((address), (lock_bit)); \ + })) + +#endif + +G_END_DECLS + +#endif /* __G_BITLOCK_H_ */ diff --git a/glib/glib/gbookmarkfile.c b/glib/glib/gbookmarkfile.c new file mode 100644 index 0000000..5b5ff50 --- /dev/null +++ b/glib/glib/gbookmarkfile.c @@ -0,0 +1,3713 @@ +/* gbookmarkfile.c: parsing and building desktop bookmarks + * + * Copyright (C) 2005-2006 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + */ + +#include "config.h" + +#include "gbookmarkfile.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "gconvert.h" +#include "gdataset.h" +#include "gerror.h" +#include "gfileutils.h" +#include "ghash.h" +#include "glibintl.h" +#include "glist.h" +#include "gslist.h" +#include "gmain.h" +#include "gmarkup.h" +#include "gmem.h" +#include "gmessages.h" +#include "gshell.h" +#include "gslice.h" +#include "gstdio.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "gtimer.h" +#include "gutils.h" + + +/** + * SECTION:bookmarkfile + * @title: Bookmark file parser + * @short_description: parses files containing bookmarks + * + * GBookmarkFile lets you parse, edit or create files containing bookmarks + * to URI, along with some meta-data about the resource pointed by the URI + * like its MIME type, the application that is registering the bookmark and + * the icon that should be used to represent the bookmark. The data is stored + * using the + * Desktop Bookmark + * Specification. + * + * The syntax of the bookmark files is described in detail inside the Desktop + * Bookmark Specification, here is a quick summary: bookmark files use a + * sub-class of the XML Bookmark Exchange Language + * specification, consisting of valid UTF-8 encoded XML, under the + * xbel root element; each bookmark is stored inside a + * bookmark element, using its URI: no relative paths can + * be used inside a bookmark file. The bookmark may have a user defined title + * and description, to be used instead of the URI. Under the + * metadata element, with its owner + * attribute set to http://freedesktop.org, is stored the + * meta-data about a resource pointed by its URI. The meta-data consists of + * the resource's MIME type; the applications that have registered a bookmark; + * the groups to which a bookmark belongs to; a visibility flag, used to set + * the bookmark as "private" to the applications and groups that has it + * registered; the URI and MIME type of an icon, to be used when displaying + * the bookmark inside a GUI. + * |[FIXME: MISSING XINCLUDE CONTENT]| + * + * A bookmark file might contain more than one bookmark; each bookmark + * is accessed through its URI. + * + * The important caveat of bookmark files is that when you add a new + * bookmark you must also add the application that is registering it, using + * g_bookmark_file_add_application() or g_bookmark_file_set_app_info(). + * If a bookmark has no applications then it won't be dumped when creating + * the on disk representation, using g_bookmark_file_to_data() or + * g_bookmark_file_to_file(). + * + * The #GBookmarkFile parser was added in GLib 2.12. + */ + +/* XBEL 1.0 standard entities */ +#define XBEL_VERSION "1.0" +#define XBEL_DTD_NICK "xbel" +#define XBEL_DTD_SYSTEM "+//IDN python.org//DTD XML Bookmark " \ + "Exchange Language 1.0//EN//XML" + +#define XBEL_DTD_URI "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd" + +#define XBEL_ROOT_ELEMENT "xbel" +#define XBEL_FOLDER_ELEMENT "folder" /* unused */ +#define XBEL_BOOKMARK_ELEMENT "bookmark" +#define XBEL_ALIAS_ELEMENT "alias" /* unused */ +#define XBEL_SEPARATOR_ELEMENT "separator" /* unused */ +#define XBEL_TITLE_ELEMENT "title" +#define XBEL_DESC_ELEMENT "desc" +#define XBEL_INFO_ELEMENT "info" +#define XBEL_METADATA_ELEMENT "metadata" + +#define XBEL_VERSION_ATTRIBUTE "version" +#define XBEL_FOLDED_ATTRIBUTE "folded" /* unused */ +#define XBEL_OWNER_ATTRIBUTE "owner" +#define XBEL_ADDED_ATTRIBUTE "added" +#define XBEL_VISITED_ATTRIBUTE "visited" +#define XBEL_MODIFIED_ATTRIBUTE "modified" +#define XBEL_ID_ATTRIBUTE "id" +#define XBEL_HREF_ATTRIBUTE "href" +#define XBEL_REF_ATTRIBUTE "ref" /* unused */ + +#define XBEL_YES_VALUE "yes" +#define XBEL_NO_VALUE "no" + +/* Desktop bookmark spec entities */ +#define BOOKMARK_METADATA_OWNER "http://freedesktop.org" + +#define BOOKMARK_NAMESPACE_NAME "bookmark" +#define BOOKMARK_NAMESPACE_URI "http://www.freedesktop.org/standards/desktop-bookmarks" + +#define BOOKMARK_GROUPS_ELEMENT "groups" +#define BOOKMARK_GROUP_ELEMENT "group" +#define BOOKMARK_APPLICATIONS_ELEMENT "applications" +#define BOOKMARK_APPLICATION_ELEMENT "application" +#define BOOKMARK_ICON_ELEMENT "icon" +#define BOOKMARK_PRIVATE_ELEMENT "private" + +#define BOOKMARK_NAME_ATTRIBUTE "name" +#define BOOKMARK_EXEC_ATTRIBUTE "exec" +#define BOOKMARK_COUNT_ATTRIBUTE "count" +#define BOOKMARK_TIMESTAMP_ATTRIBUTE "timestamp" /* deprecated by "modified" */ +#define BOOKMARK_MODIFIED_ATTRIBUTE "modified" +#define BOOKMARK_HREF_ATTRIBUTE "href" +#define BOOKMARK_TYPE_ATTRIBUTE "type" + +/* Shared MIME Info entities */ +#define MIME_NAMESPACE_NAME "mime" +#define MIME_NAMESPACE_URI "http://www.freedesktop.org/standards/shared-mime-info" +#define MIME_TYPE_ELEMENT "mime-type" +#define MIME_TYPE_ATTRIBUTE "type" + + +typedef struct _BookmarkAppInfo BookmarkAppInfo; +typedef struct _BookmarkMetadata BookmarkMetadata; +typedef struct _BookmarkItem BookmarkItem; +typedef struct _ParseData ParseData; + +struct _BookmarkAppInfo +{ + gchar *name; + gchar *exec; + + guint count; + + time_t stamp; +}; + +struct _BookmarkMetadata +{ + gchar *mime_type; + + GList *groups; + + GList *applications; + GHashTable *apps_by_name; + + gchar *icon_href; + gchar *icon_mime; + + guint is_private : 1; +}; + +struct _BookmarkItem +{ + gchar *uri; + + gchar *title; + gchar *description; + + time_t added; + time_t modified; + time_t visited; + + BookmarkMetadata *metadata; +}; + +struct _GBookmarkFile +{ + gchar *title; + gchar *description; + + /* we store our items in a list and keep a copy inside + * an hash table for faster lookup performances + */ + GList *items; + GHashTable *items_by_uri; +}; + +/* parser state machine */ +enum +{ + STATE_STARTED = 0, + + STATE_ROOT, + STATE_BOOKMARK, + STATE_TITLE, + STATE_DESC, + STATE_INFO, + STATE_METADATA, + STATE_APPLICATIONS, + STATE_APPLICATION, + STATE_GROUPS, + STATE_GROUP, + STATE_MIME, + STATE_ICON, + + STATE_FINISHED +}; + +static void g_bookmark_file_init (GBookmarkFile *bookmark); +static void g_bookmark_file_clear (GBookmarkFile *bookmark); +static gboolean g_bookmark_file_parse (GBookmarkFile *bookmark, + const gchar *buffer, + gsize length, + GError **error); +static gchar * g_bookmark_file_dump (GBookmarkFile *bookmark, + gsize *length, + GError **error); +static BookmarkItem *g_bookmark_file_lookup_item (GBookmarkFile *bookmark, + const gchar *uri); +static void g_bookmark_file_add_item (GBookmarkFile *bookmark, + BookmarkItem *item, + GError **error); + +static time_t timestamp_from_iso8601 (const gchar *iso_date); +static gchar * timestamp_to_iso8601 (time_t timestamp); + +/******************************** + * BookmarkAppInfo * + * * + * Application metadata storage * + ********************************/ +static BookmarkAppInfo * +bookmark_app_info_new (const gchar *name) +{ + BookmarkAppInfo *retval; + + g_warn_if_fail (name != NULL); + + retval = g_slice_new (BookmarkAppInfo); + + retval->name = g_strdup (name); + retval->exec = NULL; + retval->count = 0; + retval->stamp = 0; + + return retval; +} + +static void +bookmark_app_info_free (BookmarkAppInfo *app_info) +{ + if (!app_info) + return; + + g_free (app_info->name); + g_free (app_info->exec); + + g_slice_free (BookmarkAppInfo, app_info); +} + +static gchar * +bookmark_app_info_dump (BookmarkAppInfo *app_info) +{ + gchar *retval; + gchar *name, *exec, *modified, *count; + + g_warn_if_fail (app_info != NULL); + + if (app_info->count == 0) + return NULL; + + name = g_markup_escape_text (app_info->name, -1); + exec = g_markup_escape_text (app_info->exec, -1); + modified = timestamp_to_iso8601 (app_info->stamp); + count = g_strdup_printf ("%u", app_info->count); + + retval = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME ":" BOOKMARK_APPLICATION_ELEMENT + " " BOOKMARK_NAME_ATTRIBUTE "=\"", name, "\"" + " " BOOKMARK_EXEC_ATTRIBUTE "=\"", exec, "\"" + " " BOOKMARK_MODIFIED_ATTRIBUTE "=\"", modified, "\"" + " " BOOKMARK_COUNT_ATTRIBUTE "=\"", count, "\"/>\n", + NULL); + + g_free (name); + g_free (exec); + g_free (modified); + g_free (count); + + return retval; +} + + +/*********************** + * BookmarkMetadata * + * * + * Metadata storage * + ***********************/ +static BookmarkMetadata * +bookmark_metadata_new (void) +{ + BookmarkMetadata *retval; + + retval = g_slice_new (BookmarkMetadata); + + retval->mime_type = NULL; + + retval->groups = NULL; + + retval->applications = NULL; + retval->apps_by_name = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); + + retval->is_private = FALSE; + + retval->icon_href = NULL; + retval->icon_mime = NULL; + + return retval; +} + +static void +bookmark_metadata_free (BookmarkMetadata *metadata) +{ + if (!metadata) + return; + + g_free (metadata->mime_type); + + g_list_free_full (metadata->groups, g_free); + g_list_free_full (metadata->applications, (GDestroyNotify) bookmark_app_info_free); + + g_hash_table_destroy (metadata->apps_by_name); + + g_free (metadata->icon_href); + g_free (metadata->icon_mime); + + g_slice_free (BookmarkMetadata, metadata); +} + +static gchar * +bookmark_metadata_dump (BookmarkMetadata *metadata) +{ + GString *retval; + gchar *buffer; + + if (!metadata->applications) + return NULL; + + retval = g_string_sized_new (1024); + + /* metadata container */ + g_string_append (retval, + " " + "<" XBEL_METADATA_ELEMENT + " " XBEL_OWNER_ATTRIBUTE "=\"" BOOKMARK_METADATA_OWNER + "\">\n"); + + /* mime type */ + if (metadata->mime_type) { + buffer = g_strconcat (" " + "<" MIME_NAMESPACE_NAME ":" MIME_TYPE_ELEMENT " " + MIME_TYPE_ATTRIBUTE "=\"", metadata->mime_type, "\"/>\n", + NULL); + g_string_append (retval, buffer); + g_free (buffer); + } + + if (metadata->groups) + { + GList *l; + + /* open groups container */ + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_GROUPS_ELEMENT ">\n"); + + for (l = g_list_last (metadata->groups); l != NULL; l = l->prev) + { + gchar *group_name; + + group_name = g_markup_escape_text ((gchar *) l->data, -1); + buffer = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_GROUP_ELEMENT ">", + group_name, + "\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); + g_free (group_name); + } + + /* close groups container */ + g_string_append (retval, + " " + "\n"); + } + + if (metadata->applications) + { + GList *l; + + /* open applications container */ + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_APPLICATIONS_ELEMENT ">\n"); + + for (l = g_list_last (metadata->applications); l != NULL; l = l->prev) + { + BookmarkAppInfo *app_info = (BookmarkAppInfo *) l->data; + gchar *app_data; + + g_warn_if_fail (app_info != NULL); + + app_data = bookmark_app_info_dump (app_info); + + if (app_data) + { + retval = g_string_append (retval, app_data); + + g_free (app_data); + } + } + + /* close applications container */ + g_string_append (retval, + " " + "\n"); + } + + /* icon */ + if (metadata->icon_href) + { + if (!metadata->icon_mime) + metadata->icon_mime = g_strdup ("application/octet-stream"); + + buffer = g_strconcat (" " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_ICON_ELEMENT + " " BOOKMARK_HREF_ATTRIBUTE "=\"", metadata->icon_href, + "\" " BOOKMARK_TYPE_ATTRIBUTE "=\"", metadata->icon_mime, "\"/>\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); + } + + /* private hint */ + if (metadata->is_private) + g_string_append (retval, + " " + "<" BOOKMARK_NAMESPACE_NAME + ":" BOOKMARK_PRIVATE_ELEMENT "/>\n"); + + /* close metadata container */ + g_string_append (retval, + " " + "\n"); + + return g_string_free (retval, FALSE); +} + +/****************************************************** + * BookmarkItem * + * * + * Storage for a single bookmark item inside the list * + ******************************************************/ +static BookmarkItem * +bookmark_item_new (const gchar *uri) +{ + BookmarkItem *item; + + g_warn_if_fail (uri != NULL); + + item = g_slice_new (BookmarkItem); + item->uri = g_strdup (uri); + + item->title = NULL; + item->description = NULL; + + item->added = (time_t) -1; + item->modified = (time_t) -1; + item->visited = (time_t) -1; + + item->metadata = NULL; + + return item; +} + +static void +bookmark_item_free (BookmarkItem *item) +{ + if (!item) + return; + + g_free (item->uri); + g_free (item->title); + g_free (item->description); + + if (item->metadata) + bookmark_metadata_free (item->metadata); + + g_slice_free (BookmarkItem, item); +} + +static gchar * +bookmark_item_dump (BookmarkItem *item) +{ + GString *retval; + gchar *added, *visited, *modified; + gchar *escaped_uri; + gchar *buffer; + + /* at this point, we must have at least a registered application; if we don't + * we don't screw up the bookmark file, and just skip this item + */ + if (!item->metadata || !item->metadata->applications) + { + g_warning ("Item for URI '%s' has no registered applications: skipping.\n", item->uri); + return NULL; + } + + retval = g_string_sized_new (4096); + + added = timestamp_to_iso8601 (item->added); + modified = timestamp_to_iso8601 (item->modified); + visited = timestamp_to_iso8601 (item->visited); + + escaped_uri = g_markup_escape_text (item->uri, -1); + + buffer = g_strconcat (" <" + XBEL_BOOKMARK_ELEMENT + " " + XBEL_HREF_ATTRIBUTE "=\"", escaped_uri, "\" " + XBEL_ADDED_ATTRIBUTE "=\"", added, "\" " + XBEL_MODIFIED_ATTRIBUTE "=\"", modified, "\" " + XBEL_VISITED_ATTRIBUTE "=\"", visited, "\">\n", + NULL); + + g_string_append (retval, buffer); + + g_free (escaped_uri); + g_free (visited); + g_free (modified); + g_free (added); + g_free (buffer); + + if (item->title) + { + gchar *escaped_title; + + escaped_title = g_markup_escape_text (item->title, -1); + buffer = g_strconcat (" " + "<" XBEL_TITLE_ELEMENT ">", + escaped_title, + "\n", + NULL); + g_string_append (retval, buffer); + + g_free (escaped_title); + g_free (buffer); + } + + if (item->description) + { + gchar *escaped_desc; + + escaped_desc = g_markup_escape_text (item->description, -1); + buffer = g_strconcat (" " + "<" XBEL_DESC_ELEMENT ">", + escaped_desc, + "\n", + NULL); + g_string_append (retval, buffer); + + g_free (escaped_desc); + g_free (buffer); + } + + if (item->metadata) + { + gchar *metadata; + + metadata = bookmark_metadata_dump (item->metadata); + if (metadata) + { + buffer = g_strconcat (" " + "<" XBEL_INFO_ELEMENT ">\n", + metadata, + " " + "\n", + NULL); + retval = g_string_append (retval, buffer); + + g_free (buffer); + g_free (metadata); + } + } + + g_string_append (retval, " \n"); + + return g_string_free (retval, FALSE); +} + +static BookmarkAppInfo * +bookmark_item_lookup_app_info (BookmarkItem *item, + const gchar *app_name) +{ + g_warn_if_fail (item != NULL && app_name != NULL); + + if (!item->metadata) + return NULL; + + return g_hash_table_lookup (item->metadata->apps_by_name, app_name); +} + +/************************* + * GBookmarkFile * + *************************/ + +static void +g_bookmark_file_init (GBookmarkFile *bookmark) +{ + bookmark->title = NULL; + bookmark->description = NULL; + + bookmark->items = NULL; + bookmark->items_by_uri = g_hash_table_new_full (g_str_hash, + g_str_equal, + NULL, + NULL); +} + +static void +g_bookmark_file_clear (GBookmarkFile *bookmark) +{ + g_free (bookmark->title); + g_free (bookmark->description); + + g_list_free_full (bookmark->items, (GDestroyNotify) bookmark_item_free); + bookmark->items = NULL; + + if (bookmark->items_by_uri) + { + g_hash_table_destroy (bookmark->items_by_uri); + + bookmark->items_by_uri = NULL; + } +} + +struct _ParseData +{ + gint state; + + GHashTable *namespaces; + + GBookmarkFile *bookmark_file; + BookmarkItem *current_item; +}; + +static ParseData * +parse_data_new (void) +{ + ParseData *retval; + + retval = g_new (ParseData, 1); + + retval->state = STATE_STARTED; + retval->namespaces = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, + (GDestroyNotify) g_free); + retval->bookmark_file = NULL; + retval->current_item = NULL; + + return retval; +} + +static void +parse_data_free (ParseData *parse_data) +{ + g_hash_table_destroy (parse_data->namespaces); + + g_free (parse_data); +} + +#define IS_ATTRIBUTE(s,a) ((0 == strcmp ((s), (a)))) + +static void +parse_bookmark_element (GMarkupParseContext *context, + ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error) +{ + const gchar *uri, *added, *modified, *visited; + const gchar *attr; + gint i; + BookmarkItem *item; + GError *add_error; + + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_BOOKMARK)); + + i = 0; + uri = added = modified = visited = NULL; + for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) + { + if (IS_ATTRIBUTE (attr, XBEL_HREF_ATTRIBUTE)) + uri = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, XBEL_ADDED_ATTRIBUTE)) + added = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, XBEL_MODIFIED_ATTRIBUTE)) + modified = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, XBEL_VISITED_ATTRIBUTE)) + visited = attribute_values[i]; + else + { + /* bookmark is defined by the XBEL spec, so we need + * to error out if the element has different or + * missing attributes + */ + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, + _("Unexpected attribute '%s' for element '%s'"), + attr, + XBEL_BOOKMARK_ELEMENT); + return; + } + } + + if (!uri) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Attribute '%s' of element '%s' not found"), + XBEL_HREF_ATTRIBUTE, + XBEL_BOOKMARK_ELEMENT); + return; + } + + g_warn_if_fail (parse_data->current_item == NULL); + + item = bookmark_item_new (uri); + + if (added) + item->added = timestamp_from_iso8601 (added); + + if (modified) + item->modified = timestamp_from_iso8601 (modified); + + if (visited) + item->visited = timestamp_from_iso8601 (visited); + + add_error = NULL; + g_bookmark_file_add_item (parse_data->bookmark_file, + item, + &add_error); + if (add_error) + { + bookmark_item_free (item); + + g_propagate_error (error, add_error); + + return; + } + + parse_data->current_item = item; +} + +static void +parse_application_element (GMarkupParseContext *context, + ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error) +{ + const gchar *name, *exec, *count, *stamp, *modified; + const gchar *attr; + gint i; + BookmarkItem *item; + BookmarkAppInfo *ai; + + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_APPLICATION)); + + i = 0; + name = exec = count = stamp = modified = NULL; + for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) + { + if (IS_ATTRIBUTE (attr, BOOKMARK_NAME_ATTRIBUTE)) + name = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_EXEC_ATTRIBUTE)) + exec = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_COUNT_ATTRIBUTE)) + count = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_TIMESTAMP_ATTRIBUTE)) + stamp = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_MODIFIED_ATTRIBUTE)) + modified = attribute_values[i]; + } + + /* the "name" and "exec" attributes are mandatory */ + if (!name) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Attribute '%s' of element '%s' not found"), + BOOKMARK_NAME_ATTRIBUTE, + BOOKMARK_APPLICATION_ELEMENT); + return; + } + + if (!exec) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Attribute '%s' of element '%s' not found"), + BOOKMARK_EXEC_ATTRIBUTE, + BOOKMARK_APPLICATION_ELEMENT); + return; + } + + g_warn_if_fail (parse_data->current_item != NULL); + item = parse_data->current_item; + + ai = bookmark_item_lookup_app_info (item, name); + if (!ai) + { + ai = bookmark_app_info_new (name); + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + item->metadata->applications = g_list_prepend (item->metadata->applications, ai); + g_hash_table_replace (item->metadata->apps_by_name, ai->name, ai); + } + + ai->exec = g_strdup (exec); + + if (count) + ai->count = atoi (count); + else + ai->count = 1; + + if (modified) + ai->stamp = timestamp_from_iso8601 (modified); + else + { + /* the timestamp attribute has been deprecated but we still parse + * it for backward compatibility + */ + if (stamp) + ai->stamp = (time_t) atol (stamp); + else + ai->stamp = time (NULL); + } +} + +static void +parse_mime_type_element (GMarkupParseContext *context, + ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error) +{ + const gchar *type; + const gchar *attr; + gint i; + BookmarkItem *item; + + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_MIME)); + + i = 0; + type = NULL; + for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) + { + if (IS_ATTRIBUTE (attr, MIME_TYPE_ATTRIBUTE)) + type = attribute_values[i]; + } + + if (!type) + type = "application/octet-stream"; + + g_warn_if_fail (parse_data->current_item != NULL); + item = parse_data->current_item; + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + item->metadata->mime_type = g_strdup (type); +} + +static void +parse_icon_element (GMarkupParseContext *context, + ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values, + GError **error) +{ + const gchar *href; + const gchar *type; + const gchar *attr; + gint i; + BookmarkItem *item; + + g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_ICON)); + + i = 0; + href = NULL; + type = NULL; + for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i]) + { + if (IS_ATTRIBUTE (attr, BOOKMARK_HREF_ATTRIBUTE)) + href = attribute_values[i]; + else if (IS_ATTRIBUTE (attr, BOOKMARK_TYPE_ATTRIBUTE)) + type = attribute_values[i]; + } + + /* the "href" attribute is mandatory */ + if (!href) + { + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Attribute '%s' of element '%s' not found"), + BOOKMARK_HREF_ATTRIBUTE, + BOOKMARK_ICON_ELEMENT); + return; + } + + if (!type) + type = "application/octet-stream"; + + g_warn_if_fail (parse_data->current_item != NULL); + item = parse_data->current_item; + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + item->metadata->icon_href = g_strdup (href); + item->metadata->icon_mime = g_strdup (type); +} + +/* scans through the attributes of an element for the "xmlns" pragma, and + * adds any resulting namespace declaration to a per-parser hashtable, using + * the namespace name as a key for the namespace URI; if no key was found, + * the namespace is considered as default, and stored under the "default" key. + * + * FIXME: this works on the assumption that the generator of the XBEL file + * is either this code or is smart enough to place the namespace declarations + * inside the main root node or inside the metadata node and does not redefine + * a namespace inside an inner node; this does *not* conform to the + * XML-NS standard, although is a close approximation. In order to make this + * conformant to the XML-NS specification we should use a per-element + * namespace table inside GMarkup and ask it to resolve the namespaces for us. + */ +static void +map_namespace_to_name (ParseData *parse_data, + const gchar **attribute_names, + const gchar **attribute_values) +{ + const gchar *attr; + gint i; + + g_warn_if_fail (parse_data != NULL); + + if (!attribute_names || !attribute_names[0]) + return; + + i = 0; + for (attr = attribute_names[i]; attr; attr = attribute_names[++i]) + { + if (g_str_has_prefix (attr, "xmlns")) + { + gchar *namespace_name, *namespace_uri; + gchar *p; + + p = g_utf8_strchr (attr, -1, ':'); + if (p) + p = g_utf8_next_char (p); + else + p = "default"; + + namespace_name = g_strdup (p); + namespace_uri = g_strdup (attribute_values[i]); + + g_hash_table_replace (parse_data->namespaces, + namespace_name, + namespace_uri); + } + } +} + +/* checks whether @element_full is equal to @element. + * + * if @namespace is set, it tries to resolve the namespace to a known URI, + * and if found is prepended to the element name, from which is separated + * using the character specified in the @sep parameter. + */ +static gboolean +is_element_full (ParseData *parse_data, + const gchar *element_full, + const gchar *namespace, + const gchar *element, + const gchar sep) +{ + gchar *ns_uri, *ns_name; + const gchar *p, *element_name; + gboolean retval; + + g_warn_if_fail (parse_data != NULL); + g_warn_if_fail (element_full != NULL); + + if (!element) + return FALSE; + + /* no namespace requested: dumb element compare */ + if (!namespace) + return (0 == strcmp (element_full, element)); + + /* search for namespace separator; if none found, assume we are under the + * default namespace, and set ns_name to our "default" marker; if no default + * namespace has been set, just do a plain comparison between @full_element + * and @element. + */ + p = g_utf8_strchr (element_full, -1, ':'); + if (p) + { + ns_name = g_strndup (element_full, p - element_full); + element_name = g_utf8_next_char (p); + } + else + { + ns_name = g_strdup ("default"); + element_name = element_full; + } + + ns_uri = g_hash_table_lookup (parse_data->namespaces, ns_name); + if (!ns_uri) + { + /* no default namespace found */ + g_free (ns_name); + + return (0 == strcmp (element_full, element)); + } + + retval = (0 == strcmp (ns_uri, namespace) && + 0 == strcmp (element_name, element)); + + g_free (ns_name); + + return retval; +} + +#define IS_ELEMENT(p,s,e) (is_element_full ((p), (s), NULL, (e), '\0')) +#define IS_ELEMENT_NS(p,s,n,e) (is_element_full ((p), (s), (n), (e), '|')) + +static void +start_element_raw_cb (GMarkupParseContext *context, + const gchar *element_name, + const gchar **attribute_names, + const gchar **attribute_values, + gpointer user_data, + GError **error) +{ + ParseData *parse_data = (ParseData *) user_data; + + /* we must check for namespace declarations first + * + * XXX - we could speed up things by checking for namespace declarations + * only on the root node, where they usually are; this would probably break + * on streams not produced by us or by "smart" generators + */ + map_namespace_to_name (parse_data, attribute_names, attribute_values); + + switch (parse_data->state) + { + case STATE_STARTED: + if (IS_ELEMENT (parse_data, element_name, XBEL_ROOT_ELEMENT)) + { + const gchar *attr; + gint i; + + i = 0; + for (attr = attribute_names[i]; attr; attr = attribute_names[++i]) + { + if ((IS_ATTRIBUTE (attr, XBEL_VERSION_ATTRIBUTE)) && + (0 == strcmp (attribute_values[i], XBEL_VERSION))) + parse_data->state = STATE_ROOT; + } + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag '%s', tag '%s' expected"), + element_name, XBEL_ROOT_ELEMENT); + break; + case STATE_ROOT: + if (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT)) + parse_data->state = STATE_TITLE; + else if (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT)) + parse_data->state = STATE_DESC; + else if (IS_ELEMENT (parse_data, element_name, XBEL_BOOKMARK_ELEMENT)) + { + GError *inner_error = NULL; + + parse_data->state = STATE_BOOKMARK; + + parse_bookmark_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag '%s' inside '%s'"), + element_name, + XBEL_ROOT_ELEMENT); + break; + case STATE_BOOKMARK: + if (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT)) + parse_data->state = STATE_TITLE; + else if (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT)) + parse_data->state = STATE_DESC; + else if (IS_ELEMENT (parse_data, element_name, XBEL_INFO_ELEMENT)) + parse_data->state = STATE_INFO; + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag '%s' inside '%s'"), + element_name, + XBEL_BOOKMARK_ELEMENT); + break; + case STATE_INFO: + if (IS_ELEMENT (parse_data, element_name, XBEL_METADATA_ELEMENT)) + { + const gchar *attr; + gint i; + + i = 0; + for (attr = attribute_names[i]; attr; attr = attribute_names[++i]) + { + if ((IS_ATTRIBUTE (attr, XBEL_OWNER_ATTRIBUTE)) && + (0 == strcmp (attribute_values[i], BOOKMARK_METADATA_OWNER))) + { + parse_data->state = STATE_METADATA; + + if (!parse_data->current_item->metadata) + parse_data->current_item->metadata = bookmark_metadata_new (); + } + } + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag '%s', tag '%s' expected"), + element_name, + XBEL_METADATA_ELEMENT); + break; + case STATE_METADATA: + if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATIONS_ELEMENT)) + parse_data->state = STATE_APPLICATIONS; + else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUPS_ELEMENT)) + parse_data->state = STATE_GROUPS; + else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_PRIVATE_ELEMENT)) + parse_data->current_item->metadata->is_private = TRUE; + else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT)) + { + GError *inner_error = NULL; + + parse_data->state = STATE_ICON; + + parse_icon_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else if (IS_ELEMENT_NS (parse_data, element_name, MIME_NAMESPACE_URI, MIME_TYPE_ELEMENT)) + { + GError *inner_error = NULL; + + parse_data->state = STATE_MIME; + + parse_mime_type_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Unexpected tag '%s' inside '%s'"), + element_name, + XBEL_METADATA_ELEMENT); + break; + case STATE_APPLICATIONS: + if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATION_ELEMENT)) + { + GError *inner_error = NULL; + + parse_data->state = STATE_APPLICATION; + + parse_application_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag '%s', tag '%s' expected"), + element_name, + BOOKMARK_APPLICATION_ELEMENT); + break; + case STATE_GROUPS: + if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUP_ELEMENT)) + parse_data->state = STATE_GROUP; + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_INVALID_CONTENT, + _("Unexpected tag '%s', tag '%s' expected"), + element_name, + BOOKMARK_GROUP_ELEMENT); + break; + case STATE_ICON: + if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT)) + { + GError *inner_error = NULL; + + parse_icon_element (context, + parse_data, + attribute_names, + attribute_values, + &inner_error); + if (inner_error) + g_propagate_error (error, inner_error); + } + else + g_set_error (error, G_MARKUP_ERROR, + G_MARKUP_ERROR_UNKNOWN_ELEMENT, + _("Unexpected tag '%s' inside '%s'"), + element_name, + XBEL_METADATA_ELEMENT); + break; + default: + g_warn_if_reached (); + break; + } +} + +static void +end_element_raw_cb (GMarkupParseContext *context, + const gchar *element_name, + gpointer user_data, + GError **error) +{ + ParseData *parse_data = (ParseData *) user_data; + + if (IS_ELEMENT (parse_data, element_name, XBEL_ROOT_ELEMENT)) + parse_data->state = STATE_FINISHED; + else if (IS_ELEMENT (parse_data, element_name, XBEL_BOOKMARK_ELEMENT)) + { + parse_data->current_item = NULL; + + parse_data->state = STATE_ROOT; + } + else if ((IS_ELEMENT (parse_data, element_name, XBEL_INFO_ELEMENT)) || + (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT)) || + (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT))) + { + if (parse_data->current_item) + parse_data->state = STATE_BOOKMARK; + else + parse_data->state = STATE_ROOT; + } + else if (IS_ELEMENT (parse_data, element_name, XBEL_METADATA_ELEMENT)) + parse_data->state = STATE_INFO; + else if (IS_ELEMENT_NS (parse_data, element_name, + BOOKMARK_NAMESPACE_URI, + BOOKMARK_APPLICATION_ELEMENT)) + parse_data->state = STATE_APPLICATIONS; + else if (IS_ELEMENT_NS (parse_data, element_name, + BOOKMARK_NAMESPACE_URI, + BOOKMARK_GROUP_ELEMENT)) + parse_data->state = STATE_GROUPS; + else if ((IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATIONS_ELEMENT)) || + (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUPS_ELEMENT)) || + (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_PRIVATE_ELEMENT)) || + (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT)) || + (IS_ELEMENT_NS (parse_data, element_name, MIME_NAMESPACE_URI, MIME_TYPE_ELEMENT))) + parse_data->state = STATE_METADATA; +} + +static void +text_raw_cb (GMarkupParseContext *context, + const gchar *text, + gsize length, + gpointer user_data, + GError **error) +{ + ParseData *parse_data = (ParseData *) user_data; + gchar *payload; + + payload = g_strndup (text, length); + + switch (parse_data->state) + { + case STATE_TITLE: + if (parse_data->current_item) + { + g_free (parse_data->current_item->title); + parse_data->current_item->title = g_strdup (payload); + } + else + { + g_free (parse_data->bookmark_file->title); + parse_data->bookmark_file->title = g_strdup (payload); + } + break; + case STATE_DESC: + if (parse_data->current_item) + { + g_free (parse_data->current_item->description); + parse_data->current_item->description = g_strdup (payload); + } + else + { + g_free (parse_data->bookmark_file->description); + parse_data->bookmark_file->description = g_strdup (payload); + } + break; + case STATE_GROUP: + { + GList *groups; + + g_warn_if_fail (parse_data->current_item != NULL); + + if (!parse_data->current_item->metadata) + parse_data->current_item->metadata = bookmark_metadata_new (); + + groups = parse_data->current_item->metadata->groups; + parse_data->current_item->metadata->groups = g_list_prepend (groups, g_strdup (payload)); + } + break; + case STATE_ROOT: + case STATE_BOOKMARK: + case STATE_INFO: + case STATE_METADATA: + case STATE_APPLICATIONS: + case STATE_APPLICATION: + case STATE_GROUPS: + case STATE_MIME: + case STATE_ICON: + break; + default: + g_warn_if_reached (); + break; + } + + g_free (payload); +} + +static const GMarkupParser markup_parser = +{ + start_element_raw_cb, /* start_element */ + end_element_raw_cb, /* end_element */ + text_raw_cb, /* text */ + NULL, /* passthrough */ + NULL +}; + +static gboolean +g_bookmark_file_parse (GBookmarkFile *bookmark, + const gchar *buffer, + gsize length, + GError **error) +{ + GMarkupParseContext *context; + ParseData *parse_data; + GError *parse_error, *end_error; + gboolean retval; + + g_warn_if_fail (bookmark != NULL); + + if (!buffer) + return FALSE; + + parse_error = NULL; + end_error = NULL; + + if (length == (gsize) -1) + length = strlen (buffer); + + parse_data = parse_data_new (); + parse_data->bookmark_file = bookmark; + + context = g_markup_parse_context_new (&markup_parser, + 0, + parse_data, + (GDestroyNotify) parse_data_free); + + retval = g_markup_parse_context_parse (context, + buffer, + length, + &parse_error); + if (!retval) + g_propagate_error (error, parse_error); + else + { + retval = g_markup_parse_context_end_parse (context, &end_error); + if (!retval) + g_propagate_error (error, end_error); + } + + g_markup_parse_context_free (context); + + return retval; +} + +static gchar * +g_bookmark_file_dump (GBookmarkFile *bookmark, + gsize *length, + GError **error) +{ + GString *retval; + gchar *buffer; + GList *l; + + retval = g_string_sized_new (4096); + + g_string_append (retval, + "\n" +#if 0 + /* XXX - do we really need the doctype? */ + "\n" +#endif + "<" XBEL_ROOT_ELEMENT " " XBEL_VERSION_ATTRIBUTE "=\"" XBEL_VERSION "\"\n" + " xmlns:" BOOKMARK_NAMESPACE_NAME "=\"" BOOKMARK_NAMESPACE_URI "\"\n" + " xmlns:" MIME_NAMESPACE_NAME "=\"" MIME_NAMESPACE_URI "\"\n>"); + + if (bookmark->title) + { + gchar *escaped_title; + + escaped_title = g_markup_escape_text (bookmark->title, -1); + + buffer = g_strconcat (" " + "<" XBEL_TITLE_ELEMENT ">", + escaped_title, + "\n", NULL); + + g_string_append (retval, buffer); + + g_free (buffer); + g_free (escaped_title); + } + + if (bookmark->description) + { + gchar *escaped_desc; + + escaped_desc = g_markup_escape_text (bookmark->description, -1); + + buffer = g_strconcat (" " + "<" XBEL_DESC_ELEMENT ">", + escaped_desc, + "\n", NULL); + g_string_append (retval, buffer); + + g_free (buffer); + g_free (escaped_desc); + } + + if (!bookmark->items) + goto out; + else + retval = g_string_append (retval, "\n"); + + /* the items are stored in reverse order */ + for (l = g_list_last (bookmark->items); + l != NULL; + l = l->prev) + { + BookmarkItem *item = (BookmarkItem *) l->data; + gchar *item_dump; + + item_dump = bookmark_item_dump (item); + if (!item_dump) + continue; + + retval = g_string_append (retval, item_dump); + + g_free (item_dump); + } + +out: + g_string_append (retval, ""); + + if (length) + *length = retval->len; + + return g_string_free (retval, FALSE); +} + +/************** + * Misc * + **************/ + +/* converts a Unix timestamp in a ISO 8601 compliant string; you + * should free the returned string. + */ +static gchar * +timestamp_to_iso8601 (time_t timestamp) +{ + GTimeVal stamp; + + if (timestamp == (time_t) -1) + g_get_current_time (&stamp); + else + { + stamp.tv_sec = timestamp; + stamp.tv_usec = 0; + } + + return g_time_val_to_iso8601 (&stamp); +} + +static time_t +timestamp_from_iso8601 (const gchar *iso_date) +{ + GTimeVal stamp; + + if (!g_time_val_from_iso8601 (iso_date, &stamp)) + return (time_t) -1; + + return (time_t) stamp.tv_sec; +} + + + +GQuark +g_bookmark_file_error_quark (void) +{ + return g_quark_from_static_string ("g-bookmark-file-error-quark"); +} + + + +/******************** + * Public API * + ********************/ + +/** + * g_bookmark_file_new: + * + * Creates a new empty #GBookmarkFile object. + * + * Use g_bookmark_file_load_from_file(), g_bookmark_file_load_from_data() + * or g_bookmark_file_load_from_data_dirs() to read an existing bookmark + * file. + * + * Return value: an empty #GBookmarkFile + * + * Since: 2.12 + */ +GBookmarkFile * +g_bookmark_file_new (void) +{ + GBookmarkFile *bookmark; + + bookmark = g_new (GBookmarkFile, 1); + + g_bookmark_file_init (bookmark); + + return bookmark; +} + +/** + * g_bookmark_file_free: + * @bookmark: a #GBookmarkFile + * + * Frees a #GBookmarkFile. + * + * Since: 2.12 + */ +void +g_bookmark_file_free (GBookmarkFile *bookmark) +{ + if (!bookmark) + return; + + g_bookmark_file_clear (bookmark); + + g_free (bookmark); +} + +/** + * g_bookmark_file_load_from_data: + * @bookmark: an empty #GBookmarkFile struct + * @data: desktop bookmarks loaded in memory + * @length: the length of @data in bytes + * @error: return location for a #GError, or %NULL + * + * Loads a bookmark file from memory into an empty #GBookmarkFile + * structure. If the object cannot be created then @error is set to a + * #GBookmarkFileError. + * + * Return value: %TRUE if a desktop bookmark could be loaded. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_load_from_data (GBookmarkFile *bookmark, + const gchar *data, + gsize length, + GError **error) +{ + GError *parse_error; + gboolean retval; + + g_return_val_if_fail (bookmark != NULL, FALSE); + + if (length == (gsize) -1) + length = strlen (data); + + if (bookmark->items) + { + g_bookmark_file_clear (bookmark); + g_bookmark_file_init (bookmark); + } + + parse_error = NULL; + retval = g_bookmark_file_parse (bookmark, data, length, &parse_error); + + if (!retval) + g_propagate_error (error, parse_error); + + return retval; +} + +/** + * g_bookmark_file_load_from_file: + * @bookmark: an empty #GBookmarkFile struct + * @filename: the path of a filename to load, in the GLib file name encoding + * @error: return location for a #GError, or %NULL + * + * Loads a desktop bookmark file into an empty #GBookmarkFile structure. + * If the file could not be loaded then @error is set to either a #GFileError + * or #GBookmarkFileError. + * + * Return value: %TRUE if a desktop bookmark file could be loaded + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_load_from_file (GBookmarkFile *bookmark, + const gchar *filename, + GError **error) +{ + gchar *buffer; + gsize len; + GError *read_error; + gboolean retval; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + + read_error = NULL; + g_file_get_contents (filename, &buffer, &len, &read_error); + if (read_error) + { + g_propagate_error (error, read_error); + + return FALSE; + } + + read_error = NULL; + retval = g_bookmark_file_load_from_data (bookmark, + buffer, + len, + &read_error); + if (read_error) + { + g_propagate_error (error, read_error); + + g_free (buffer); + + return FALSE; + } + + g_free (buffer); + + return retval; +} + + +/* Iterates through all the directories in *dirs trying to + * find file. When it successfully locates file, returns a + * string its absolute path. It also leaves the unchecked + * directories in *dirs. You should free the returned string + * + * Adapted from gkeyfile.c + */ +static gchar * +find_file_in_data_dirs (const gchar *file, + gchar ***dirs, + GError **error) +{ + gchar **data_dirs, *data_dir, *path; + + path = NULL; + + if (dirs == NULL) + return NULL; + + data_dirs = *dirs; + path = NULL; + while (data_dirs && (data_dir = *data_dirs) && !path) + { + gchar *candidate_file, *sub_dir; + + candidate_file = (gchar *) file; + sub_dir = g_strdup (""); + while (candidate_file != NULL && !path) + { + gchar *p; + + path = g_build_filename (data_dir, sub_dir, + candidate_file, NULL); + + candidate_file = strchr (candidate_file, '-'); + + if (candidate_file == NULL) + break; + + candidate_file++; + + g_free (sub_dir); + sub_dir = g_strndup (file, candidate_file - file - 1); + + for (p = sub_dir; *p != '\0'; p++) + { + if (*p == '-') + *p = G_DIR_SEPARATOR; + } + } + g_free (sub_dir); + data_dirs++; + } + + *dirs = data_dirs; + + if (!path) + { + g_set_error_literal (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND, + _("No valid bookmark file found in data dirs")); + + return NULL; + } + + return path; +} + + +/** + * g_bookmark_file_load_from_data_dirs: + * @bookmark: a #GBookmarkFile + * @file: a relative path to a filename to open and parse + * @full_path: return location for a string containing the full path + * of the file, or %NULL + * @error: return location for a #GError, or %NULL + * + * This function looks for a desktop bookmark file named @file in the + * paths returned from g_get_user_data_dir() and g_get_system_data_dirs(), + * loads the file into @bookmark and returns the file's full path in + * @full_path. If the file could not be loaded then an %error is + * set to either a #GFileError or #GBookmarkFileError. + * + * Return value: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_load_from_data_dirs (GBookmarkFile *bookmark, + const gchar *file, + gchar **full_path, + GError **error) +{ + GError *file_error = NULL; + gchar **all_data_dirs, **data_dirs; + const gchar *user_data_dir; + const gchar * const * system_data_dirs; + gsize i, j; + gchar *output_path; + gboolean found_file; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (!g_path_is_absolute (file), FALSE); + + user_data_dir = g_get_user_data_dir (); + system_data_dirs = g_get_system_data_dirs (); + all_data_dirs = g_new0 (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2); + + i = 0; + all_data_dirs[i++] = g_strdup (user_data_dir); + + j = 0; + while (system_data_dirs[j] != NULL) + all_data_dirs[i++] = g_strdup (system_data_dirs[j++]); + + found_file = FALSE; + data_dirs = all_data_dirs; + output_path = NULL; + while (*data_dirs != NULL && !found_file) + { + g_free (output_path); + + output_path = find_file_in_data_dirs (file, &data_dirs, &file_error); + + if (file_error) + { + g_propagate_error (error, file_error); + break; + } + + found_file = g_bookmark_file_load_from_file (bookmark, + output_path, + &file_error); + if (file_error) + { + g_propagate_error (error, file_error); + break; + } + } + + if (found_file && full_path) + *full_path = output_path; + else + g_free (output_path); + + g_strfreev (all_data_dirs); + + return found_file; +} + + +/** + * g_bookmark_file_to_data: + * @bookmark: a #GBookmarkFile + * @length: return location for the length of the returned string, or %NULL + * @error: return location for a #GError, or %NULL + * + * This function outputs @bookmark as a string. + * + * Return value: a newly allocated string holding + * the contents of the #GBookmarkFile + * + * Since: 2.12 + */ +gchar * +g_bookmark_file_to_data (GBookmarkFile *bookmark, + gsize *length, + GError **error) +{ + GError *write_error = NULL; + gchar *retval; + + g_return_val_if_fail (bookmark != NULL, NULL); + + retval = g_bookmark_file_dump (bookmark, length, &write_error); + if (write_error) + { + g_propagate_error (error, write_error); + + return NULL; + } + + return retval; +} + +/** + * g_bookmark_file_to_file: + * @bookmark: a #GBookmarkFile + * @filename: path of the output file + * @error: return location for a #GError, or %NULL + * + * This function outputs @bookmark into a file. The write process is + * guaranteed to be atomic by using g_file_set_contents() internally. + * + * Return value: %TRUE if the file was successfully written. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_to_file (GBookmarkFile *bookmark, + const gchar *filename, + GError **error) +{ + gchar *data; + GError *data_error, *write_error; + gsize len; + gboolean retval; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (filename != NULL, FALSE); + + data_error = NULL; + data = g_bookmark_file_to_data (bookmark, &len, &data_error); + if (data_error) + { + g_propagate_error (error, data_error); + + return FALSE; + } + + write_error = NULL; + g_file_set_contents (filename, data, len, &write_error); + if (write_error) + { + g_propagate_error (error, write_error); + + retval = FALSE; + } + else + retval = TRUE; + + g_free (data); + + return retval; +} + +static BookmarkItem * +g_bookmark_file_lookup_item (GBookmarkFile *bookmark, + const gchar *uri) +{ + g_warn_if_fail (bookmark != NULL && uri != NULL); + + return g_hash_table_lookup (bookmark->items_by_uri, uri); +} + +/* this function adds a new item to the list */ +static void +g_bookmark_file_add_item (GBookmarkFile *bookmark, + BookmarkItem *item, + GError **error) +{ + g_warn_if_fail (bookmark != NULL); + g_warn_if_fail (item != NULL); + + /* this should never happen; and if it does, then we are + * screwing up something big time. + */ + if (G_UNLIKELY (g_bookmark_file_has_item (bookmark, item->uri))) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_URI, + _("A bookmark for URI '%s' already exists"), + item->uri); + return; + } + + bookmark->items = g_list_prepend (bookmark->items, item); + + g_hash_table_replace (bookmark->items_by_uri, + item->uri, + item); + + if (item->added == (time_t) -1) + item->added = time (NULL); + + if (item->modified == (time_t) -1) + item->modified = time (NULL); +} + +/** + * g_bookmark_file_remove_item: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Removes the bookmark for @uri from the bookmark file @bookmark. + * + * Return value: %TRUE if the bookmark was removed successfully. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_remove_item (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return FALSE; + } + + bookmark->items = g_list_remove (bookmark->items, item); + g_hash_table_remove (bookmark->items_by_uri, item->uri); + + bookmark_item_free (item); + + return TRUE; +} + +/** + * g_bookmark_file_has_item: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * + * Looks whether the desktop bookmark has an item with its URI set to @uri. + * + * Return value: %TRUE if @uri is inside @bookmark, %FALSE otherwise + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_has_item (GBookmarkFile *bookmark, + const gchar *uri) +{ + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + return (NULL != g_hash_table_lookup (bookmark->items_by_uri, uri)); +} + +/** + * g_bookmark_file_get_uris: + * @bookmark: a #GBookmarkFile + * @length: return location for the number of returned URIs, or %NULL + * + * Returns all URIs of the bookmarks in the bookmark file @bookmark. + * The array of returned URIs will be %NULL-terminated, so @length may + * optionally be %NULL. + * + * Return value: a newly allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * + * Since: 2.12 + */ +gchar ** +g_bookmark_file_get_uris (GBookmarkFile *bookmark, + gsize *length) +{ + GList *l; + gchar **uris; + gsize i, n_items; + + g_return_val_if_fail (bookmark != NULL, NULL); + + n_items = g_list_length (bookmark->items); + uris = g_new0 (gchar *, n_items + 1); + + /* the items are stored in reverse order, so we walk the list backward */ + for (l = g_list_last (bookmark->items), i = 0; l != NULL; l = l->prev) + { + BookmarkItem *item = (BookmarkItem *) l->data; + + g_warn_if_fail (item != NULL); + + uris[i++] = g_strdup (item->uri); + } + uris[i] = NULL; + + if (length) + *length = i; + + return uris; +} + +/** + * g_bookmark_file_set_title: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI or %NULL + * @title: a UTF-8 encoded string + * + * Sets @title as the title of the bookmark for @uri inside the + * bookmark file @bookmark. + * + * If @uri is %NULL, the title of @bookmark is set. + * + * If a bookmark for @uri cannot be found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_title (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *title) +{ + g_return_if_fail (bookmark != NULL); + + if (!uri) + { + g_free (bookmark->title); + bookmark->title = g_strdup (title); + } + else + { + BookmarkItem *item; + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + g_free (item->title); + item->title = g_strdup (title); + + item->modified = time (NULL); + } +} + +/** + * g_bookmark_file_get_title: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns the title of the bookmark for @uri. + * + * If @uri is %NULL, the title of @bookmark is returned. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: a newly allocated string or %NULL if the specified + * URI cannot be found. + * + * Since: 2.12 + */ +gchar * +g_bookmark_file_get_title (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + + if (!uri) + return g_strdup (bookmark->title); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return NULL; + } + + return g_strdup (item->title); +} + +/** + * g_bookmark_file_set_description: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI or %NULL + * @description: a string + * + * Sets @description as the description of the bookmark for @uri. + * + * If @uri is %NULL, the description of @bookmark is set. + * + * If a bookmark for @uri cannot be found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_description (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *description) +{ + g_return_if_fail (bookmark != NULL); + + if (!uri) + { + g_free (bookmark->description); + bookmark->description = g_strdup (description); + } + else + { + BookmarkItem *item; + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + g_free (item->description); + item->description = g_strdup (description); + + item->modified = time (NULL); + } +} + +/** + * g_bookmark_file_get_description: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Retrieves the description of the bookmark for @uri. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: a newly allocated string or %NULL if the specified + * URI cannot be found. + * + * Since: 2.12 + */ +gchar * +g_bookmark_file_get_description (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + + if (!uri) + return g_strdup (bookmark->description); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return NULL; + } + + return g_strdup (item->description); +} + +/** + * g_bookmark_file_set_mime_type: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @mime_type: a MIME type + * + * Sets @mime_type as the MIME type of the bookmark for @uri. + * + * If a bookmark for @uri cannot be found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_mime_type (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *mime_type) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (mime_type != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + g_free (item->metadata->mime_type); + + item->metadata->mime_type = g_strdup (mime_type); + item->modified = time (NULL); +} + +/** + * g_bookmark_file_get_mime_type: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Retrieves the MIME type of the resource pointed by @uri. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the + * event that the MIME type cannot be found, %NULL is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE. + * + * Return value: a newly allocated string or %NULL if the specified + * URI cannot be found. + * + * Since: 2.12 + */ +gchar * +g_bookmark_file_get_mime_type (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return NULL; + } + + if (!item->metadata) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_VALUE, + _("No MIME type defined in the bookmark for URI '%s'"), + uri); + return NULL; + } + + return g_strdup (item->metadata->mime_type); +} + +/** + * g_bookmark_file_set_is_private: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @is_private: %TRUE if the bookmark should be marked as private + * + * Sets the private flag of the bookmark for @uri. + * + * If a bookmark for @uri cannot be found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_is_private (GBookmarkFile *bookmark, + const gchar *uri, + gboolean is_private) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + item->metadata->is_private = (is_private == TRUE); + item->modified = time (NULL); +} + +/** + * g_bookmark_file_get_is_private: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets whether the private flag of the bookmark for @uri is set. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the + * event that the private flag cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE. + * + * Return value: %TRUE if the private flag is set, %FALSE otherwise. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_get_is_private (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return FALSE; + } + + if (!item->metadata) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_VALUE, + _("No private flag has been defined in bookmark for URI '%s'"), + uri); + return FALSE; + } + + return item->metadata->is_private; +} + +/** + * g_bookmark_file_set_added: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @added: a timestamp or -1 to use the current time + * + * Sets the time the bookmark for @uri was added into @bookmark. + * + * If no bookmark for @uri is found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_added (GBookmarkFile *bookmark, + const gchar *uri, + time_t added) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (added == (time_t) -1) + time (&added); + + item->added = added; + item->modified = added; +} + +/** + * g_bookmark_file_get_added: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time the bookmark for @uri was added to @bookmark + * + * In the event the URI cannot be found, -1 is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: a timestamp + * + * Since: 2.12 + */ +time_t +g_bookmark_file_get_added (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, (time_t) -1); + g_return_val_if_fail (uri != NULL, (time_t) -1); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return (time_t) -1; + } + + return item->added; +} + +/** + * g_bookmark_file_set_modified: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @modified: a timestamp or -1 to use the current time + * + * Sets the last time the bookmark for @uri was last modified. + * + * If no bookmark for @uri is found then it is created. + * + * The "modified" time should only be set when the bookmark's meta-data + * was actually changed. Every function of #GBookmarkFile that + * modifies a bookmark also changes the modification time, except for + * g_bookmark_file_set_visited(). + * + * Since: 2.12 + */ +void +g_bookmark_file_set_modified (GBookmarkFile *bookmark, + const gchar *uri, + time_t modified) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (modified == (time_t) -1) + time (&modified); + + item->modified = modified; +} + +/** + * g_bookmark_file_get_modified: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time when the bookmark for @uri was last modified. + * + * In the event the URI cannot be found, -1 is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: a timestamp + * + * Since: 2.12 + */ +time_t +g_bookmark_file_get_modified (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, (time_t) -1); + g_return_val_if_fail (uri != NULL, (time_t) -1); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return (time_t) -1; + } + + return item->modified; +} + +/** + * g_bookmark_file_set_visited: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @visited: a timestamp or -1 to use the current time + * + * Sets the time the bookmark for @uri was last visited. + * + * If no bookmark for @uri is found then it is created. + * + * The "visited" time should only be set if the bookmark was launched, + * either using the command line retrieved by g_bookmark_file_get_app_info() + * or by the default application for the bookmark's MIME type, retrieved + * using g_bookmark_file_get_mime_type(). Changing the "visited" time + * does not affect the "modified" time. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_visited (GBookmarkFile *bookmark, + const gchar *uri, + time_t visited) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (visited == (time_t) -1) + time (&visited); + + item->visited = visited; +} + +/** + * g_bookmark_file_get_visited: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @error: return location for a #GError, or %NULL + * + * Gets the time the bookmark for @uri was last visited. + * + * In the event the URI cannot be found, -1 is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: a timestamp. + * + * Since: 2.12 + */ +time_t +g_bookmark_file_get_visited (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, (time_t) -1); + g_return_val_if_fail (uri != NULL, (time_t) -1); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return (time_t) -1; + } + + return item->visited; +} + +/** + * g_bookmark_file_has_group: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @group: the group name to be searched + * @error: return location for a #GError, or %NULL + * + * Checks whether @group appears in the list of groups to which + * the bookmark for @uri belongs to. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: %TRUE if @group was found. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_has_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group, + GError **error) +{ + BookmarkItem *item; + GList *l; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return FALSE; + } + + if (!item->metadata) + return FALSE; + + for (l = item->metadata->groups; l != NULL; l = l->next) + { + if (strcmp (l->data, group) == 0) + return TRUE; + } + + return FALSE; + +} + +/** + * g_bookmark_file_add_group: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @group: the group name to be added + * + * Adds @group to the list of groups to which the bookmark for @uri + * belongs to. + * + * If no bookmark for @uri is found then it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_add_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (group != NULL && group[0] != '\0'); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + if (!g_bookmark_file_has_group (bookmark, uri, group, NULL)) + { + item->metadata->groups = g_list_prepend (item->metadata->groups, + g_strdup (group)); + + item->modified = time (NULL); + } +} + +/** + * g_bookmark_file_remove_group: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @group: the group name to be removed + * @error: return location for a #GError, or %NULL + * + * Removes @group from the list of groups to which the bookmark + * for @uri belongs to. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * In the event no group was defined, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE. + * + * Return value: %TRUE if @group was successfully removed. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_remove_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group, + GError **error) +{ + BookmarkItem *item; + GList *l; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return FALSE; + } + + if (!item->metadata) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_VALUE, + _("No groups set in bookmark for URI '%s'"), + uri); + return FALSE; + } + + for (l = item->metadata->groups; l != NULL; l = l->next) + { + if (strcmp (l->data, group) == 0) + { + item->metadata->groups = g_list_remove_link (item->metadata->groups, l); + g_free (l->data); + g_list_free_1 (l); + + item->modified = time (NULL); + + return TRUE; + } + } + + return FALSE; +} + +/** + * g_bookmark_file_set_groups: + * @bookmark: a #GBookmarkFile + * @uri: an item's URI + * @groups: an array of group names, or %NULL to remove all groups + * @length: number of group name values in @groups + * + * Sets a list of group names for the item with URI @uri. Each previously + * set group name list is removed. + * + * If @uri cannot be found then an item for it is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_groups (GBookmarkFile *bookmark, + const gchar *uri, + const gchar **groups, + gsize length) +{ + BookmarkItem *item; + gsize i; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + g_return_if_fail (groups != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + g_list_free_full (item->metadata->groups, g_free); + item->metadata->groups = NULL; + + if (groups) + { + for (i = 0; groups[i] != NULL && i < length; i++) + item->metadata->groups = g_list_append (item->metadata->groups, + g_strdup (groups[i])); + } + + item->modified = time (NULL); +} + +/** + * g_bookmark_file_get_groups: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @length: return location for the length of the returned string, or %NULL + * @error: return location for a #GError, or %NULL + * + * Retrieves the list of group names of the bookmark for @uri. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * The returned array is %NULL terminated, so @length may optionally + * be %NULL. + * + * Return value: a newly allocated %NULL-terminated array of group names. + * Use g_strfreev() to free it. + * + * Since: 2.12 + */ +gchar ** +g_bookmark_file_get_groups (GBookmarkFile *bookmark, + const gchar *uri, + gsize *length, + GError **error) +{ + BookmarkItem *item; + GList *l; + gsize len, i; + gchar **retval; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return NULL; + } + + if (!item->metadata) + { + if (length) + *length = 0; + + return NULL; + } + + len = g_list_length (item->metadata->groups); + retval = g_new0 (gchar *, len + 1); + for (l = g_list_last (item->metadata->groups), i = 0; + l != NULL; + l = l->prev) + { + gchar *group_name = (gchar *) l->data; + + g_warn_if_fail (group_name != NULL); + + retval[i++] = g_strdup (group_name); + } + retval[i] = NULL; + + if (length) + *length = len; + + return retval; +} + +/** + * g_bookmark_file_add_application: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: the name of the application registering the bookmark + * or %NULL + * @exec: command line to be used to launch the bookmark or %NULL + * + * Adds the application with @name and @exec to the list of + * applications that have registered a bookmark for @uri into + * @bookmark. + * + * Every bookmark inside a #GBookmarkFile must have at least an + * application registered. Each application must provide a name, a + * command line useful for launching the bookmark, the number of times + * the bookmark has been registered by the application and the last + * time the application registered this bookmark. + * + * If @name is %NULL, the name of the application will be the + * same returned by g_get_application_name(); if @exec is %NULL, the + * command line will be a composition of the program name as + * returned by g_get_prgname() and the "\%u" modifier, which will be + * expanded to the bookmark's URI. + * + * This function will automatically take care of updating the + * registrations count and timestamping in case an application + * with the same @name had already registered a bookmark for + * @uri inside @bookmark. + * + * If no bookmark for @uri is found, one is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_add_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + const gchar *exec) +{ + BookmarkItem *item; + gchar *app_name, *app_exec; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (name && name[0] != '\0') + app_name = g_strdup (name); + else + app_name = g_strdup (g_get_application_name ()); + + if (exec && exec[0] != '\0') + app_exec = g_strdup (exec); + else + app_exec = g_strjoin (" ", g_get_prgname(), "%u", NULL); + + g_bookmark_file_set_app_info (bookmark, uri, + app_name, + app_exec, + -1, + (time_t) -1, + NULL); + + g_free (app_exec); + g_free (app_name); +} + +/** + * g_bookmark_file_remove_application: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: the name of the application + * @error: return location for a #GError or %NULL + * + * Removes application registered with @name from the list of applications + * that have registered a bookmark for @uri inside @bookmark. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * In the event that no application with name @app_name has registered + * a bookmark for @uri, %FALSE is returned and error is set to + * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. + * + * Return value: %TRUE if the application was successfully removed. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_remove_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + GError **error) +{ + GError *set_error; + gboolean retval; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + set_error = NULL; + retval = g_bookmark_file_set_app_info (bookmark, uri, + name, + "", + 0, + (time_t) -1, + &set_error); + if (set_error) + { + g_propagate_error (error, set_error); + + return FALSE; + } + + return retval; +} + +/** + * g_bookmark_file_has_application: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: the name of the application + * @error: return location for a #GError or %NULL + * + * Checks whether the bookmark for @uri inside @bookmark has been + * registered by application @name. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: %TRUE if the application @name was found + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_has_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return FALSE; + } + + return (NULL != bookmark_item_lookup_app_info (item, name)); +} + +/** + * g_bookmark_file_set_app_info: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: an application's name + * @exec: an application's command line + * @count: the number of registrations done for this application + * @stamp: the time of the last registration for this application + * @error: return location for a #GError or %NULL + * + * Sets the meta-data of application @name inside the list of + * applications that have registered a bookmark for @uri inside + * @bookmark. + * + * You should rarely use this function; use g_bookmark_file_add_application() + * and g_bookmark_file_remove_application() instead. + * + * @name can be any UTF-8 encoded string used to identify an + * application. + * @exec can have one of these two modifiers: "\%f", which will + * be expanded as the local file name retrieved from the bookmark's + * URI; "\%u", which will be expanded as the bookmark's URI. + * The expansion is done automatically when retrieving the stored + * command line using the g_bookmark_file_get_app_info() function. + * @count is the number of times the application has registered the + * bookmark; if is < 0, the current registration count will be increased + * by one, if is 0, the application with @name will be removed from + * the list of registered applications. + * @stamp is the Unix time of the last registration; if it is -1, the + * current time will be used. + * + * If you try to remove an application by setting its registration count to + * zero, and no bookmark for @uri is found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND; similarly, + * in the event that no application @name has registered a bookmark + * for @uri, %FALSE is returned and error is set to + * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. Otherwise, if no bookmark + * for @uri is found, one is created. + * + * Return value: %TRUE if the application's meta-data was successfully + * changed. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_set_app_info (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + const gchar *exec, + gint count, + time_t stamp, + GError **error) +{ + BookmarkItem *item; + BookmarkAppInfo *ai; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (exec != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + if (count == 0) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return FALSE; + } + else + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + } + + ai = bookmark_item_lookup_app_info (item, name); + if (!ai) + { + if (count == 0) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED, + _("No application with name '%s' registered a bookmark for '%s'"), + name, + uri); + return FALSE; + } + else + { + ai = bookmark_app_info_new (name); + + item->metadata->applications = g_list_prepend (item->metadata->applications, ai); + g_hash_table_replace (item->metadata->apps_by_name, ai->name, ai); + } + } + + if (count == 0) + { + item->metadata->applications = g_list_remove (item->metadata->applications, ai); + g_hash_table_remove (item->metadata->apps_by_name, ai->name); + bookmark_app_info_free (ai); + + item->modified = time (NULL); + + return TRUE; + } + else if (count > 0) + ai->count = count; + else + ai->count += 1; + + if (stamp != (time_t) -1) + ai->stamp = stamp; + else + ai->stamp = time (NULL); + + if (exec && exec[0] != '\0') + { + g_free (ai->exec); + ai->exec = g_shell_quote (exec); + } + + item->modified = time (NULL); + + return TRUE; +} + +/* expands the application's command line */ +static gchar * +expand_exec_line (const gchar *exec_fmt, + const gchar *uri) +{ + GString *exec; + gchar ch; + + exec = g_string_sized_new (512); + while ((ch = *exec_fmt++) != '\0') + { + if (ch != '%') + { + exec = g_string_append_c (exec, ch); + continue; + } + + ch = *exec_fmt++; + switch (ch) + { + case '\0': + goto out; + case 'U': + case 'u': + g_string_append (exec, uri); + break; + case 'F': + case 'f': + { + gchar *file = g_filename_from_uri (uri, NULL, NULL); + if (file) + { + g_string_append (exec, file); + g_free (file); + } + else + { + g_string_free (exec, TRUE); + return NULL; + } + } + break; + case '%': + default: + exec = g_string_append_c (exec, ch); + break; + } + } + + out: + return g_string_free (exec, FALSE); +} + +/** + * g_bookmark_file_get_app_info: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @name: an application's name + * @exec: location for the command line of the application, or %NULL + * @count: return location for the registration count, or %NULL + * @stamp: return location for the last registration time, or %NULL + * @error: return location for a #GError, or %NULL + * + * Gets the registration informations of @app_name for the bookmark for + * @uri. See g_bookmark_file_set_app_info() for more informations about + * the returned data. + * + * The string returned in @app_exec must be freed. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. In the + * event that no application with name @app_name has registered a bookmark + * for @uri, %FALSE is returned and error is set to + * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. In the event that unquoting + * the command line fails, an error of the #G_SHELL_ERROR domain is + * set and %FALSE is returned. + * + * Return value: %TRUE on success. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_get_app_info (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + gchar **exec, + guint *count, + time_t *stamp, + GError **error) +{ + BookmarkItem *item; + BookmarkAppInfo *ai; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return FALSE; + } + + ai = bookmark_item_lookup_app_info (item, name); + if (!ai) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED, + _("No application with name '%s' registered a bookmark for '%s'"), + name, + uri); + return FALSE; + } + + if (exec) + { + GError *unquote_error = NULL; + gchar *command_line; + + command_line = g_shell_unquote (ai->exec, &unquote_error); + if (unquote_error) + { + g_propagate_error (error, unquote_error); + return FALSE; + } + + *exec = expand_exec_line (command_line, uri); + if (!*exec) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_INVALID_URI, + _("Failed to expand exec line '%s' with URI '%s'"), + ai->exec, uri); + g_free (command_line); + + return FALSE; + } + else + g_free (command_line); + } + + if (count) + *count = ai->count; + + if (stamp) + *stamp = ai->stamp; + + return TRUE; +} + +/** + * g_bookmark_file_get_applications: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @length: return location of the length of the returned list, or %NULL + * @error: return location for a #GError, or %NULL + * + * Retrieves the names of the applications that have registered the + * bookmark for @uri. + * + * In the event the URI cannot be found, %NULL is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: a newly allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * + * Since: 2.12 + */ +gchar ** +g_bookmark_file_get_applications (GBookmarkFile *bookmark, + const gchar *uri, + gsize *length, + GError **error) +{ + BookmarkItem *item; + GList *l; + gchar **apps; + gsize i, n_apps; + + g_return_val_if_fail (bookmark != NULL, NULL); + g_return_val_if_fail (uri != NULL, NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return NULL; + } + + if (!item->metadata) + { + if (length) + *length = 0; + + return NULL; + } + + n_apps = g_list_length (item->metadata->applications); + apps = g_new0 (gchar *, n_apps + 1); + + for (l = g_list_last (item->metadata->applications), i = 0; + l != NULL; + l = l->prev) + { + BookmarkAppInfo *ai; + + ai = (BookmarkAppInfo *) l->data; + + g_warn_if_fail (ai != NULL); + g_warn_if_fail (ai->name != NULL); + + apps[i++] = g_strdup (ai->name); + } + apps[i] = NULL; + + if (length) + *length = i; + + return apps; +} + +/** + * g_bookmark_file_get_size: + * @bookmark: a #GBookmarkFile + * + * Gets the number of bookmarks inside @bookmark. + * + * Return value: the number of bookmarks + * + * Since: 2.12 + */ +gint +g_bookmark_file_get_size (GBookmarkFile *bookmark) +{ + g_return_val_if_fail (bookmark != NULL, 0); + + return g_list_length (bookmark->items); +} + +/** + * g_bookmark_file_move_item: + * @bookmark: a #GBookmarkFile + * @old_uri: a valid URI + * @new_uri: a valid URI, or %NULL + * @error: return location for a #GError or %NULL + * + * Changes the URI of a bookmark item from @old_uri to @new_uri. Any + * existing bookmark for @new_uri will be overwritten. If @new_uri is + * %NULL, then the bookmark is removed. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: %TRUE if the URI was successfully changed + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_move_item (GBookmarkFile *bookmark, + const gchar *old_uri, + const gchar *new_uri, + GError **error) +{ + BookmarkItem *item; + GError *remove_error; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (old_uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, old_uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + old_uri); + return FALSE; + } + + if (new_uri && new_uri[0] != '\0') + { + if (g_bookmark_file_has_item (bookmark, new_uri)) + { + remove_error = NULL; + g_bookmark_file_remove_item (bookmark, new_uri, &remove_error); + if (remove_error) + { + g_propagate_error (error, remove_error); + + return FALSE; + } + } + + g_hash_table_steal (bookmark->items_by_uri, item->uri); + + g_free (item->uri); + item->uri = g_strdup (new_uri); + item->modified = time (NULL); + + g_hash_table_replace (bookmark->items_by_uri, item->uri, item); + + return TRUE; + } + else + { + remove_error = NULL; + g_bookmark_file_remove_item (bookmark, old_uri, &remove_error); + if (remove_error) + { + g_propagate_error (error, remove_error); + + return FALSE; + } + + return TRUE; + } +} + +/** + * g_bookmark_file_set_icon: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @href: the URI of the icon for the bookmark, or %NULL + * @mime_type: the MIME type of the icon for the bookmark + * + * Sets the icon for the bookmark for @uri. If @href is %NULL, unsets + * the currently set icon. @href can either be a full URL for the icon + * file or the icon name following the Icon Naming specification. + * + * If no bookmark for @uri is found one is created. + * + * Since: 2.12 + */ +void +g_bookmark_file_set_icon (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *href, + const gchar *mime_type) +{ + BookmarkItem *item; + + g_return_if_fail (bookmark != NULL); + g_return_if_fail (uri != NULL); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + item = bookmark_item_new (uri); + g_bookmark_file_add_item (bookmark, item, NULL); + } + + if (!item->metadata) + item->metadata = bookmark_metadata_new (); + + g_free (item->metadata->icon_href); + g_free (item->metadata->icon_mime); + + item->metadata->icon_href = g_strdup (href); + + if (mime_type && mime_type[0] != '\0') + item->metadata->icon_mime = g_strdup (mime_type); + else + item->metadata->icon_mime = g_strdup ("application/octet-stream"); + + item->modified = time (NULL); +} + +/** + * g_bookmark_file_get_icon: + * @bookmark: a #GBookmarkFile + * @uri: a valid URI + * @href: return location for the icon's location or %NULL + * @mime_type: return location for the icon's MIME type or %NULL + * @error: return location for a #GError or %NULL + * + * Gets the icon of the bookmark for @uri. + * + * In the event the URI cannot be found, %FALSE is returned and + * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND. + * + * Return value: %TRUE if the icon for the bookmark for the URI was found. + * You should free the returned strings. + * + * Since: 2.12 + */ +gboolean +g_bookmark_file_get_icon (GBookmarkFile *bookmark, + const gchar *uri, + gchar **href, + gchar **mime_type, + GError **error) +{ + BookmarkItem *item; + + g_return_val_if_fail (bookmark != NULL, FALSE); + g_return_val_if_fail (uri != NULL, FALSE); + + item = g_bookmark_file_lookup_item (bookmark, uri); + if (!item) + { + g_set_error (error, G_BOOKMARK_FILE_ERROR, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + _("No bookmark found for URI '%s'"), + uri); + return FALSE; + } + + if ((!item->metadata) || (!item->metadata->icon_href)) + return FALSE; + + if (href) + *href = g_strdup (item->metadata->icon_href); + + if (mime_type) + *mime_type = g_strdup (item->metadata->icon_mime); + + return TRUE; +} diff --git a/glib/glib/gbookmarkfile.h b/glib/glib/gbookmarkfile.h new file mode 100644 index 0000000..6b2ee6f --- /dev/null +++ b/glib/glib/gbookmarkfile.h @@ -0,0 +1,215 @@ +/* gbookmarkfile.h: parsing and building desktop bookmarks + * + * Copyright (C) 2005-2006 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_BOOKMARK_FILE_H__ +#define __G_BOOKMARK_FILE_H__ + +#include +#include + +G_BEGIN_DECLS + +/** + * G_BOOKMARK_FILE_ERROR: + * + * Error domain for bookmark file parsing. + * Errors in this domain will be from the #GBookmarkFileError + * enumeration. See #GError for information on error domains. + */ +#define G_BOOKMARK_FILE_ERROR (g_bookmark_file_error_quark ()) + + +/** + * GBookmarkFileError: + * @G_BOOKMARK_FILE_ERROR_INVALID_URI: URI was ill-formed + * @G_BOOKMARK_FILE_ERROR_INVALID_VALUE: a requested field was not found + * @G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED: a requested application did + * not register a bookmark + * @G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND: a requested URI was not found + * @G_BOOKMARK_FILE_ERROR_READ: document was ill formed + * @G_BOOKMARK_FILE_ERROR_UNKNOWN_ENCODING: the text being parsed was + * in an unknown encoding + * @G_BOOKMARK_FILE_ERROR_WRITE: an error occurred while writing + * @G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND: requested file was not found + * + * Error codes returned by bookmark file parsing. + */ +typedef enum +{ + G_BOOKMARK_FILE_ERROR_INVALID_URI, + G_BOOKMARK_FILE_ERROR_INVALID_VALUE, + G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED, + G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND, + G_BOOKMARK_FILE_ERROR_READ, + G_BOOKMARK_FILE_ERROR_UNKNOWN_ENCODING, + G_BOOKMARK_FILE_ERROR_WRITE, + G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND +} GBookmarkFileError; + +GQuark g_bookmark_file_error_quark (void); + +/** + * GBookmarkFile: + * + * The GBookmarkFile struct contains only + * private data and should not be directly accessed. + */ +typedef struct _GBookmarkFile GBookmarkFile; + +GBookmarkFile *g_bookmark_file_new (void); +void g_bookmark_file_free (GBookmarkFile *bookmark); + +gboolean g_bookmark_file_load_from_file (GBookmarkFile *bookmark, + const gchar *filename, + GError **error); +gboolean g_bookmark_file_load_from_data (GBookmarkFile *bookmark, + const gchar *data, + gsize length, + GError **error); +gboolean g_bookmark_file_load_from_data_dirs (GBookmarkFile *bookmark, + const gchar *file, + gchar **full_path, + GError **error); +gchar * g_bookmark_file_to_data (GBookmarkFile *bookmark, + gsize *length, + GError **error) G_GNUC_MALLOC; +gboolean g_bookmark_file_to_file (GBookmarkFile *bookmark, + const gchar *filename, + GError **error); + +void g_bookmark_file_set_title (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *title); +gchar * g_bookmark_file_get_title (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) G_GNUC_MALLOC; +void g_bookmark_file_set_description (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *description); +gchar * g_bookmark_file_get_description (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) G_GNUC_MALLOC; +void g_bookmark_file_set_mime_type (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *mime_type); +gchar * g_bookmark_file_get_mime_type (GBookmarkFile *bookmark, + const gchar *uri, + GError **error) G_GNUC_MALLOC; +void g_bookmark_file_set_groups (GBookmarkFile *bookmark, + const gchar *uri, + const gchar **groups, + gsize length); +void g_bookmark_file_add_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group); +gboolean g_bookmark_file_has_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group, + GError **error); +gchar ** g_bookmark_file_get_groups (GBookmarkFile *bookmark, + const gchar *uri, + gsize *length, + GError **error) G_GNUC_MALLOC; +void g_bookmark_file_add_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + const gchar *exec); +gboolean g_bookmark_file_has_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + GError **error); +gchar ** g_bookmark_file_get_applications (GBookmarkFile *bookmark, + const gchar *uri, + gsize *length, + GError **error) G_GNUC_MALLOC; +gboolean g_bookmark_file_set_app_info (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + const gchar *exec, + gint count, + time_t stamp, + GError **error); +gboolean g_bookmark_file_get_app_info (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + gchar **exec, + guint *count, + time_t *stamp, + GError **error); +void g_bookmark_file_set_is_private (GBookmarkFile *bookmark, + const gchar *uri, + gboolean is_private); +gboolean g_bookmark_file_get_is_private (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +void g_bookmark_file_set_icon (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *href, + const gchar *mime_type); +gboolean g_bookmark_file_get_icon (GBookmarkFile *bookmark, + const gchar *uri, + gchar **href, + gchar **mime_type, + GError **error); +void g_bookmark_file_set_added (GBookmarkFile *bookmark, + const gchar *uri, + time_t added); +time_t g_bookmark_file_get_added (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +void g_bookmark_file_set_modified (GBookmarkFile *bookmark, + const gchar *uri, + time_t modified); +time_t g_bookmark_file_get_modified (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +void g_bookmark_file_set_visited (GBookmarkFile *bookmark, + const gchar *uri, + time_t visited); +time_t g_bookmark_file_get_visited (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +gboolean g_bookmark_file_has_item (GBookmarkFile *bookmark, + const gchar *uri); +gint g_bookmark_file_get_size (GBookmarkFile *bookmark); +gchar ** g_bookmark_file_get_uris (GBookmarkFile *bookmark, + gsize *length) G_GNUC_MALLOC; +gboolean g_bookmark_file_remove_group (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *group, + GError **error); +gboolean g_bookmark_file_remove_application (GBookmarkFile *bookmark, + const gchar *uri, + const gchar *name, + GError **error); +gboolean g_bookmark_file_remove_item (GBookmarkFile *bookmark, + const gchar *uri, + GError **error); +gboolean g_bookmark_file_move_item (GBookmarkFile *bookmark, + const gchar *old_uri, + const gchar *new_uri, + GError **error); + +G_END_DECLS + +#endif /* __G_BOOKMARK_FILE_H__ */ diff --git a/glib/glib/gbsearcharray.h b/glib/glib/gbsearcharray.h new file mode 100644 index 0000000..98822cb --- /dev/null +++ b/glib/glib/gbsearcharray.h @@ -0,0 +1,303 @@ +/* GBSearchArray - Binary Searchable Array implementation + * Copyright (C) 2000-2003 Tim Janik + * + * This software is provided "as is"; redistribution and modification + * is permitted, provided that the following disclaimer is retained. + * + * This software 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. + * In no event shall the authors or contributors be liable for any + * direct, indirect, incidental, special, exemplary, or consequential + * damages (including, but not limited to, procurement of substitute + * goods or services; loss of use, data, or profits; or business + * interruption) however caused and on any theory of liability, whether + * in contract, strict liability, or tort (including negligence or + * otherwise) arising in any way out of the use of this software, even + * if advised of the possibility of such damage. + */ +#ifndef __G_BSEARCH_ARRAY_H__ +#define __G_BSEARCH_ARRAY_H__ + +#include +#include + + +G_BEGIN_DECLS /* c++ guards */ + +/* this implementation is intended to be usable in third-party code + * simply by pasting the contents of this file. as such, the + * implementation needs to be self-contained within this file. + */ + +/* convenience macro to avoid signed overflow for value comparisons */ +#define G_BSEARCH_ARRAY_CMP(v1,v2) ((v1) > (v2) ? +1 : (v1) == (v2) ? 0 : -1) + + +/* --- typedefs --- */ +typedef gint (*GBSearchCompareFunc) (gconstpointer bsearch_node1, /* key */ + gconstpointer bsearch_node2); +typedef enum +{ + G_BSEARCH_ARRAY_ALIGN_POWER2 = 1 << 0, /* align memory to power2 sizes */ + G_BSEARCH_ARRAY_AUTO_SHRINK = 1 << 1 /* shrink array upon removal */ +} GBSearchArrayFlags; + + +/* --- structures --- */ +typedef struct +{ + guint sizeof_node; + GBSearchCompareFunc cmp_nodes; + guint flags; +} GBSearchConfig; +typedef union +{ + guint n_nodes; + /*< private >*/ + gpointer alignment_dummy1; + glong alignment_dummy2; + gdouble alignment_dummy3; +} GBSearchArray; + + +/* --- public API --- */ +static inline GBSearchArray* g_bsearch_array_create (const GBSearchConfig *bconfig); +static inline gpointer g_bsearch_array_get_nth (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint nth); +static inline guint g_bsearch_array_get_index (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer node_in_array); +static inline GBSearchArray* g_bsearch_array_remove (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint index_); +/* provide uninitialized space at index for node insertion */ +static inline GBSearchArray* g_bsearch_array_grow (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint index); +/* insert key_node into array if it does not exist, otherwise do nothing */ +static inline GBSearchArray* g_bsearch_array_insert (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node); +/* insert key_node into array if it does not exist, + * otherwise replace the existing node's contents with key_node + */ +static inline GBSearchArray* g_bsearch_array_replace (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node); +static inline void g_bsearch_array_free (GBSearchArray *barray, + const GBSearchConfig *bconfig); +#define g_bsearch_array_get_n_nodes(barray) (((GBSearchArray*) (barray))->n_nodes) + +/* g_bsearch_array_lookup(): + * return NULL or exact match node + */ +#define g_bsearch_array_lookup(barray, bconfig, key_node) \ + g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 0) + +/* g_bsearch_array_lookup_sibling(): + * return NULL for barray->n_nodes==0, otherwise return the + * exact match node, or, if there's no such node, return the + * node last visited, which is pretty close to an exact match + * (will be one off into either direction). + */ +#define g_bsearch_array_lookup_sibling(barray, bconfig, key_node) \ + g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 1) + +/* g_bsearch_array_lookup_insertion(): + * return NULL for barray->n_nodes==0 or exact match, otherwise + * return the node where key_node should be inserted (may be one + * after end, i.e. g_bsearch_array_get_index(result) <= barray->n_nodes). + */ +#define g_bsearch_array_lookup_insertion(barray, bconfig, key_node) \ + g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 2) + + +/* --- implementation --- */ +/* helper macro to cut down realloc()s */ +#ifdef DISABLE_MEM_POOLS +#define G_BSEARCH_UPPER_POWER2(n) (n) +#else /* !DISABLE_MEM_POOLS */ +#define G_BSEARCH_UPPER_POWER2(n) ((n) ? 1 << g_bit_storage ((n) - 1) : 0) +#endif /* !DISABLE_MEM_POOLS */ +#define G_BSEARCH_ARRAY_NODES(barray) (((guint8*) (barray)) + sizeof (GBSearchArray)) +static inline GBSearchArray* +g_bsearch_array_create (const GBSearchConfig *bconfig) +{ + GBSearchArray *barray; + guint size; + + g_return_val_if_fail (bconfig != NULL, NULL); + + size = sizeof (GBSearchArray) + bconfig->sizeof_node; + if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2) + size = G_BSEARCH_UPPER_POWER2 (size); + barray = (GBSearchArray *) g_malloc (size); + memset (barray, 0, sizeof (GBSearchArray)); + + return barray; +} +static inline gpointer +g_bsearch_array_lookup_fuzzy (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node, + const guint sibling_or_after); +static inline gpointer +g_bsearch_array_lookup_fuzzy (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node, + const guint sibling_or_after) +{ + GBSearchCompareFunc cmp_nodes = bconfig->cmp_nodes; + guint8 *check = NULL, *nodes = G_BSEARCH_ARRAY_NODES (barray); + guint n_nodes = barray->n_nodes, offs = 0; + guint sizeof_node = bconfig->sizeof_node; + gint cmp = 0; + + while (offs < n_nodes) + { + guint i = (offs + n_nodes) >> 1; + + check = nodes + i * sizeof_node; + cmp = cmp_nodes (key_node, check); + if (cmp == 0) + return sibling_or_after > 1 ? NULL : check; + else if (cmp < 0) + n_nodes = i; + else /* (cmp > 0) */ + offs = i + 1; + } + + /* check is last mismatch, cmp > 0 indicates greater key */ + return G_LIKELY (!sibling_or_after) ? NULL : (sibling_or_after > 1 && cmp > 0) ? check + sizeof_node : check; +} +static inline gpointer +g_bsearch_array_get_nth (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint nth) +{ + return (G_LIKELY (nth < barray->n_nodes) ? + G_BSEARCH_ARRAY_NODES (barray) + nth * bconfig->sizeof_node : + NULL); +} +static inline guint +g_bsearch_array_get_index (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer node_in_array) +{ + guint distance = ((guint8*) node_in_array) - G_BSEARCH_ARRAY_NODES (barray); + + g_return_val_if_fail (node_in_array != NULL, barray->n_nodes); + + distance /= bconfig->sizeof_node; + + return MIN (distance, barray->n_nodes + 1); /* may return one after end */ +} +static inline GBSearchArray* +g_bsearch_array_grow (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint index_) +{ + guint old_size = barray->n_nodes * bconfig->sizeof_node; + guint new_size = old_size + bconfig->sizeof_node; + guint8 *node; + + g_return_val_if_fail (index_ <= barray->n_nodes, NULL); + + if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)) + { + new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size); + old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size); + if (old_size != new_size) + barray = (GBSearchArray *) g_realloc (barray, new_size); + } + else + barray = (GBSearchArray *) g_realloc (barray, sizeof (GBSearchArray) + new_size); + node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node; + g_memmove (node + bconfig->sizeof_node, node, (barray->n_nodes - index_) * bconfig->sizeof_node); + barray->n_nodes += 1; + return barray; +} +static inline GBSearchArray* +g_bsearch_array_insert (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node) +{ + guint8 *node; + + if (G_UNLIKELY (!barray->n_nodes)) + { + barray = g_bsearch_array_grow (barray, bconfig, 0); + node = G_BSEARCH_ARRAY_NODES (barray); + } + else + { + node = (guint8 *) g_bsearch_array_lookup_insertion (barray, bconfig, key_node); + if (G_LIKELY (node)) + { + guint index_ = g_bsearch_array_get_index (barray, bconfig, node); + + /* grow and insert */ + barray = g_bsearch_array_grow (barray, bconfig, index_); + node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node; + } + else /* no insertion needed, node already there */ + return barray; + } + memcpy (node, key_node, bconfig->sizeof_node); + return barray; +} +static inline GBSearchArray* +g_bsearch_array_replace (GBSearchArray *barray, + const GBSearchConfig *bconfig, + gconstpointer key_node) +{ + guint8 *node = (guint8 *) g_bsearch_array_lookup (barray, bconfig, key_node); + if (G_LIKELY (node)) /* expected path */ + memcpy (node, key_node, bconfig->sizeof_node); + else /* revert to insertion */ + barray = g_bsearch_array_insert (barray, bconfig, key_node); + return barray; +} +static inline GBSearchArray* +g_bsearch_array_remove (GBSearchArray *barray, + const GBSearchConfig *bconfig, + guint index_) +{ + guint8 *node; + + g_return_val_if_fail (index_ < barray->n_nodes, NULL); + + barray->n_nodes -= 1; + node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node; + g_memmove (node, node + bconfig->sizeof_node, (barray->n_nodes - index_) * bconfig->sizeof_node); + if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_AUTO_SHRINK)) + { + guint new_size = barray->n_nodes * bconfig->sizeof_node; + guint old_size = new_size + bconfig->sizeof_node; + + if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)) + { + new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size); + old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size); + if (old_size != new_size) + barray = (GBSearchArray *) g_realloc (barray, new_size); + } + else + barray = (GBSearchArray *) g_realloc (barray, sizeof (GBSearchArray) + new_size); + } + return barray; +} +static inline void +g_bsearch_array_free (GBSearchArray *barray, + const GBSearchConfig *bconfig) +{ + g_return_if_fail (barray != NULL); + + g_free (barray); +} + +G_END_DECLS /* c++ guards */ + +#endif /* !__G_BSEARCH_ARRAY_H__ */ diff --git a/glib/glib/gbytes.c b/glib/glib/gbytes.c new file mode 100644 index 0000000..daf5642 --- /dev/null +++ b/glib/glib/gbytes.c @@ -0,0 +1,482 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * Copyright © 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + * Stef Walter + */ + +#include "config.h" + +#include "gbytes.h" + +#include +#include +#include +#include +#include +#include +#include + +#include + +/** + * GBytes: + * + * A simple refcounted data type representing an immutable byte sequence + * from an unspecified origin. + * + * The purpose of a #GBytes is to keep the memory region that it holds + * alive for as long as anyone holds a reference to the bytes. When + * the last reference count is dropped, the memory is released. Multiple + * unrelated callers can use byte data in the #GBytes without coordinating + * their activities, resting assured that the byte data will not change or + * move while they hold a reference. + * + * A #GBytes can come from many different origins that may have + * different procedures for freeing the memory region. Examples are + * memory from g_malloc(), from memory slices, from a #GMappedFile or + * memory from other allocators. + * + * #GBytes work well as keys in #GHashTable. Use g_bytes_equal() and + * g_bytes_hash() as parameters to g_hash_table_new() or g_hash_table_new_full(). + * #GBytes can also be used as keys in a #GTree by passing the g_bytes_compare() + * function to g_tree_new(). + * + * The data pointed to by this bytes must not be modified. For a mutable + * array of bytes see #GByteArray. Use g_bytes_unref_to_array() to create a + * mutable array for a #GBytes sequence. To create an immutable #GBytes from + * a mutable #GByteArray, use the g_byte_array_free_to_bytes() function. + * + * Since: 2.32 + **/ + +struct _GBytes +{ + gconstpointer data; + gsize size; + gint ref_count; + GDestroyNotify free_func; + gpointer user_data; +}; + +/** + * g_bytes_new: + * @data: (array length=size): the data to be used for the bytes + * @size: the size of @data + * + * Creates a new #GBytes from @data. + * + * @data is copied. + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new (gconstpointer data, + gsize size) +{ + return g_bytes_new_take (g_memdup (data, size), size); +} + +/** + * g_bytes_new_take: + * @data: (transfer full) (array length=size): the data to be used for the bytes + * @size: the size of @data + * + * Creates a new #GBytes from @data. + * + * After this call, @data belongs to the bytes and may no longer be + * modified by the caller. g_free() will be called on @data when the + * bytes is no longer in use. Because of this @data must have been created by + * a call to g_malloc(), g_malloc0() or g_realloc() or by one of the many + * functions that wrap these calls (such as g_new(), g_strdup(), etc). + * + * For creating #GBytes with memory from other allocators, see + * g_bytes_new_with_free_func(). + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new_take (gpointer data, + gsize size) +{ + return g_bytes_new_with_free_func (data, size, g_free, data); +} + + +/** + * g_bytes_new_static: + * @data: (array length=size): the data to be used for the bytes + * @size: the size of @data + * + * Creates a new #GBytes from static data. + * + * @data must be static (ie: never modified or freed). + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new_static (gconstpointer data, + gsize size) +{ + return g_bytes_new_with_free_func (data, size, NULL, NULL); +} + +/** + * g_bytes_new_with_free_func: + * @data: (array length=size): the data to be used for the bytes + * @size: the size of @data + * @free_func: the function to call to release the data + * @user_data: data to pass to @free_func + * + * Creates a #GBytes from @data. + * + * When the last reference is dropped, @free_func will be called with the + * @user_data argument. + * + * @data must not be modified after this call is made until @free_func has + * been called to indicate that the bytes is no longer in use. + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new_with_free_func (gconstpointer data, + gsize size, + GDestroyNotify free_func, + gpointer user_data) +{ + GBytes *bytes; + + bytes = g_slice_new (GBytes); + bytes->data = data; + bytes->size = size; + bytes->free_func = free_func; + bytes->user_data = user_data; + bytes->ref_count = 1; + + return (GBytes *)bytes; +} + +/** + * g_bytes_new_from_bytes: + * @bytes: a #GBytes + * @offset: offset which subsection starts at + * @length: length of subsection + * + * Creates a #GBytes which is a subsection of another #GBytes. The @offset + + * @length may not be longer than the size of @bytes. + * + * A reference to @bytes will be held by the newly created #GBytes until + * the byte data is no longer needed. + * + * Returns: (transfer full): a new #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_new_from_bytes (GBytes *bytes, + gsize offset, + gsize length) +{ + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (offset <= bytes->size, NULL); + g_return_val_if_fail (offset + length <= bytes->size, NULL); + + return g_bytes_new_with_free_func ((gchar *)bytes->data + offset, length, + (GDestroyNotify)g_bytes_unref, g_bytes_ref (bytes)); +} + +/** + * g_bytes_get_data: + * @bytes: a #GBytes + * @size: (out) (allow-none): location to return size of byte data + * + * Get the byte data in the #GBytes. This data should not be modified. + * + * This function will always return the same pointer for a given #GBytes. + * + * Returns: (array length=size) (type guint8): a pointer to the byte data + * + * Since: 2.32 + */ +gconstpointer +g_bytes_get_data (GBytes *bytes, + gsize *size) +{ + g_return_val_if_fail (bytes != NULL, NULL); + if (size) + *size = bytes->size; + return bytes->data; +} + +/** + * g_bytes_get_size: + * @bytes: a #GBytes + * + * Get the size of the byte data in the #GBytes. + * + * This function will always return the same value for a given #GBytes. + * + * Returns: the size + * + * Since: 2.32 + */ +gsize +g_bytes_get_size (GBytes *bytes) +{ + g_return_val_if_fail (bytes != NULL, 0); + return bytes->size; +} + + +/** + * g_bytes_ref: + * @bytes: a #GBytes + * + * Increase the reference count on @bytes. + * + * Returns: the #GBytes + * + * Since: 2.32 + */ +GBytes * +g_bytes_ref (GBytes *bytes) +{ + g_return_val_if_fail (bytes != NULL, NULL); + + g_atomic_int_inc (&bytes->ref_count); + + return bytes; +} + +/** + * g_bytes_unref: + * @bytes: (allow-none): a #GBytes + * + * Releases a reference on @bytes. This may result in the bytes being + * freed. + * + * Since: 2.32 + */ +void +g_bytes_unref (GBytes *bytes) +{ + if (bytes == NULL) + return; + + if (g_atomic_int_dec_and_test (&bytes->ref_count)) + { + if (bytes->free_func != NULL) + bytes->free_func (bytes->user_data); + g_slice_free (GBytes, bytes); + } +} + +/** + * g_bytes_equal: + * @bytes1: (type GLib.Bytes): a pointer to a #GBytes + * @bytes2: (type GLib.Bytes): a pointer to a #GBytes to compare with @bytes1 + * + * Compares the two #GBytes values being pointed to and returns + * %TRUE if they are equal. + * + * This function can be passed to g_hash_table_new() as the @key_equal_func + * parameter, when using non-%NULL #GBytes pointers as keys in a #GHashTable. + * + * Returns: %TRUE if the two keys match. + * + * Since: 2.32 + */ +gboolean +g_bytes_equal (gconstpointer bytes1, + gconstpointer bytes2) +{ + const GBytes *b1 = bytes1; + const GBytes *b2 = bytes2; + + g_return_val_if_fail (bytes1 != NULL, FALSE); + g_return_val_if_fail (bytes2 != NULL, FALSE); + + return b1->size == b2->size && + memcmp (b1->data, b2->data, b1->size) == 0; +} + +/** + * g_bytes_hash: + * @bytes: (type GLib.Bytes): a pointer to a #GBytes key + * + * Creates an integer hash code for the byte data in the #GBytes. + * + * This function can be passed to g_hash_table_new() as the @key_equal_func + * parameter, when using non-%NULL #GBytes pointers as keys in a #GHashTable. + * + * Returns: a hash value corresponding to the key. + * + * Since: 2.32 + */ +guint +g_bytes_hash (gconstpointer bytes) +{ + const GBytes *a = bytes; + const signed char *p, *e; + guint32 h = 5381; + + g_return_val_if_fail (bytes != NULL, 0); + + for (p = (signed char *)a->data, e = (signed char *)a->data + a->size; p != e; p++) + h = (h << 5) + h + *p; + + return h; +} + +/** + * g_bytes_compare: + * @bytes1: (type GLib.Bytes): a pointer to a #GBytes + * @bytes2: (type GLib.Bytes): a pointer to a #GBytes to compare with @bytes1 + * + * Compares the two #GBytes values. + * + * This function can be used to sort GBytes instances in lexographical order. + * + * Returns: a negative value if bytes2 is lesser, a positive value if bytes2 is + * greater, and zero if bytes2 is equal to bytes1 + * + * Since: 2.32 + */ +gint +g_bytes_compare (gconstpointer bytes1, + gconstpointer bytes2) +{ + const GBytes *b1 = bytes1; + const GBytes *b2 = bytes2; + gint ret; + + g_return_val_if_fail (bytes1 != NULL, 0); + g_return_val_if_fail (bytes2 != NULL, 0); + + ret = memcmp (b1->data, b2->data, MIN (b1->size, b2->size)); + if (ret == 0 && b1->size != b2->size) + ret = b1->size < b2->size ? -1 : 1; + return ret; +} + +static gpointer +try_steal_and_unref (GBytes *bytes, + GDestroyNotify free_func, + gsize *size) +{ + gpointer result; + + if (bytes->free_func != free_func) + return NULL; + + /* Are we the only reference? */ + if (g_atomic_int_get (&bytes->ref_count) == 1) + { + *size = bytes->size; + result = (gpointer)bytes->data; + g_slice_free (GBytes, bytes); + return result; + } + + return NULL; +} + + +/** + * g_bytes_unref_to_data: + * @bytes: (transfer full): a #GBytes + * @size: location to place the length of the returned data + * + * Unreferences the bytes, and returns a pointer the same byte data + * contents. + * + * As an optimization, the byte data is returned without copying if this was + * the last reference to bytes and bytes was created with g_bytes_new(), + * g_bytes_new_take() or g_byte_array_free_to_bytes(). In all other cases the + * data is copied. + * + * Returns: (transfer full): a pointer to the same byte data, which should + * be freed with g_free() + * + * Since: 2.32 + */ +gpointer +g_bytes_unref_to_data (GBytes *bytes, + gsize *size) +{ + gpointer result; + + g_return_val_if_fail (bytes != NULL, NULL); + g_return_val_if_fail (size != NULL, NULL); + + /* + * Optimal path: if this is was the last reference, then we can return + * the data from this GBytes without copying. + */ + + result = try_steal_and_unref (bytes, g_free, size); + if (result == NULL) + { + /* + * Copy: Non g_malloc (or compatible) allocator, or static memory, + * so we have to copy, and then unref. + */ + result = g_memdup (bytes->data, bytes->size); + *size = bytes->size; + g_bytes_unref (bytes); + } + + return result; +} + +/** + * g_bytes_unref_to_array: + * @bytes: (transfer full): a #GBytes + * + * Unreferences the bytes, and returns a new mutable #GByteArray containing + * the same byte data. + * + * As an optimization, the byte data is transferred to the array without copying + * if this was the last reference to bytes and bytes was created with + * g_bytes_new(), g_bytes_new_take() or g_byte_array_free_to_bytes(). In all + * other cases the data is copied. + * + * Returns: (transfer full): a new mutable #GByteArray containing the same byte data + * + * Since: 2.32 + */ +GByteArray * +g_bytes_unref_to_array (GBytes *bytes) +{ + gpointer data; + gsize size; + + g_return_val_if_fail (bytes != NULL, NULL); + + data = g_bytes_unref_to_data (bytes, &size); + return g_byte_array_new_take (data, size); +} diff --git a/glib/glib/gbytes.h b/glib/glib/gbytes.h new file mode 100644 index 0000000..a120e21 --- /dev/null +++ b/glib/glib/gbytes.h @@ -0,0 +1,74 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * Copyright © 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + * Stef Walter + */ + +#ifndef __G_BYTES_H__ +#define __G_BYTES_H__ + +#include +#include + +G_BEGIN_DECLS + +GBytes * g_bytes_new (gconstpointer data, + gsize size); + +GBytes * g_bytes_new_take (gpointer data, + gsize size); + +GBytes * g_bytes_new_static (gconstpointer data, + gsize size); + +GBytes * g_bytes_new_with_free_func (gconstpointer data, + gsize size, + GDestroyNotify free_func, + gpointer user_data); + +GBytes * g_bytes_new_from_bytes (GBytes *bytes, + gsize offset, + gsize length); + +gconstpointer g_bytes_get_data (GBytes *bytes, + gsize *size); + +gsize g_bytes_get_size (GBytes *bytes); + +GBytes * g_bytes_ref (GBytes *bytes); + +void g_bytes_unref (GBytes *bytes); + +gpointer g_bytes_unref_to_data (GBytes *bytes, + gsize *size); + +GByteArray * g_bytes_unref_to_array (GBytes *bytes); + +guint g_bytes_hash (gconstpointer bytes); + +gboolean g_bytes_equal (gconstpointer bytes1, + gconstpointer bytes2); + +gint g_bytes_compare (gconstpointer bytes1, + gconstpointer bytes2); + +G_END_DECLS + +#endif /* __G_BYTES_H__ */ diff --git a/glib/glib/gcharset.c b/glib/glib/gcharset.c new file mode 100644 index 0000000..4f52ab4 --- /dev/null +++ b/glib/glib/gcharset.c @@ -0,0 +1,592 @@ +/* gcharset.c - Charset information + * + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "gcharset.h" + +#include "garray.h" +#include "genviron.h" +#include "ghash.h" +#include "gmessages.h" +#include "gstrfuncs.h" +#include "gthread.h" +#ifdef G_OS_WIN32 +#include "gwin32.h" +#endif + +#include "libcharset/libcharset.h" + +#include +#include + +G_LOCK_DEFINE_STATIC (aliases); + +static GHashTable * +get_alias_hash (void) +{ + static GHashTable *alias_hash = NULL; + const char *aliases; + + G_LOCK (aliases); + + if (!alias_hash) + { + alias_hash = g_hash_table_new (g_str_hash, g_str_equal); + + aliases = _g_locale_get_charset_aliases (); + while (*aliases != '\0') + { + const char *canonical; + const char *alias; + const char **alias_array; + int count = 0; + + alias = aliases; + aliases += strlen (aliases) + 1; + canonical = aliases; + aliases += strlen (aliases) + 1; + + alias_array = g_hash_table_lookup (alias_hash, canonical); + if (alias_array) + { + while (alias_array[count]) + count++; + } + + alias_array = g_renew (const char *, alias_array, count + 2); + alias_array[count] = alias; + alias_array[count + 1] = NULL; + + g_hash_table_insert (alias_hash, (char *)canonical, alias_array); + } + } + + G_UNLOCK (aliases); + + return alias_hash; +} + +/* As an abuse of the alias table, the following routines gets + * the charsets that are aliases for the canonical name. + */ +G_GNUC_INTERNAL const char ** +_g_charset_get_aliases (const char *canonical_name) +{ + GHashTable *alias_hash = get_alias_hash (); + + return g_hash_table_lookup (alias_hash, canonical_name); +} + +static gboolean +g_utf8_get_charset_internal (const char *raw_data, + const char **a) +{ + const char *charset = g_getenv ("CHARSET"); + + if (charset && *charset) + { + *a = charset; + + if (charset && strstr (charset, "UTF-8")) + return TRUE; + else + return FALSE; + } + + /* The libcharset code tries to be thread-safe without + * a lock, but has a memory leak and a missing memory + * barrier, so we lock for it + */ + G_LOCK (aliases); + charset = _g_locale_charset_unalias (raw_data); + G_UNLOCK (aliases); + + if (charset && *charset) + { + *a = charset; + + if (charset && strstr (charset, "UTF-8")) + return TRUE; + else + return FALSE; + } + + /* Assume this for compatibility at present. */ + *a = "US-ASCII"; + + return FALSE; +} + +typedef struct _GCharsetCache GCharsetCache; + +struct _GCharsetCache { + gboolean is_utf8; + gchar *raw; + gchar *charset; +}; + +static void +charset_cache_free (gpointer data) +{ + GCharsetCache *cache = data; + g_free (cache->raw); + g_free (cache->charset); + g_free (cache); +} + +/** + * g_get_charset: + * @charset: return location for character set name + * + * Obtains the character set for the current + * locale; you might use this character set as an argument to + * g_convert(), to convert from the current locale's encoding to some + * other encoding. (Frequently g_locale_to_utf8() and g_locale_from_utf8() + * are nice shortcuts, though.) + * + * On Windows the character set returned by this function is the + * so-called system default ANSI code-page. That is the character set + * used by the "narrow" versions of C library and Win32 functions that + * handle file names. It might be different from the character set + * used by the C library's current locale. + * + * The return value is %TRUE if the locale's encoding is UTF-8, in that + * case you can perhaps avoid calling g_convert(). + * + * The string returned in @charset is not allocated, and should not be + * freed. + * + * Return value: %TRUE if the returned charset is UTF-8 + */ +gboolean +g_get_charset (const char **charset) +{ + static GPrivate cache_private = G_PRIVATE_INIT (charset_cache_free); + GCharsetCache *cache = g_private_get (&cache_private); + const gchar *raw; + + if (!cache) + { + cache = g_new0 (GCharsetCache, 1); + g_private_set (&cache_private, cache); + } + + G_LOCK (aliases); + raw = _g_locale_charset_raw (); + G_UNLOCK (aliases); + + if (!(cache->raw && strcmp (cache->raw, raw) == 0)) + { + const gchar *new_charset; + + g_free (cache->raw); + g_free (cache->charset); + cache->raw = g_strdup (raw); + cache->is_utf8 = g_utf8_get_charset_internal (raw, &new_charset); + cache->charset = g_strdup (new_charset); + } + + if (charset) + *charset = cache->charset; + + return cache->is_utf8; +} + +/** + * g_get_codeset: + * + * Gets the character set for the current locale. + * + * Return value: a newly allocated string containing the name + * of the character set. This string must be freed with g_free(). + */ +gchar * +g_get_codeset (void) +{ + const gchar *charset; + + g_get_charset (&charset); + + return g_strdup (charset); +} + +#ifndef G_OS_WIN32 + +static GHashTable *alias_table = NULL; + +/* read an alias file for the locales */ +static void +read_aliases (gchar *file) +{ + FILE *fp; + char buf[256]; + + if (!alias_table) + alias_table = g_hash_table_new (g_str_hash, g_str_equal); + fp = fopen (file,"r"); + if (!fp) + return; + while (fgets (buf, 256, fp)) + { + char *p, *q; + + g_strstrip (buf); + + /* Line is a comment */ + if ((buf[0] == '#') || (buf[0] == '\0')) + continue; + + /* Reads first column */ + for (p = buf, q = NULL; *p; p++) { + if ((*p == '\t') || (*p == ' ') || (*p == ':')) { + *p = '\0'; + q = p+1; + while ((*q == '\t') || (*q == ' ')) { + q++; + } + break; + } + } + /* The line only had one column */ + if (!q || *q == '\0') + continue; + + /* Read second column */ + for (p = q; *p; p++) { + if ((*p == '\t') || (*p == ' ')) { + *p = '\0'; + break; + } + } + + /* Add to alias table if necessary */ + if (!g_hash_table_lookup (alias_table, buf)) { + g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q)); + } + } + fclose (fp); +} + +#endif + +static char * +unalias_lang (char *lang) +{ +#ifndef G_OS_WIN32 + char *p; + int i; + + if (!alias_table) + read_aliases ("/usr/share/locale/locale.alias"); + + i = 0; + while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0)) + { + lang = p; + if (i++ == 30) + { + static gboolean said_before = FALSE; + if (!said_before) + g_warning ("Too many alias levels for a locale, " + "may indicate a loop"); + said_before = TRUE; + return lang; + } + } +#endif + return lang; +} + +/* Mask for components of locale spec. The ordering here is from + * least significant to most significant + */ +enum +{ + COMPONENT_CODESET = 1 << 0, + COMPONENT_TERRITORY = 1 << 1, + COMPONENT_MODIFIER = 1 << 2 +}; + +/* Break an X/Open style locale specification into components + */ +static guint +explode_locale (const gchar *locale, + gchar **language, + gchar **territory, + gchar **codeset, + gchar **modifier) +{ + const gchar *uscore_pos; + const gchar *at_pos; + const gchar *dot_pos; + + guint mask = 0; + + uscore_pos = strchr (locale, '_'); + dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.'); + at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@'); + + if (at_pos) + { + mask |= COMPONENT_MODIFIER; + *modifier = g_strdup (at_pos); + } + else + at_pos = locale + strlen (locale); + + if (dot_pos) + { + mask |= COMPONENT_CODESET; + *codeset = g_strndup (dot_pos, at_pos - dot_pos); + } + else + dot_pos = at_pos; + + if (uscore_pos) + { + mask |= COMPONENT_TERRITORY; + *territory = g_strndup (uscore_pos, dot_pos - uscore_pos); + } + else + uscore_pos = dot_pos; + + *language = g_strndup (locale, uscore_pos - locale); + + return mask; +} + +/* + * Compute all interesting variants for a given locale name - + * by stripping off different components of the value. + * + * For simplicity, we assume that the locale is in + * X/Open format: language[_territory][.codeset][@modifier] + * + * TODO: Extend this to handle the CEN format (see the GNUlibc docs) + * as well. We could just copy the code from glibc wholesale + * but it is big, ugly, and complicated, so I'm reluctant + * to do so when this should handle 99% of the time... + */ +static void +append_locale_variants (GPtrArray *array, + const gchar *locale) +{ + gchar *language = NULL; + gchar *territory = NULL; + gchar *codeset = NULL; + gchar *modifier = NULL; + + guint mask; + guint i, j; + + g_return_if_fail (locale != NULL); + + mask = explode_locale (locale, &language, &territory, &codeset, &modifier); + + /* Iterate through all possible combinations, from least attractive + * to most attractive. + */ + for (j = 0; j <= mask; ++j) + { + i = mask - j; + + if ((i & ~mask) == 0) + { + gchar *val = g_strconcat (language, + (i & COMPONENT_TERRITORY) ? territory : "", + (i & COMPONENT_CODESET) ? codeset : "", + (i & COMPONENT_MODIFIER) ? modifier : "", + NULL); + g_ptr_array_add (array, val); + } + } + + g_free (language); + if (mask & COMPONENT_CODESET) + g_free (codeset); + if (mask & COMPONENT_TERRITORY) + g_free (territory); + if (mask & COMPONENT_MODIFIER) + g_free (modifier); +} + +/** + * g_get_locale_variants: + * @locale: a locale identifier + * + * Returns a list of derived variants of @locale, which can be used to + * e.g. construct locale-dependent filenames or search paths. The returned + * list is sorted from most desirable to least desirable. + * This function handles territory, charset and extra locale modifiers. + * + * For example, if @locale is "fr_BE", then the returned list + * is "fr_BE", "fr". + * + * If you need the list of variants for the current locale, + * use g_get_language_names(). + * + * Returns: (transfer full) (array zero-terminated=1) (element-type utf8): a newly + * allocated array of newly allocated strings with the locale variants. Free with + * g_strfreev(). + * + * Since: 2.28 + */ +gchar ** +g_get_locale_variants (const gchar *locale) +{ + GPtrArray *array; + + g_return_val_if_fail (locale != NULL, NULL); + + array = g_ptr_array_sized_new (8); + append_locale_variants (array, locale); + g_ptr_array_add (array, NULL); + + return (gchar **) g_ptr_array_free (array, FALSE); +} + +/* The following is (partly) taken from the gettext package. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. */ + +static const gchar * +guess_category_value (const gchar *category_name) +{ + const gchar *retval; + + /* The highest priority value is the `LANGUAGE' environment + variable. This is a GNU extension. */ + retval = g_getenv ("LANGUAGE"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* `LANGUAGE' is not set. So we have to proceed with the POSIX + methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some + systems this can be done by the `setlocale' function itself. */ + + /* Setting of LC_ALL overwrites all other. */ + retval = g_getenv ("LC_ALL"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* Next comes the name of the desired category. */ + retval = g_getenv (category_name); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + + /* Last possibility is the LANG environment variable. */ + retval = g_getenv ("LANG"); + if ((retval != NULL) && (retval[0] != '\0')) + return retval; + +#ifdef G_PLATFORM_WIN32 + /* g_win32_getlocale() first checks for LC_ALL, LC_MESSAGES and + * LANG, which we already did above. Oh well. The main point of + * calling g_win32_getlocale() is to get the thread's locale as used + * by Windows and the Microsoft C runtime (in the "English_United + * States" format) translated into the Unixish format. + */ + { + char *locale = g_win32_getlocale (); + retval = g_intern_string (locale); + g_free (locale); + return retval; + } +#endif + + return NULL; +} + +typedef struct _GLanguageNamesCache GLanguageNamesCache; + +struct _GLanguageNamesCache { + gchar *languages; + gchar **language_names; +}; + +static void +language_names_cache_free (gpointer data) +{ + GLanguageNamesCache *cache = data; + g_free (cache->languages); + g_strfreev (cache->language_names); + g_free (cache); +} + +/** + * g_get_language_names: + * + * Computes a list of applicable locale names, which can be used to + * e.g. construct locale-dependent filenames or search paths. The returned + * list is sorted from most desirable to least desirable and always contains + * the default locale "C". + * + * For example, if LANGUAGE=de:en_US, then the returned list is + * "de", "en_US", "en", "C". + * + * This function consults the environment variables LANGUAGE, + * LC_ALL, LC_MESSAGES and LANG + * to find the list of locales specified by the user. + * + * Return value: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by GLib + * that must not be modified or freed. + * + * Since: 2.6 + **/ +const gchar * const * +g_get_language_names (void) +{ + static GPrivate cache_private = G_PRIVATE_INIT (language_names_cache_free); + GLanguageNamesCache *cache = g_private_get (&cache_private); + const gchar *value; + + if (!cache) + { + cache = g_new0 (GLanguageNamesCache, 1); + g_private_set (&cache_private, cache); + } + + value = guess_category_value ("LC_MESSAGES"); + if (!value) + value = "C"; + + if (!(cache->languages && strcmp (cache->languages, value) == 0)) + { + GPtrArray *array; + gchar **alist, **a; + + g_free (cache->languages); + g_strfreev (cache->language_names); + cache->languages = g_strdup (value); + + array = g_ptr_array_sized_new (8); + + alist = g_strsplit (value, ":", 0); + for (a = alist; *a; a++) + append_locale_variants (array, unalias_lang (*a)); + g_strfreev (alist); + g_ptr_array_add (array, g_strdup ("C")); + g_ptr_array_add (array, NULL); + + cache->language_names = (gchar **) g_ptr_array_free (array, FALSE); + } + + return (const gchar * const *) cache->language_names; +} diff --git a/glib/glib/gcharset.h b/glib/glib/gcharset.h new file mode 100644 index 0000000..9b56524 --- /dev/null +++ b/glib/glib/gcharset.h @@ -0,0 +1,40 @@ +/* gcharset.h - Charset functions + * + * Copyright (C) 2011 Red Hat, Inc. + * + * The GLib Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The GLib Library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_CHARSET_H__ +#define __G_CHARSET_H__ + +#include + +G_BEGIN_DECLS + +gboolean g_get_charset (const char **charset); +gchar * g_get_codeset (void); + +const gchar * const * g_get_language_names (void); +gchar ** g_get_locale_variants (const gchar *locale); + +G_END_DECLS + +#endif /* __G_CHARSET_H__ */ diff --git a/glib/glib/gchecksum.c b/glib/glib/gchecksum.c new file mode 100644 index 0000000..e860243 --- /dev/null +++ b/glib/glib/gchecksum.c @@ -0,0 +1,1461 @@ +/* gchecksum.h - data hashing functions + * + * Copyright (C) 2007 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "gchecksum.h" + +#include "gslice.h" +#include "gmem.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gtypes.h" +#include "glibintl.h" + + +/** + * SECTION:checksum + * @title: Data Checksums + * @short_description: computes the checksum for data + * + * GLib provides a generic API for computing checksums (or "digests") + * for a sequence of arbitrary bytes, using various hashing algorithms + * like MD5, SHA-1 and SHA-256. Checksums are commonly used in various + * environments and specifications. + * + * GLib supports incremental checksums using the GChecksum data + * structure, by calling g_checksum_update() as long as there's data + * available and then using g_checksum_get_string() or + * g_checksum_get_digest() to compute the checksum and return it either + * as a string in hexadecimal form, or as a raw sequence of bytes. To + * compute the checksum for binary blobs and NUL-terminated strings in + * one go, use the convenience functions g_compute_checksum_for_data() + * and g_compute_checksum_for_string(), respectively. + * + * Support for checksums has been added in GLib 2.16 + **/ + +#define IS_VALID_TYPE(type) ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA256) + +/* The fact that these are lower case characters is part of the ABI */ +static const gchar hex_digits[] = "0123456789abcdef"; + +#define MD5_DATASIZE 64 +#define MD5_DIGEST_LEN 16 + +typedef struct +{ + guint32 buf[4]; + guint32 bits[2]; + + guchar data[MD5_DATASIZE]; + + guchar digest[MD5_DIGEST_LEN]; +} Md5sum; + +#define SHA1_DATASIZE 64 +#define SHA1_DIGEST_LEN 20 + +typedef struct +{ + guint32 buf[5]; + guint32 bits[2]; + + /* we pack 64 unsigned chars into 16 32-bit unsigned integers */ + guint32 data[16]; + + guchar digest[SHA1_DIGEST_LEN]; +} Sha1sum; + +#define SHA256_DATASIZE 64 +#define SHA256_DIGEST_LEN 32 + +typedef struct +{ + guint32 buf[8]; + guint32 bits[2]; + + guint8 data[SHA256_DATASIZE]; + + guchar digest[SHA256_DIGEST_LEN]; +} Sha256sum; + +struct _GChecksum +{ + GChecksumType type; + + gchar *digest_str; + + union { + Md5sum md5; + Sha1sum sha1; + Sha256sum sha256; + } sum; +}; + +/* we need different byte swapping functions because MD5 expects buffers + * to be little-endian, while SHA1 and SHA256 expect them in big-endian + * form. + */ + +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +#define md5_byte_reverse(buffer,length) +#else +/* assume that the passed buffer is integer aligned */ +static inline void +md5_byte_reverse (guchar *buffer, + gulong length) +{ + guint32 bit; + + do + { + bit = (guint32) ((unsigned) buffer[3] << 8 | buffer[2]) << 16 | + ((unsigned) buffer[1] << 8 | buffer[0]); + * (guint32 *) buffer = bit; + buffer += 4; + } + while (--length); +} +#endif /* G_BYTE_ORDER == G_LITTLE_ENDIAN */ + +#if G_BYTE_ORDER == G_BIG_ENDIAN +#define sha_byte_reverse(buffer,length) +#else +static inline void +sha_byte_reverse (guint32 *buffer, + gint length) +{ + length /= sizeof (guint32); + while (length--) + { + *buffer = GUINT32_SWAP_LE_BE (*buffer); + ++buffer; + } +} +#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */ + +static gchar * +digest_to_string (guint8 *digest, + gsize digest_len) +{ + gint len = digest_len * 2; + gint i; + gchar *retval; + + retval = g_new (gchar, len + 1); + + for (i = 0; i < digest_len; i++) + { + guint8 byte = digest[i]; + + retval[2 * i] = hex_digits[byte >> 4]; + retval[2 * i + 1] = hex_digits[byte & 0xf]; + } + + retval[len] = 0; + + return retval; +} + +/* + * MD5 Checksum + */ + +/* This MD5 digest computation is based on the equivalent code + * written by Colin Plumb. It came with this notice: + * + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + */ + +static void +md5_sum_init (Md5sum *md5) +{ + /* arbitrary constants */ + md5->buf[0] = 0x67452301; + md5->buf[1] = 0xefcdab89; + md5->buf[2] = 0x98badcfe; + md5->buf[3] = 0x10325476; + + md5->bits[0] = md5->bits[1] = 0; +} + +/* + * The core of the MD5 algorithm, this alters an existing MD5 hash to + * reflect the addition of 16 longwords of new data. md5_sum_update() + * blocks the data and converts bytes into longwords for this routine. + */ +static void +md5_transform (guint32 buf[4], + guint32 const in[16]) +{ + register guint32 a, b, c, d; + +/* The four core functions - F1 is optimized somewhat */ +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1 (z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +/* This is the central step in the MD5 algorithm. */ +#define md5_step(f, w, x, y, z, data, s) \ + ( w += f (x, y, z) + data, w = w << s | w >> (32 - s), w += x ) + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + md5_step (F1, a, b, c, d, in[0] + 0xd76aa478, 7); + md5_step (F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + md5_step (F1, c, d, a, b, in[2] + 0x242070db, 17); + md5_step (F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + md5_step (F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + md5_step (F1, d, a, b, c, in[5] + 0x4787c62a, 12); + md5_step (F1, c, d, a, b, in[6] + 0xa8304613, 17); + md5_step (F1, b, c, d, a, in[7] + 0xfd469501, 22); + md5_step (F1, a, b, c, d, in[8] + 0x698098d8, 7); + md5_step (F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + md5_step (F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + md5_step (F1, b, c, d, a, in[11] + 0x895cd7be, 22); + md5_step (F1, a, b, c, d, in[12] + 0x6b901122, 7); + md5_step (F1, d, a, b, c, in[13] + 0xfd987193, 12); + md5_step (F1, c, d, a, b, in[14] + 0xa679438e, 17); + md5_step (F1, b, c, d, a, in[15] + 0x49b40821, 22); + + md5_step (F2, a, b, c, d, in[1] + 0xf61e2562, 5); + md5_step (F2, d, a, b, c, in[6] + 0xc040b340, 9); + md5_step (F2, c, d, a, b, in[11] + 0x265e5a51, 14); + md5_step (F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + md5_step (F2, a, b, c, d, in[5] + 0xd62f105d, 5); + md5_step (F2, d, a, b, c, in[10] + 0x02441453, 9); + md5_step (F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + md5_step (F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + md5_step (F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + md5_step (F2, d, a, b, c, in[14] + 0xc33707d6, 9); + md5_step (F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + md5_step (F2, b, c, d, a, in[8] + 0x455a14ed, 20); + md5_step (F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + md5_step (F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + md5_step (F2, c, d, a, b, in[7] + 0x676f02d9, 14); + md5_step (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + md5_step (F3, a, b, c, d, in[5] + 0xfffa3942, 4); + md5_step (F3, d, a, b, c, in[8] + 0x8771f681, 11); + md5_step (F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + md5_step (F3, b, c, d, a, in[14] + 0xfde5380c, 23); + md5_step (F3, a, b, c, d, in[1] + 0xa4beea44, 4); + md5_step (F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + md5_step (F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + md5_step (F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + md5_step (F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + md5_step (F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + md5_step (F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + md5_step (F3, b, c, d, a, in[6] + 0x04881d05, 23); + md5_step (F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + md5_step (F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + md5_step (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + md5_step (F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + md5_step (F4, a, b, c, d, in[0] + 0xf4292244, 6); + md5_step (F4, d, a, b, c, in[7] + 0x432aff97, 10); + md5_step (F4, c, d, a, b, in[14] + 0xab9423a7, 15); + md5_step (F4, b, c, d, a, in[5] + 0xfc93a039, 21); + md5_step (F4, a, b, c, d, in[12] + 0x655b59c3, 6); + md5_step (F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + md5_step (F4, c, d, a, b, in[10] + 0xffeff47d, 15); + md5_step (F4, b, c, d, a, in[1] + 0x85845dd1, 21); + md5_step (F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + md5_step (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + md5_step (F4, c, d, a, b, in[6] + 0xa3014314, 15); + md5_step (F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + md5_step (F4, a, b, c, d, in[4] + 0xf7537e82, 6); + md5_step (F4, d, a, b, c, in[11] + 0xbd3af235, 10); + md5_step (F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + md5_step (F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; + +#undef F1 +#undef F2 +#undef F3 +#undef F4 +#undef md5_step +} + +static void +md5_sum_update (Md5sum *md5, + const guchar *data, + gsize length) +{ + guint32 bit; + + bit = md5->bits[0]; + md5->bits[0] = bit + ((guint32) length << 3); + + /* carry from low to high */ + if (md5->bits[0] < bit) + md5->bits[1] += 1; + + md5->bits[1] += length >> 29; + + /* bytes already in Md5sum->data */ + bit = (bit >> 3) & 0x3f; + + /* handle any leading odd-sized chunks */ + if (bit) + { + guchar *p = (guchar *) md5->data + bit; + + bit = MD5_DATASIZE - bit; + if (length < bit) + { + memcpy (p, data, length); + return; + } + + memcpy (p, data, bit); + + md5_byte_reverse (md5->data, 16); + md5_transform (md5->buf, (guint32 *) md5->data); + + data += bit; + length -= bit; + } + + /* process data in 64-byte chunks */ + while (length >= MD5_DATASIZE) + { + memcpy (md5->data, data, MD5_DATASIZE); + + md5_byte_reverse (md5->data, 16); + md5_transform (md5->buf, (guint32 *) md5->data); + + data += MD5_DATASIZE; + length -= MD5_DATASIZE; + } + + /* handle any remaining bytes of data */ + memcpy (md5->data, data, length); +} + +/* closes a checksum */ +static void +md5_sum_close (Md5sum *md5) +{ + guint count; + guchar *p; + + /* Compute number of bytes mod 64 */ + count = (md5->bits[0] >> 3) & 0x3F; + + /* Set the first char of padding to 0x80. + * This is safe since there is always at least one byte free + */ + p = md5->data + count; + *p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = MD5_DATASIZE - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) + { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset (p, 0, count); + + md5_byte_reverse (md5->data, 16); + md5_transform (md5->buf, (guint32 *) md5->data); + + /* Now fill the next block with 56 bytes */ + memset (md5->data, 0, MD5_DATASIZE - 8); + } + else + { + /* Pad block to 56 bytes */ + memset (p, 0, count - 8); + } + + md5_byte_reverse (md5->data, 14); + + /* Append length in bits and transform */ + ((guint32 *) md5->data)[14] = md5->bits[0]; + ((guint32 *) md5->data)[15] = md5->bits[1]; + + md5_transform (md5->buf, (guint32 *) md5->data); + md5_byte_reverse ((guchar *) md5->buf, 4); + + memcpy (md5->digest, md5->buf, 16); + + /* Reset buffers in case they contain sensitive data */ + memset (md5->buf, 0, sizeof (md5->buf)); + memset (md5->data, 0, sizeof (md5->data)); +} + +static gchar * +md5_sum_to_string (Md5sum *md5) +{ + return digest_to_string (md5->digest, MD5_DIGEST_LEN); +} + +static void +md5_sum_digest (Md5sum *md5, + guint8 *digest) +{ + gint i; + + for (i = 0; i < MD5_DIGEST_LEN; i++) + digest[i] = md5->digest[i]; +} + +/* + * SHA-1 Checksum + */ + +/* The following implementation comes from D-Bus dbus-sha.c. I've changed + * it to use GLib types and to work more like the MD5 implementation above. + * I left the comments to have an history of this code. + * -- Emmanuele Bassi, ebassi@gnome.org + */ + +/* The following comments have the history of where this code + * comes from. I actually copied it from GNet in GNOME CVS. + * - hp@redhat.com + */ + +/* + * sha.h : Implementation of the Secure Hash Algorithm + * + * Part of the Python Cryptography Toolkit, version 1.0.0 + * + * Copyright (C) 1995, A.M. Kuchling + * + * Distribute and use freely; there are no restrictions on further + * dissemination and usage except those imposed by the laws of your + * country of residence. + * + */ + +/* SHA: NIST's Secure Hash Algorithm */ + +/* Based on SHA code originally posted to sci.crypt by Peter Gutmann + in message <30ajo5$oe8@ccu2.auckland.ac.nz>. + Modified to test for endianness on creation of SHA objects by AMK. + Also, the original specification of SHA was found to have a weakness + by NSA/NIST. This code implements the fixed version of SHA. +*/ + +/* Here's the first paragraph of Peter Gutmann's posting: + +The following is my SHA (FIPS 180) code updated to allow use of the "fixed" +SHA, thanks to Jim Gillogly and an anonymous contributor for the information on +what's changed in the new version. The fix is a simple change which involves +adding a single rotate in the initial expansion function. It is unknown +whether this is an optimal solution to the problem which was discovered in the +SHA or whether it's simply a bandaid which fixes the problem with a minimum of +effort (for example the reengineering of a great many Capstone chips). +*/ + +static void +sha1_sum_init (Sha1sum *sha1) +{ + /* initialize constants */ + sha1->buf[0] = 0x67452301L; + sha1->buf[1] = 0xEFCDAB89L; + sha1->buf[2] = 0x98BADCFEL; + sha1->buf[3] = 0x10325476L; + sha1->buf[4] = 0xC3D2E1F0L; + + /* initialize bits */ + sha1->bits[0] = sha1->bits[1] = 0; +} + +/* The SHA f()-functions. */ + +#define f1(x,y,z) (z ^ (x & (y ^ z))) /* Rounds 0-19 */ +#define f2(x,y,z) (x ^ y ^ z) /* Rounds 20-39 */ +#define f3(x,y,z) (( x & y) | (z & (x | y))) /* Rounds 40-59 */ +#define f4(x,y,z) (x ^ y ^ z) /* Rounds 60-79 */ + +/* The SHA Mysterious Constants */ +#define K1 0x5A827999L /* Rounds 0-19 */ +#define K2 0x6ED9EBA1L /* Rounds 20-39 */ +#define K3 0x8F1BBCDCL /* Rounds 40-59 */ +#define K4 0xCA62C1D6L /* Rounds 60-79 */ + +/* 32-bit rotate left - kludged with shifts */ +#define ROTL(n,X) (((X) << n ) | ((X) >> (32 - n))) + +/* The initial expanding function. The hash function is defined over an + 80-word expanded input array W, where the first 16 are copies of the input + data, and the remaining 64 are defined by + + W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ] + + This implementation generates these values on the fly in a circular + buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this + optimization. + + The updated SHA changes the expanding function by adding a rotate of 1 + bit. Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor + for this information */ + +#define expand(W,i) (W[ i & 15 ] = ROTL (1, (W[ i & 15] ^ \ + W[(i - 14) & 15] ^ \ + W[(i - 8) & 15] ^ \ + W[(i - 3) & 15]))) + + +/* The prototype SHA sub-round. The fundamental sub-round is: + + a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data; + b' = a; + c' = ROTL( 30, b ); + d' = c; + e' = d; + + but this is implemented by unrolling the loop 5 times and renaming the + variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration. + This code is then replicated 20 times for each of the 4 functions, using + the next 20 values from the W[] array each time */ + +#define subRound(a, b, c, d, e, f, k, data) \ + (e += ROTL (5, a) + f(b, c, d) + k + data, b = ROTL (30, b)) + +static void +sha1_transform (guint32 buf[5], + guint32 in[16]) +{ + guint32 A, B, C, D, E; + + A = buf[0]; + B = buf[1]; + C = buf[2]; + D = buf[3]; + E = buf[4]; + + /* Heavy mangling, in 4 sub-rounds of 20 iterations each. */ + subRound (A, B, C, D, E, f1, K1, in[0]); + subRound (E, A, B, C, D, f1, K1, in[1]); + subRound (D, E, A, B, C, f1, K1, in[2]); + subRound (C, D, E, A, B, f1, K1, in[3]); + subRound (B, C, D, E, A, f1, K1, in[4]); + subRound (A, B, C, D, E, f1, K1, in[5]); + subRound (E, A, B, C, D, f1, K1, in[6]); + subRound (D, E, A, B, C, f1, K1, in[7]); + subRound (C, D, E, A, B, f1, K1, in[8]); + subRound (B, C, D, E, A, f1, K1, in[9]); + subRound (A, B, C, D, E, f1, K1, in[10]); + subRound (E, A, B, C, D, f1, K1, in[11]); + subRound (D, E, A, B, C, f1, K1, in[12]); + subRound (C, D, E, A, B, f1, K1, in[13]); + subRound (B, C, D, E, A, f1, K1, in[14]); + subRound (A, B, C, D, E, f1, K1, in[15]); + subRound (E, A, B, C, D, f1, K1, expand (in, 16)); + subRound (D, E, A, B, C, f1, K1, expand (in, 17)); + subRound (C, D, E, A, B, f1, K1, expand (in, 18)); + subRound (B, C, D, E, A, f1, K1, expand (in, 19)); + + subRound (A, B, C, D, E, f2, K2, expand (in, 20)); + subRound (E, A, B, C, D, f2, K2, expand (in, 21)); + subRound (D, E, A, B, C, f2, K2, expand (in, 22)); + subRound (C, D, E, A, B, f2, K2, expand (in, 23)); + subRound (B, C, D, E, A, f2, K2, expand (in, 24)); + subRound (A, B, C, D, E, f2, K2, expand (in, 25)); + subRound (E, A, B, C, D, f2, K2, expand (in, 26)); + subRound (D, E, A, B, C, f2, K2, expand (in, 27)); + subRound (C, D, E, A, B, f2, K2, expand (in, 28)); + subRound (B, C, D, E, A, f2, K2, expand (in, 29)); + subRound (A, B, C, D, E, f2, K2, expand (in, 30)); + subRound (E, A, B, C, D, f2, K2, expand (in, 31)); + subRound (D, E, A, B, C, f2, K2, expand (in, 32)); + subRound (C, D, E, A, B, f2, K2, expand (in, 33)); + subRound (B, C, D, E, A, f2, K2, expand (in, 34)); + subRound (A, B, C, D, E, f2, K2, expand (in, 35)); + subRound (E, A, B, C, D, f2, K2, expand (in, 36)); + subRound (D, E, A, B, C, f2, K2, expand (in, 37)); + subRound (C, D, E, A, B, f2, K2, expand (in, 38)); + subRound (B, C, D, E, A, f2, K2, expand (in, 39)); + + subRound (A, B, C, D, E, f3, K3, expand (in, 40)); + subRound (E, A, B, C, D, f3, K3, expand (in, 41)); + subRound (D, E, A, B, C, f3, K3, expand (in, 42)); + subRound (C, D, E, A, B, f3, K3, expand (in, 43)); + subRound (B, C, D, E, A, f3, K3, expand (in, 44)); + subRound (A, B, C, D, E, f3, K3, expand (in, 45)); + subRound (E, A, B, C, D, f3, K3, expand (in, 46)); + subRound (D, E, A, B, C, f3, K3, expand (in, 47)); + subRound (C, D, E, A, B, f3, K3, expand (in, 48)); + subRound (B, C, D, E, A, f3, K3, expand (in, 49)); + subRound (A, B, C, D, E, f3, K3, expand (in, 50)); + subRound (E, A, B, C, D, f3, K3, expand (in, 51)); + subRound (D, E, A, B, C, f3, K3, expand (in, 52)); + subRound (C, D, E, A, B, f3, K3, expand (in, 53)); + subRound (B, C, D, E, A, f3, K3, expand (in, 54)); + subRound (A, B, C, D, E, f3, K3, expand (in, 55)); + subRound (E, A, B, C, D, f3, K3, expand (in, 56)); + subRound (D, E, A, B, C, f3, K3, expand (in, 57)); + subRound (C, D, E, A, B, f3, K3, expand (in, 58)); + subRound (B, C, D, E, A, f3, K3, expand (in, 59)); + + subRound (A, B, C, D, E, f4, K4, expand (in, 60)); + subRound (E, A, B, C, D, f4, K4, expand (in, 61)); + subRound (D, E, A, B, C, f4, K4, expand (in, 62)); + subRound (C, D, E, A, B, f4, K4, expand (in, 63)); + subRound (B, C, D, E, A, f4, K4, expand (in, 64)); + subRound (A, B, C, D, E, f4, K4, expand (in, 65)); + subRound (E, A, B, C, D, f4, K4, expand (in, 66)); + subRound (D, E, A, B, C, f4, K4, expand (in, 67)); + subRound (C, D, E, A, B, f4, K4, expand (in, 68)); + subRound (B, C, D, E, A, f4, K4, expand (in, 69)); + subRound (A, B, C, D, E, f4, K4, expand (in, 70)); + subRound (E, A, B, C, D, f4, K4, expand (in, 71)); + subRound (D, E, A, B, C, f4, K4, expand (in, 72)); + subRound (C, D, E, A, B, f4, K4, expand (in, 73)); + subRound (B, C, D, E, A, f4, K4, expand (in, 74)); + subRound (A, B, C, D, E, f4, K4, expand (in, 75)); + subRound (E, A, B, C, D, f4, K4, expand (in, 76)); + subRound (D, E, A, B, C, f4, K4, expand (in, 77)); + subRound (C, D, E, A, B, f4, K4, expand (in, 78)); + subRound (B, C, D, E, A, f4, K4, expand (in, 79)); + + /* Build message digest */ + buf[0] += A; + buf[1] += B; + buf[2] += C; + buf[3] += D; + buf[4] += E; +} + +#undef K1 +#undef K2 +#undef K3 +#undef K4 +#undef f1 +#undef f2 +#undef f3 +#undef f4 +#undef ROTL +#undef expand +#undef subRound + +static void +sha1_sum_update (Sha1sum *sha1, + const guchar *buffer, + gsize count) +{ + guint32 tmp; + guint dataCount; + + /* Update bitcount */ + tmp = sha1->bits[0]; + if ((sha1->bits[0] = tmp + ((guint32) count << 3) ) < tmp) + sha1->bits[1] += 1; /* Carry from low to high */ + sha1->bits[1] += count >> 29; + + /* Get count of bytes already in data */ + dataCount = (guint) (tmp >> 3) & 0x3F; + + /* Handle any leading odd-sized chunks */ + if (dataCount) + { + guchar *p = (guchar *) sha1->data + dataCount; + + dataCount = SHA1_DATASIZE - dataCount; + if (count < dataCount) + { + memcpy (p, buffer, count); + return; + } + + memcpy (p, buffer, dataCount); + + sha_byte_reverse (sha1->data, SHA1_DATASIZE); + sha1_transform (sha1->buf, sha1->data); + + buffer += dataCount; + count -= dataCount; + } + + /* Process data in SHA1_DATASIZE chunks */ + while (count >= SHA1_DATASIZE) + { + memcpy (sha1->data, buffer, SHA1_DATASIZE); + + sha_byte_reverse (sha1->data, SHA1_DATASIZE); + sha1_transform (sha1->buf, sha1->data); + + buffer += SHA1_DATASIZE; + count -= SHA1_DATASIZE; + } + + /* Handle any remaining bytes of data. */ + memcpy (sha1->data, buffer, count); +} + +/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern + 1 0* (64-bit count of bits processed, MSB-first) */ +static void +sha1_sum_close (Sha1sum *sha1) +{ + gint count; + guchar *data_p; + + /* Compute number of bytes mod 64 */ + count = (gint) ((sha1->bits[0] >> 3) & 0x3f); + + /* Set the first char of padding to 0x80. This is safe since there is + always at least one byte free */ + data_p = (guchar *) sha1->data + count; + *data_p++ = 0x80; + + /* Bytes of padding needed to make 64 bytes */ + count = SHA1_DATASIZE - 1 - count; + + /* Pad out to 56 mod 64 */ + if (count < 8) + { + /* Two lots of padding: Pad the first block to 64 bytes */ + memset (data_p, 0, count); + + sha_byte_reverse (sha1->data, SHA1_DATASIZE); + sha1_transform (sha1->buf, sha1->data); + + /* Now fill the next block with 56 bytes */ + memset (sha1->data, 0, SHA1_DATASIZE - 8); + } + else + { + /* Pad block to 56 bytes */ + memset (data_p, 0, count - 8); + } + + /* Append length in bits and transform */ + sha1->data[14] = sha1->bits[1]; + sha1->data[15] = sha1->bits[0]; + + sha_byte_reverse (sha1->data, SHA1_DATASIZE - 8); + sha1_transform (sha1->buf, sha1->data); + sha_byte_reverse (sha1->buf, SHA1_DIGEST_LEN); + + memcpy (sha1->digest, sha1->buf, SHA1_DIGEST_LEN); + + /* Reset buffers in case they contain sensitive data */ + memset (sha1->buf, 0, sizeof (sha1->buf)); + memset (sha1->data, 0, sizeof (sha1->data)); +} + +static gchar * +sha1_sum_to_string (Sha1sum *sha1) +{ + return digest_to_string (sha1->digest, SHA1_DIGEST_LEN); +} + +static void +sha1_sum_digest (Sha1sum *sha1, + guint8 *digest) +{ + gint i; + + for (i = 0; i < SHA1_DIGEST_LEN; i++) + digest[i] = sha1->digest[i]; +} + +/* + * SHA-256 Checksum + */ + +/* adapted from the SHA256 implementation in gsk/src/hash/gskhash.c. + * + * Copyright (C) 2006 Dave Benson + * Released under the terms of the GNU Lesser General Public License + */ + +static void +sha256_sum_init (Sha256sum *sha256) +{ + sha256->buf[0] = 0x6a09e667; + sha256->buf[1] = 0xbb67ae85; + sha256->buf[2] = 0x3c6ef372; + sha256->buf[3] = 0xa54ff53a; + sha256->buf[4] = 0x510e527f; + sha256->buf[5] = 0x9b05688c; + sha256->buf[6] = 0x1f83d9ab; + sha256->buf[7] = 0x5be0cd19; + + sha256->bits[0] = sha256->bits[1] = 0; +} + +#define GET_UINT32(n,b,i) G_STMT_START{ \ + (n) = ((guint32) (b)[(i) ] << 24) \ + | ((guint32) (b)[(i) + 1] << 16) \ + | ((guint32) (b)[(i) + 2] << 8) \ + | ((guint32) (b)[(i) + 3] ); } G_STMT_END + +#define PUT_UINT32(n,b,i) G_STMT_START{ \ + (b)[(i) ] = (guint8) ((n) >> 24); \ + (b)[(i) + 1] = (guint8) ((n) >> 16); \ + (b)[(i) + 2] = (guint8) ((n) >> 8); \ + (b)[(i) + 3] = (guint8) ((n) ); } G_STMT_END + +static void +sha256_transform (guint32 buf[8], + guint8 const data[64]) +{ + guint32 temp1, temp2, W[64]; + guint32 A, B, C, D, E, F, G, H; + + GET_UINT32 (W[0], data, 0); + GET_UINT32 (W[1], data, 4); + GET_UINT32 (W[2], data, 8); + GET_UINT32 (W[3], data, 12); + GET_UINT32 (W[4], data, 16); + GET_UINT32 (W[5], data, 20); + GET_UINT32 (W[6], data, 24); + GET_UINT32 (W[7], data, 28); + GET_UINT32 (W[8], data, 32); + GET_UINT32 (W[9], data, 36); + GET_UINT32 (W[10], data, 40); + GET_UINT32 (W[11], data, 44); + GET_UINT32 (W[12], data, 48); + GET_UINT32 (W[13], data, 52); + GET_UINT32 (W[14], data, 56); + GET_UINT32 (W[15], data, 60); + +#define SHR(x,n) ((x & 0xFFFFFFFF) >> n) +#define ROTR(x,n) (SHR (x,n) | (x << (32 - n))) + +#define S0(x) (ROTR (x, 7) ^ ROTR (x,18) ^ SHR (x, 3)) +#define S1(x) (ROTR (x,17) ^ ROTR (x,19) ^ SHR (x,10)) +#define S2(x) (ROTR (x, 2) ^ ROTR (x,13) ^ ROTR (x,22)) +#define S3(x) (ROTR (x, 6) ^ ROTR (x,11) ^ ROTR (x,25)) + +#define F0(x,y,z) ((x & y) | (z & (x | y))) +#define F1(x,y,z) (z ^ (x & (y ^ z))) + +#define R(t) (W[t] = S1(W[t - 2]) + W[t - 7] + \ + S0(W[t - 15]) + W[t - 16]) + +#define P(a,b,c,d,e,f,g,h,x,K) G_STMT_START { \ + temp1 = h + S3(e) + F1(e,f,g) + K + x; \ + temp2 = S2(a) + F0(a,b,c); \ + d += temp1; h = temp1 + temp2; } G_STMT_END + + A = buf[0]; + B = buf[1]; + C = buf[2]; + D = buf[3]; + E = buf[4]; + F = buf[5]; + G = buf[6]; + H = buf[7]; + + P (A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); + P (H, A, B, C, D, E, F, G, W[ 1], 0x71374491); + P (G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF); + P (F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5); + P (E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B); + P (D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1); + P (C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4); + P (B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5); + P (A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98); + P (H, A, B, C, D, E, F, G, W[ 9], 0x12835B01); + P (G, H, A, B, C, D, E, F, W[10], 0x243185BE); + P (F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); + P (E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); + P (D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); + P (C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); + P (B, C, D, E, F, G, H, A, W[15], 0xC19BF174); + P (A, B, C, D, E, F, G, H, R(16), 0xE49B69C1); + P (H, A, B, C, D, E, F, G, R(17), 0xEFBE4786); + P (G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6); + P (F, G, H, A, B, C, D, E, R(19), 0x240CA1CC); + P (E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F); + P (D, E, F, G, H, A, B, C, R(21), 0x4A7484AA); + P (C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC); + P (B, C, D, E, F, G, H, A, R(23), 0x76F988DA); + P (A, B, C, D, E, F, G, H, R(24), 0x983E5152); + P (H, A, B, C, D, E, F, G, R(25), 0xA831C66D); + P (G, H, A, B, C, D, E, F, R(26), 0xB00327C8); + P (F, G, H, A, B, C, D, E, R(27), 0xBF597FC7); + P (E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3); + P (D, E, F, G, H, A, B, C, R(29), 0xD5A79147); + P (C, D, E, F, G, H, A, B, R(30), 0x06CA6351); + P (B, C, D, E, F, G, H, A, R(31), 0x14292967); + P (A, B, C, D, E, F, G, H, R(32), 0x27B70A85); + P (H, A, B, C, D, E, F, G, R(33), 0x2E1B2138); + P (G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC); + P (F, G, H, A, B, C, D, E, R(35), 0x53380D13); + P (E, F, G, H, A, B, C, D, R(36), 0x650A7354); + P (D, E, F, G, H, A, B, C, R(37), 0x766A0ABB); + P (C, D, E, F, G, H, A, B, R(38), 0x81C2C92E); + P (B, C, D, E, F, G, H, A, R(39), 0x92722C85); + P (A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1); + P (H, A, B, C, D, E, F, G, R(41), 0xA81A664B); + P (G, H, A, B, C, D, E, F, R(42), 0xC24B8B70); + P (F, G, H, A, B, C, D, E, R(43), 0xC76C51A3); + P (E, F, G, H, A, B, C, D, R(44), 0xD192E819); + P (D, E, F, G, H, A, B, C, R(45), 0xD6990624); + P (C, D, E, F, G, H, A, B, R(46), 0xF40E3585); + P (B, C, D, E, F, G, H, A, R(47), 0x106AA070); + P (A, B, C, D, E, F, G, H, R(48), 0x19A4C116); + P (H, A, B, C, D, E, F, G, R(49), 0x1E376C08); + P (G, H, A, B, C, D, E, F, R(50), 0x2748774C); + P (F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5); + P (E, F, G, H, A, B, C, D, R(52), 0x391C0CB3); + P (D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A); + P (C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F); + P (B, C, D, E, F, G, H, A, R(55), 0x682E6FF3); + P (A, B, C, D, E, F, G, H, R(56), 0x748F82EE); + P (H, A, B, C, D, E, F, G, R(57), 0x78A5636F); + P (G, H, A, B, C, D, E, F, R(58), 0x84C87814); + P (F, G, H, A, B, C, D, E, R(59), 0x8CC70208); + P (E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA); + P (D, E, F, G, H, A, B, C, R(61), 0xA4506CEB); + P (C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7); + P (B, C, D, E, F, G, H, A, R(63), 0xC67178F2); + +#undef SHR +#undef ROTR +#undef S0 +#undef S1 +#undef S2 +#undef S3 +#undef F0 +#undef F1 +#undef R +#undef P + + buf[0] += A; + buf[1] += B; + buf[2] += C; + buf[3] += D; + buf[4] += E; + buf[5] += F; + buf[6] += G; + buf[7] += H; +} + +static void +sha256_sum_update (Sha256sum *sha256, + const guchar *buffer, + gsize length) +{ + guint32 left, fill; + const guint8 *input = buffer; + + if (length == 0) + return; + + left = sha256->bits[0] & 0x3F; + fill = 64 - left; + + sha256->bits[0] += length; + sha256->bits[0] &= 0xFFFFFFFF; + + if (sha256->bits[0] < length) + sha256->bits[1]++; + + if (left > 0 && length >= fill) + { + memcpy ((sha256->data + left), input, fill); + + sha256_transform (sha256->buf, sha256->data); + length -= fill; + input += fill; + + left = 0; + } + + while (length >= SHA256_DATASIZE) + { + sha256_transform (sha256->buf, input); + + length -= 64; + input += 64; + } + + if (length) + memcpy (sha256->data + left, input, length); +} + +static guint8 sha256_padding[64] = +{ + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void +sha256_sum_close (Sha256sum *sha256) +{ + guint32 last, padn; + guint32 high, low; + guint8 msglen[8]; + + high = (sha256->bits[0] >> 29) + | (sha256->bits[1] << 3); + low = (sha256->bits[0] << 3); + + PUT_UINT32 (high, msglen, 0); + PUT_UINT32 (low, msglen, 4); + + last = sha256->bits[0] & 0x3F; + padn = (last < 56) ? (56 - last) : (120 - last); + + sha256_sum_update (sha256, sha256_padding, padn); + sha256_sum_update (sha256, msglen, 8); + + PUT_UINT32 (sha256->buf[0], sha256->digest, 0); + PUT_UINT32 (sha256->buf[1], sha256->digest, 4); + PUT_UINT32 (sha256->buf[2], sha256->digest, 8); + PUT_UINT32 (sha256->buf[3], sha256->digest, 12); + PUT_UINT32 (sha256->buf[4], sha256->digest, 16); + PUT_UINT32 (sha256->buf[5], sha256->digest, 20); + PUT_UINT32 (sha256->buf[6], sha256->digest, 24); + PUT_UINT32 (sha256->buf[7], sha256->digest, 28); +} + +#undef PUT_UINT32 +#undef GET_UINT32 + +static gchar * +sha256_sum_to_string (Sha256sum *sha256) +{ + return digest_to_string (sha256->digest, SHA256_DIGEST_LEN); +} + +static void +sha256_sum_digest (Sha256sum *sha256, + guint8 *digest) +{ + gint i; + + for (i = 0; i < SHA256_DIGEST_LEN; i++) + digest[i] = sha256->digest[i]; +} + + +/* + * Public API + */ + +/** + * g_checksum_type_get_length: + * @checksum_type: a #GChecksumType + * + * Gets the length in bytes of digests of type @checksum_type + * + * Return value: the checksum length, or -1 if @checksum_type is + * not supported. + * + * Since: 2.16 + */ +gssize +g_checksum_type_get_length (GChecksumType checksum_type) +{ + gssize len = -1; + + switch (checksum_type) + { + case G_CHECKSUM_MD5: + len = MD5_DIGEST_LEN; + break; + case G_CHECKSUM_SHA1: + len = SHA1_DIGEST_LEN; + break; + case G_CHECKSUM_SHA256: + len = SHA256_DIGEST_LEN; + break; + default: + len = -1; + break; + } + + return len; +} + +/** + * g_checksum_new: + * @checksum_type: the desired type of checksum + * + * Creates a new #GChecksum, using the checksum algorithm @checksum_type. + * If the @checksum_type is not known, %NULL is returned. + * A #GChecksum can be used to compute the checksum, or digest, of an + * arbitrary binary blob, using different hashing algorithms. + * + * A #GChecksum works by feeding a binary blob through g_checksum_update() + * until there is data to be checked; the digest can then be extracted + * using g_checksum_get_string(), which will return the checksum as a + * hexadecimal string; or g_checksum_get_digest(), which will return a + * vector of raw bytes. Once either g_checksum_get_string() or + * g_checksum_get_digest() have been called on a #GChecksum, the checksum + * will be closed and it won't be possible to call g_checksum_update() + * on it anymore. + * + * Return value: the newly created #GChecksum, or %NULL. + * Use g_checksum_free() to free the memory allocated by it. + * + * Since: 2.16 + */ +GChecksum * +g_checksum_new (GChecksumType checksum_type) +{ + GChecksum *checksum; + + if (! IS_VALID_TYPE (checksum_type)) + return NULL; + + checksum = g_slice_new0 (GChecksum); + checksum->type = checksum_type; + + g_checksum_reset (checksum); + + return checksum; +} + +/** + * g_checksum_reset: + * @checksum: the #GChecksum to reset + * + * Resets the state of the @checksum back to its initial state. + * + * Since: 2.18 + **/ +void +g_checksum_reset (GChecksum *checksum) +{ + g_return_if_fail (checksum != NULL); + + g_free (checksum->digest_str); + checksum->digest_str = NULL; + + switch (checksum->type) + { + case G_CHECKSUM_MD5: + md5_sum_init (&(checksum->sum.md5)); + break; + case G_CHECKSUM_SHA1: + sha1_sum_init (&(checksum->sum.sha1)); + break; + case G_CHECKSUM_SHA256: + sha256_sum_init (&(checksum->sum.sha256)); + break; + default: + g_assert_not_reached (); + break; + } +} + +/** + * g_checksum_copy: + * @checksum: the #GChecksum to copy + * + * Copies a #GChecksum. If @checksum has been closed, by calling + * g_checksum_get_string() or g_checksum_get_digest(), the copied + * checksum will be closed as well. + * + * Return value: the copy of the passed #GChecksum. Use g_checksum_free() + * when finished using it. + * + * Since: 2.16 + */ +GChecksum * +g_checksum_copy (const GChecksum *checksum) +{ + GChecksum *copy; + + g_return_val_if_fail (checksum != NULL, NULL); + + copy = g_slice_new (GChecksum); + *copy = *checksum; + + copy->digest_str = g_strdup (checksum->digest_str); + + return copy; +} + +/** + * g_checksum_free: + * @checksum: a #GChecksum + * + * Frees the memory allocated for @checksum. + * + * Since: 2.16 + */ +void +g_checksum_free (GChecksum *checksum) +{ + if (G_LIKELY (checksum)) + { + g_free (checksum->digest_str); + + g_slice_free (GChecksum, checksum); + } +} + +/** + * g_checksum_update: + * @checksum: a #GChecksum + * @data: buffer used to compute the checksum + * @length: size of the buffer, or -1 if it is a null-terminated string. + * + * Feeds @data into an existing #GChecksum. The checksum must still be + * open, that is g_checksum_get_string() or g_checksum_get_digest() must + * not have been called on @checksum. + * + * Since: 2.16 + */ +void +g_checksum_update (GChecksum *checksum, + const guchar *data, + gssize length) +{ + g_return_if_fail (checksum != NULL); + g_return_if_fail (length == 0 || data != NULL); + + if (length < 0) + length = strlen ((const gchar *) data); + + if (checksum->digest_str) + { + g_warning ("The checksum `%s' has been closed and cannot be updated " + "anymore.", + checksum->digest_str); + return; + } + + switch (checksum->type) + { + case G_CHECKSUM_MD5: + md5_sum_update (&(checksum->sum.md5), data, length); + break; + case G_CHECKSUM_SHA1: + sha1_sum_update (&(checksum->sum.sha1), data, length); + break; + case G_CHECKSUM_SHA256: + sha256_sum_update (&(checksum->sum.sha256), data, length); + break; + default: + g_assert_not_reached (); + break; + } +} + +/** + * g_checksum_get_string: + * @checksum: a #GChecksum + * + * Gets the digest as an hexadecimal string. + * + * Once this function has been called the #GChecksum can no longer be + * updated with g_checksum_update(). + * + * The hexadecimal characters will be lower case. + * + * Return value: the hexadecimal representation of the checksum. The + * returned string is owned by the checksum and should not be modified + * or freed. + * + * Since: 2.16 + */ +const gchar * +g_checksum_get_string (GChecksum *checksum) +{ + gchar *str = NULL; + + g_return_val_if_fail (checksum != NULL, NULL); + + if (checksum->digest_str) + return checksum->digest_str; + + switch (checksum->type) + { + case G_CHECKSUM_MD5: + md5_sum_close (&(checksum->sum.md5)); + str = md5_sum_to_string (&(checksum->sum.md5)); + break; + case G_CHECKSUM_SHA1: + sha1_sum_close (&(checksum->sum.sha1)); + str = sha1_sum_to_string (&(checksum->sum.sha1)); + break; + case G_CHECKSUM_SHA256: + sha256_sum_close (&(checksum->sum.sha256)); + str = sha256_sum_to_string (&(checksum->sum.sha256)); + break; + default: + g_assert_not_reached (); + break; + } + + checksum->digest_str = str; + + return checksum->digest_str; +} + +/** + * g_checksum_get_digest: + * @checksum: a #GChecksum + * @buffer: output buffer + * @digest_len: an inout parameter. The caller initializes it to the size of @buffer. + * After the call it contains the length of the digest. + * + * Gets the digest from @checksum as a raw binary vector and places it + * into @buffer. The size of the digest depends on the type of checksum. + * + * Once this function has been called, the #GChecksum is closed and can + * no longer be updated with g_checksum_update(). + * + * Since: 2.16 + */ +void +g_checksum_get_digest (GChecksum *checksum, + guint8 *buffer, + gsize *digest_len) +{ + gboolean checksum_open = FALSE; + gchar *str = NULL; + gsize len; + + g_return_if_fail (checksum != NULL); + + len = g_checksum_type_get_length (checksum->type); + g_return_if_fail (*digest_len >= len); + + checksum_open = !!(checksum->digest_str == NULL); + + switch (checksum->type) + { + case G_CHECKSUM_MD5: + if (checksum_open) + { + md5_sum_close (&(checksum->sum.md5)); + str = md5_sum_to_string (&(checksum->sum.md5)); + } + md5_sum_digest (&(checksum->sum.md5), buffer); + break; + case G_CHECKSUM_SHA1: + if (checksum_open) + { + sha1_sum_close (&(checksum->sum.sha1)); + str = sha1_sum_to_string (&(checksum->sum.sha1)); + } + sha1_sum_digest (&(checksum->sum.sha1), buffer); + break; + case G_CHECKSUM_SHA256: + if (checksum_open) + { + sha256_sum_close (&(checksum->sum.sha256)); + str = sha256_sum_to_string (&(checksum->sum.sha256)); + } + sha256_sum_digest (&(checksum->sum.sha256), buffer); + break; + default: + g_assert_not_reached (); + break; + } + + if (str) + checksum->digest_str = str; + + *digest_len = len; +} + +/** + * g_compute_checksum_for_data: + * @checksum_type: a #GChecksumType + * @data: binary blob to compute the digest of + * @length: length of @data + * + * Computes the checksum for a binary @data of @length. This is a + * convenience wrapper for g_checksum_new(), g_checksum_get_string() + * and g_checksum_free(). + * + * The hexadecimal string returned will be in lower case. + * + * Return value: the digest of the binary data as a string in hexadecimal. + * The returned string should be freed with g_free() when done using it. + * + * Since: 2.16 + */ +gchar * +g_compute_checksum_for_data (GChecksumType checksum_type, + const guchar *data, + gsize length) +{ + GChecksum *checksum; + gchar *retval; + + g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL); + g_return_val_if_fail (length == 0 || data != NULL, NULL); + + checksum = g_checksum_new (checksum_type); + if (!checksum) + return NULL; + + g_checksum_update (checksum, data, length); + retval = g_strdup (g_checksum_get_string (checksum)); + g_checksum_free (checksum); + + return retval; +} + +/** + * g_compute_checksum_for_string: + * @checksum_type: a #GChecksumType + * @str: the string to compute the checksum of + * @length: the length of the string, or -1 if the string is null-terminated. + * + * Computes the checksum of a string. + * + * The hexadecimal string returned will be in lower case. + * + * Return value: the checksum as a hexadecimal string. The returned string + * should be freed with g_free() when done using it. + * + * Since: 2.16 + */ +gchar * +g_compute_checksum_for_string (GChecksumType checksum_type, + const gchar *str, + gssize length) +{ + g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL); + g_return_val_if_fail (length == 0 || str != NULL, NULL); + + if (length < 0) + length = strlen (str); + + return g_compute_checksum_for_data (checksum_type, (const guchar *) str, length); +} diff --git a/glib/glib/gchecksum.h b/glib/glib/gchecksum.h new file mode 100644 index 0000000..69fe1f4 --- /dev/null +++ b/glib/glib/gchecksum.h @@ -0,0 +1,86 @@ +/* gchecksum.h - data hashing functions + * + * Copyright (C) 2007 Emmanuele Bassi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_CHECKSUM_H__ +#define __G_CHECKSUM_H__ + +#include + +G_BEGIN_DECLS + +/** + * GChecksumType: + * @G_CHECKSUM_MD5: Use the MD5 hashing algorithm + * @G_CHECKSUM_SHA1: Use the SHA-1 hashing algorithm + * @G_CHECKSUM_SHA256: Use the SHA-256 hashing algorithm + * + * The hashing algorithm to be used by #GChecksum when performing the + * digest of some data. + * + * Note that the #GChecksumType enumeration may be extended at a later + * date to include new hashing algorithm types. + * + * Since: 2.16 + */ +typedef enum { + G_CHECKSUM_MD5, + G_CHECKSUM_SHA1, + G_CHECKSUM_SHA256 +} GChecksumType; + +/** + * GChecksum: + * + * An opaque structure representing a checksumming operation. + * To create a new GChecksum, use g_checksum_new(). To free + * a GChecksum, use g_checksum_free(). + * + * Since: 2.16 + */ +typedef struct _GChecksum GChecksum; + +gssize g_checksum_type_get_length (GChecksumType checksum_type); + +GChecksum * g_checksum_new (GChecksumType checksum_type); +void g_checksum_reset (GChecksum *checksum); +GChecksum * g_checksum_copy (const GChecksum *checksum); +void g_checksum_free (GChecksum *checksum); +void g_checksum_update (GChecksum *checksum, + const guchar *data, + gssize length); +const gchar * g_checksum_get_string (GChecksum *checksum); +void g_checksum_get_digest (GChecksum *checksum, + guint8 *buffer, + gsize *digest_len); + +gchar *g_compute_checksum_for_data (GChecksumType checksum_type, + const guchar *data, + gsize length); +gchar *g_compute_checksum_for_string (GChecksumType checksum_type, + const gchar *str, + gssize length); + +G_END_DECLS + +#endif /* __G_CHECKSUM_H__ */ diff --git a/glib/glib/gconstructor.h b/glib/glib/gconstructor.h new file mode 100644 index 0000000..c5cff19 --- /dev/null +++ b/glib/glib/gconstructor.h @@ -0,0 +1,91 @@ +/* + If G_HAS_CONSTRUCTORS is true then the compiler support *both* constructors and + destructors, in a sane way, including e.g. on library unload. If not you're on + your own. + + Some compilers need #pragma to handle this, which does not work with macros, + so the way you need to use this is (for constructors): + + #ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA + #pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(my_constructor) + #endif + G_DEFINE_CONSTRUCTOR(my_constructor) + static void my_constructor(void) { + ... + } + +*/ + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) + +#define G_HAS_CONSTRUCTORS 1 + +#define G_DEFINE_CONSTRUCTOR(_func) static void __attribute__((constructor)) _func (void); +#define G_DEFINE_DESTRUCTOR(_func) static void __attribute__((destructor)) _func (void); + +#elif defined (_MSC_VER) && (_MSC_VER >= 1500) +/* Visual studio 2008 and later has _Pragma */ + +#define G_HAS_CONSTRUCTORS 1 + +#define G_DEFINE_CONSTRUCTOR(_func) \ + static void _func(void); \ + static int _func ## _wrapper(void) { _func(); return 0; } \ + __pragma(section(".CRT$XCU",read)) \ + __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _wrapper; + +#define G_DEFINE_DESTRUCTOR(_func) \ + static void _func(void); \ + static int _func ## _constructor(void) { atexit (_func); return 0; } \ + __pragma(section(".CRT$XCU",read)) \ + __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor; + +#elif defined (_MSC_VER) + +#define G_HAS_CONSTRUCTORS 1 + +/* Pre Visual studio 2008 must use #pragma section */ +#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 +#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 + +#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ + section(".CRT$XCU",read) +#define G_DEFINE_CONSTRUCTOR(_func) \ + static void _func(void); \ + static int _func ## _wrapper(void) { _func(); return 0; } \ + __declspec(allocate(".CRT$XCU")) static int (*p)(void) = _func ## _wrapper; + +#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ + section(".CRT$XCU",read) +#define G_DEFINE_DESTRUCTOR(_func) \ + static void _func(void); \ + static int _func ## _constructor(void) { atexit (_func); return 0; } \ + __declspec(allocate(".CRT$XCU")) static int (* _array ## _func)(void) = _func ## _constructor; + +#elif defined(__SUNPRO_C) + +/* This is not tested, but i believe it should work, based on: + * http://opensource.apple.com/source/OpenSSL098/OpenSSL098-35/src/fips/fips_premain.c + */ + +#define G_HAS_CONSTRUCTORS 1 + +#define G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA 1 +#define G_DEFINE_DESTRUCTOR_NEEDS_PRAGMA 1 + +#define G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(_func) \ + init(_func) +#define G_DEFINE_CONSTRUCTOR(_func) \ + static void _func(void); + +#define G_DEFINE_DESTRUCTOR_PRAGMA_ARGS(_func) \ + fini(_func) +#define G_DEFINE_DESTRUCTOR(_func) \ + static void _func(void); + +#else + +/* constructors not supported for this compiler */ + +#endif + diff --git a/glib/glib/gconvert.c b/glib/glib/gconvert.c new file mode 100644 index 0000000..3b2d396 --- /dev/null +++ b/glib/glib/gconvert.c @@ -0,0 +1,2250 @@ +/* GLIB - Library of useful routines for C programming + * + * gconvert.c: Convert between character sets using iconv + * Copyright Red Hat Inc., 2000 + * Authors: Havoc Pennington , Owen Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include "glibconfig.h" + +#ifndef G_OS_WIN32 +#include +#endif +#include +#include +#include +#include + +#ifdef G_OS_WIN32 +#include "win_iconv.c" +#endif + +#ifdef G_PLATFORM_WIN32 +#define STRICT +#include +#undef STRICT +#endif + +#include "gconvert.h" + +#include "gcharset.h" +#include "gslist.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gthread.h" +#include "gunicode.h" +#include "gfileutils.h" + +#ifdef NEED_ICONV_CACHE +#include "glist.h" +#include "ghash.h" +#endif + +#include "glibintl.h" + +#if defined(USE_LIBICONV_GNU) && !defined (_LIBICONV_H) +#error GNU libiconv in use but included iconv.h not from libiconv +#endif +#if !defined(USE_LIBICONV_GNU) && defined (_LIBICONV_H) \ + && !defined (__APPLE_CC__) && !defined (__LP_64__) +#error GNU libiconv not in use but included iconv.h is from libiconv +#endif + + +/** + * SECTION:conversions + * @title: Character Set Conversion + * @short_description: convert strings between different character sets + * + * The g_convert() family of function wraps the functionality of iconv(). In + * addition to pure character set conversions, GLib has functions to deal + * with the extra complications of encodings for file names. + * + * + * File Name Encodings + * + * Historically, Unix has not had a defined encoding for file + * names: a file name is valid as long as it does not have path + * separators in it ("/"). However, displaying file names may + * require conversion: from the character set in which they were + * created, to the character set in which the application + * operates. Consider the Spanish file name + * "Presentación.sxi". If the + * application which created it uses ISO-8859-1 for its encoding, + * + * + * Character: P r e s e n t a c i ó n . s x i + * Hex code: 50 72 65 73 65 6e 74 61 63 69 f3 6e 2e 73 78 69 + * + * + * However, if the application use UTF-8, the actual file name on + * disk would look like this: + * + * + * Character: P r e s e n t a c i ó n . s x i + * Hex code: 50 72 65 73 65 6e 74 61 63 69 c3 b3 6e 2e 73 78 69 + * + * + * Glib uses UTF-8 for its strings, and GUI toolkits like GTK+ + * that use Glib do the same thing. If you get a file name from + * the file system, for example, from readdir(3) or from g_dir_read_name(), + * and you wish to display the file name to the user, you + * will need to convert it into UTF-8. The + * opposite case is when the user types the name of a file he + * wishes to save: the toolkit will give you that string in + * UTF-8 encoding, and you will need to convert it to the + * character set used for file names before you can create the + * file with open(2) or fopen(3). + * + * + * By default, Glib assumes that file names on disk are in UTF-8 + * encoding. This is a valid assumption for file systems which + * were created relatively recently: most applications use UTF-8 + * encoding for their strings, and that is also what they use for + * the file names they create. However, older file systems may + * still contain file names created in "older" encodings, such as + * ISO-8859-1. In this case, for compatibility reasons, you may + * want to instruct Glib to use that particular encoding for file + * names rather than UTF-8. You can do this by specifying the + * encoding for file names in the G_FILENAME_ENCODING + * environment variable. For example, if your installation uses + * ISO-8859-1 for file names, you can put this in your + * ~/.profile: + * + * + * export G_FILENAME_ENCODING=ISO-8859-1 + * + * + * Glib provides the functions g_filename_to_utf8() and + * g_filename_from_utf8() to perform the necessary conversions. These + * functions convert file names from the encoding specified in + * G_FILENAME_ENCODING to UTF-8 and vice-versa. + * illustrates how + * these functions are used to convert between UTF-8 and the + * encoding for file names in the file system. + * + *
+ * Conversion between File Name Encodings + * + *
+ * + * Checklist for Application Writers + * + * This section is a practical summary of the detailed + * description above. You can use this as a checklist of + * things to do to make sure your applications process file + * name encodings correctly. + * + * + * + * If you get a file name from the file system from a function + * such as readdir(3) or gtk_file_chooser_get_filename(), + * you do not need to do any conversion to pass that + * file name to functions like open(2), rename(2), or + * fopen(3) — those are "raw" file names which the file + * system understands. + * + * + * If you need to display a file name, convert it to UTF-8 first by + * using g_filename_to_utf8(). If conversion fails, display a string like + * "Unknown file name". Do not + * convert this string back into the encoding used for file names if you + * wish to pass it to the file system; use the original file name instead. + * For example, the document window of a word processor could display + * "Unknown file name" in its title bar but still let the user save the + * file, as it would keep the raw file name internally. This can happen + * if the user has not set the G_FILENAME_ENCODING + * environment variable even though he has files whose names are not + * encoded in UTF-8. + * + * + * If your user interface lets the user type a file name for saving or + * renaming, convert it to the encoding used for file names in the file + * system by using g_filename_from_utf8(). Pass the converted file name + * to functions like fopen(3). If conversion fails, ask the user to enter + * a different file name. This can happen if the user types Japanese + * characters when G_FILENAME_ENCODING is set to + * ISO-8859-1, for example. + * + * + * + *
+ */ + +/* We try to terminate strings in unknown charsets with this many zero bytes + * to ensure that multibyte strings really are nul-terminated when we return + * them from g_convert() and friends. + */ +#define NUL_TERMINATOR_LENGTH 4 + +GQuark +g_convert_error_quark (void) +{ + return g_quark_from_static_string ("g_convert_error"); +} + +static gboolean +try_conversion (const char *to_codeset, + const char *from_codeset, + iconv_t *cd) +{ + *cd = iconv_open (to_codeset, from_codeset); + + if (*cd == (iconv_t)-1 && errno == EINVAL) + return FALSE; + else + return TRUE; +} + +static gboolean +try_to_aliases (const char **to_aliases, + const char *from_codeset, + iconv_t *cd) +{ + if (to_aliases) + { + const char **p = to_aliases; + while (*p) + { + if (try_conversion (*p, from_codeset, cd)) + return TRUE; + + p++; + } + } + + return FALSE; +} + +G_GNUC_INTERNAL extern const char ** +_g_charset_get_aliases (const char *canonical_name); + +/** + * g_iconv_open: + * @to_codeset: destination codeset + * @from_codeset: source codeset + * + * Same as the standard UNIX routine iconv_open(), but + * may be implemented via libiconv on UNIX flavors that lack + * a native implementation. + * + * GLib provides g_convert() and g_locale_to_utf8() which are likely + * more convenient than the raw iconv wrappers. + * + * Return value: a "conversion descriptor", or (GIConv)-1 if + * opening the converter failed. + **/ +GIConv +g_iconv_open (const gchar *to_codeset, + const gchar *from_codeset) +{ + iconv_t cd; + + if (!try_conversion (to_codeset, from_codeset, &cd)) + { + const char **to_aliases = _g_charset_get_aliases (to_codeset); + const char **from_aliases = _g_charset_get_aliases (from_codeset); + + if (from_aliases) + { + const char **p = from_aliases; + while (*p) + { + if (try_conversion (to_codeset, *p, &cd)) + goto out; + + if (try_to_aliases (to_aliases, *p, &cd)) + goto out; + + p++; + } + } + + if (try_to_aliases (to_aliases, from_codeset, &cd)) + goto out; + } + + out: + return (cd == (iconv_t)-1) ? (GIConv)-1 : (GIConv)cd; +} + +/** + * g_iconv: + * @converter: conversion descriptor from g_iconv_open() + * @inbuf: bytes to convert + * @inbytes_left: inout parameter, bytes remaining to convert in @inbuf + * @outbuf: converted output bytes + * @outbytes_left: inout parameter, bytes available to fill in @outbuf + * + * Same as the standard UNIX routine iconv(), but + * may be implemented via libiconv on UNIX flavors that lack + * a native implementation. + * + * GLib provides g_convert() and g_locale_to_utf8() which are likely + * more convenient than the raw iconv wrappers. + * + * Return value: count of non-reversible conversions, or -1 on error + **/ +gsize +g_iconv (GIConv converter, + gchar **inbuf, + gsize *inbytes_left, + gchar **outbuf, + gsize *outbytes_left) +{ + iconv_t cd = (iconv_t)converter; + + return iconv (cd, inbuf, inbytes_left, outbuf, outbytes_left); +} + +/** + * g_iconv_close: + * @converter: a conversion descriptor from g_iconv_open() + * + * Same as the standard UNIX routine iconv_close(), but + * may be implemented via libiconv on UNIX flavors that lack + * a native implementation. Should be called to clean up + * the conversion descriptor from g_iconv_open() when + * you are done converting things. + * + * GLib provides g_convert() and g_locale_to_utf8() which are likely + * more convenient than the raw iconv wrappers. + * + * Return value: -1 on error, 0 on success + **/ +gint +g_iconv_close (GIConv converter) +{ + iconv_t cd = (iconv_t)converter; + + return iconv_close (cd); +} + + +#ifdef NEED_ICONV_CACHE + +#define ICONV_CACHE_SIZE (16) + +struct _iconv_cache_bucket { + gchar *key; + guint32 refcount; + gboolean used; + GIConv cd; +}; + +static GList *iconv_cache_list; +static GHashTable *iconv_cache; +static GHashTable *iconv_open_hash; +static guint iconv_cache_size = 0; +G_LOCK_DEFINE_STATIC (iconv_cache_lock); + +/* caller *must* hold the iconv_cache_lock */ +static void +iconv_cache_init (void) +{ + static gboolean initialized = FALSE; + + if (initialized) + return; + + iconv_cache_list = NULL; + iconv_cache = g_hash_table_new (g_str_hash, g_str_equal); + iconv_open_hash = g_hash_table_new (g_direct_hash, g_direct_equal); + + initialized = TRUE; +} + + +/* + * iconv_cache_bucket_new: + * @key: cache key + * @cd: iconv descriptor + * + * Creates a new cache bucket, inserts it into the cache and + * increments the cache size. + * + * This assumes ownership of @key. + * + * Returns a pointer to the newly allocated cache bucket. + **/ +static struct _iconv_cache_bucket * +iconv_cache_bucket_new (gchar *key, GIConv cd) +{ + struct _iconv_cache_bucket *bucket; + + bucket = g_new (struct _iconv_cache_bucket, 1); + bucket->key = key; + bucket->refcount = 1; + bucket->used = TRUE; + bucket->cd = cd; + + g_hash_table_insert (iconv_cache, bucket->key, bucket); + + /* FIXME: if we sorted the list so items with few refcounts were + first, then we could expire them faster in iconv_cache_expire_unused () */ + iconv_cache_list = g_list_prepend (iconv_cache_list, bucket); + + iconv_cache_size++; + + return bucket; +} + + +/* + * iconv_cache_bucket_expire: + * @node: cache bucket's node + * @bucket: cache bucket + * + * Expires a single cache bucket @bucket. This should only ever be + * called on a bucket that currently has no used iconv descriptors + * open. + * + * @node is not a required argument. If @node is not supplied, we + * search for it ourselves. + **/ +static void +iconv_cache_bucket_expire (GList *node, struct _iconv_cache_bucket *bucket) +{ + g_hash_table_remove (iconv_cache, bucket->key); + + if (node == NULL) + node = g_list_find (iconv_cache_list, bucket); + + g_assert (node != NULL); + + if (node->prev) + { + node->prev->next = node->next; + if (node->next) + node->next->prev = node->prev; + } + else + { + iconv_cache_list = node->next; + if (node->next) + node->next->prev = NULL; + } + + g_list_free_1 (node); + + g_free (bucket->key); + g_iconv_close (bucket->cd); + g_free (bucket); + + iconv_cache_size--; +} + + +/* + * iconv_cache_expire_unused: + * + * Expires as many unused cache buckets as it needs to in order to get + * the total number of buckets < ICONV_CACHE_SIZE. + **/ +static void +iconv_cache_expire_unused (void) +{ + struct _iconv_cache_bucket *bucket; + GList *node, *next; + + node = iconv_cache_list; + while (node && iconv_cache_size >= ICONV_CACHE_SIZE) + { + next = node->next; + + bucket = node->data; + if (bucket->refcount == 0) + iconv_cache_bucket_expire (node, bucket); + + node = next; + } +} + +static GIConv +open_converter (const gchar *to_codeset, + const gchar *from_codeset, + GError **error) +{ + struct _iconv_cache_bucket *bucket; + gchar *key, *dyn_key, auto_key[80]; + GIConv cd; + gsize len_from_codeset, len_to_codeset; + + /* create our key */ + len_from_codeset = strlen (from_codeset); + len_to_codeset = strlen (to_codeset); + if (len_from_codeset + len_to_codeset + 2 < sizeof (auto_key)) + { + key = auto_key; + dyn_key = NULL; + } + else + key = dyn_key = g_malloc (len_from_codeset + len_to_codeset + 2); + memcpy (key, from_codeset, len_from_codeset); + key[len_from_codeset] = ':'; + strcpy (key + len_from_codeset + 1, to_codeset); + + G_LOCK (iconv_cache_lock); + + /* make sure the cache has been initialized */ + iconv_cache_init (); + + bucket = g_hash_table_lookup (iconv_cache, key); + if (bucket) + { + g_free (dyn_key); + + if (bucket->used) + { + cd = g_iconv_open (to_codeset, from_codeset); + if (cd == (GIConv) -1) + goto error; + } + else + { + /* Apparently iconv on Solaris <= 7 segfaults if you pass in + * NULL for anything but inbuf; work around that. (NULL outbuf + * or NULL *outbuf is allowed by Unix98.) + */ + gsize inbytes_left = 0; + gchar *outbuf = NULL; + gsize outbytes_left = 0; + + cd = bucket->cd; + bucket->used = TRUE; + + /* reset the descriptor */ + g_iconv (cd, NULL, &inbytes_left, &outbuf, &outbytes_left); + } + + bucket->refcount++; + } + else + { + cd = g_iconv_open (to_codeset, from_codeset); + if (cd == (GIConv) -1) + { + g_free (dyn_key); + goto error; + } + + iconv_cache_expire_unused (); + + bucket = iconv_cache_bucket_new (dyn_key ? dyn_key : g_strdup (key), cd); + } + + g_hash_table_insert (iconv_open_hash, cd, bucket->key); + + G_UNLOCK (iconv_cache_lock); + + return cd; + + error: + + G_UNLOCK (iconv_cache_lock); + + /* Something went wrong. */ + if (error) + { + if (errno == EINVAL) + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION, + _("Conversion from character set '%s' to '%s' is not supported"), + from_codeset, to_codeset); + else + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Could not open converter from '%s' to '%s'"), + from_codeset, to_codeset); + } + + return cd; +} + +static int +close_converter (GIConv converter) +{ + struct _iconv_cache_bucket *bucket; + const gchar *key; + GIConv cd; + + cd = converter; + + if (cd == (GIConv) -1) + return 0; + + G_LOCK (iconv_cache_lock); + + key = g_hash_table_lookup (iconv_open_hash, cd); + if (key) + { + g_hash_table_remove (iconv_open_hash, cd); + + bucket = g_hash_table_lookup (iconv_cache, key); + g_assert (bucket); + + bucket->refcount--; + + if (cd == bucket->cd) + bucket->used = FALSE; + else + g_iconv_close (cd); + + if (!bucket->refcount && iconv_cache_size > ICONV_CACHE_SIZE) + { + /* expire this cache bucket */ + iconv_cache_bucket_expire (NULL, bucket); + } + } + else + { + G_UNLOCK (iconv_cache_lock); + + g_warning ("This iconv context wasn't opened using open_converter"); + + return g_iconv_close (converter); + } + + G_UNLOCK (iconv_cache_lock); + + return 0; +} + +#else /* !NEED_ICONV_CACHE */ + +static GIConv +open_converter (const gchar *to_codeset, + const gchar *from_codeset, + GError **error) +{ + GIConv cd; + + cd = g_iconv_open (to_codeset, from_codeset); + + if (cd == (GIConv) -1) + { + /* Something went wrong. */ + if (error) + { + if (errno == EINVAL) + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION, + _("Conversion from character set '%s' to '%s' is not supported"), + from_codeset, to_codeset); + else + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Could not open converter from '%s' to '%s'"), + from_codeset, to_codeset); + } + } + + return cd; +} + +static int +close_converter (GIConv cd) +{ + if (cd == (GIConv) -1) + return 0; + + return g_iconv_close (cd); +} + +#endif /* NEED_ICONV_CACHE */ + +/** + * g_convert_with_iconv: + * @str: the string to convert + * @len: the length of the string, or -1 if the string is + * nul-terminated. + * @converter: conversion descriptor from g_iconv_open() + * @bytes_read: location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will the byte offset after the last valid + * input sequence. + * @bytes_written: the number of bytes stored in the output buffer (not + * including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from one character set to another. + * + * Note that you should use g_iconv() for streaming + * conversions + * + * Despite the fact that @byes_read can return information about partial + * characters, the g_convert_... functions + * are not generally suitable for streaming. If the underlying converter + * being used maintains internal state, then this won't be preserved + * across successive calls to g_convert(), g_convert_with_iconv() or + * g_convert_with_fallback(). (An example of this is the GNU C converter + * for CP1255 which does not emit a base character until it knows that + * the next character is not a mark that could combine with the base + * character.) + * + * . + * + * Return value: If the conversion was successful, a newly allocated + * nul-terminated string, which must be freed with + * g_free(). Otherwise %NULL and @error will be set. + **/ +gchar* +g_convert_with_iconv (const gchar *str, + gssize len, + GIConv converter, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + gchar *dest; + gchar *outp; + const gchar *p; + gsize inbytes_remaining; + gsize outbytes_remaining; + gsize err; + gsize outbuf_size; + gboolean have_error = FALSE; + gboolean done = FALSE; + gboolean reset = FALSE; + + g_return_val_if_fail (converter != (GIConv) -1, NULL); + + if (len < 0) + len = strlen (str); + + p = str; + inbytes_remaining = len; + outbuf_size = len + NUL_TERMINATOR_LENGTH; + + outbytes_remaining = outbuf_size - NUL_TERMINATOR_LENGTH; + outp = dest = g_malloc (outbuf_size); + + while (!done && !have_error) + { + if (reset) + err = g_iconv (converter, NULL, &inbytes_remaining, &outp, &outbytes_remaining); + else + err = g_iconv (converter, (char **)&p, &inbytes_remaining, &outp, &outbytes_remaining); + + if (err == (gsize) -1) + { + switch (errno) + { + case EINVAL: + /* Incomplete text, do not report an error */ + done = TRUE; + break; + case E2BIG: + { + gsize used = outp - dest; + + outbuf_size *= 2; + dest = g_realloc (dest, outbuf_size); + + outp = dest + used; + outbytes_remaining = outbuf_size - used - NUL_TERMINATOR_LENGTH; + } + break; + case EILSEQ: + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + have_error = TRUE; + break; + default: + { + int errsv = errno; + + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Error during conversion: %s"), + g_strerror (errsv)); + } + have_error = TRUE; + break; + } + } + else + { + if (!reset) + { + /* call g_iconv with NULL inbuf to cleanup shift state */ + reset = TRUE; + inbytes_remaining = 0; + } + else + done = TRUE; + } + } + + memset (outp, 0, NUL_TERMINATOR_LENGTH); + + if (bytes_read) + *bytes_read = p - str; + else + { + if ((p - str) != len) + { + if (!have_error) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + _("Partial character sequence at end of input")); + have_error = TRUE; + } + } + } + + if (bytes_written) + *bytes_written = outp - dest; /* Doesn't include '\0' */ + + if (have_error) + { + g_free (dest); + return NULL; + } + else + return dest; +} + +/** + * g_convert: + * @str: the string to convert + * @len: the length of the string, or -1 if the string is + * nul-terminated + + Note that some encodings may allow nul bytes to + occur inside strings. In that case, using -1 for + the @len parameter is unsafe. + + . + * @to_codeset: name of character set into which to convert @str + * @from_codeset: character set of @str. + * @bytes_read: (out): location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will the byte offset after the last valid + * input sequence. + * @bytes_written: (out): the number of bytes stored in the output buffer (not + * including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from one character set to another. + * + * Note that you should use g_iconv() for streaming + * conversions. + * + * Return value: If the conversion was successful, a newly allocated + * nul-terminated string, which must be freed with + * g_free(). Otherwise %NULL and @error will be set. + **/ +gchar* +g_convert (const gchar *str, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + gchar *res; + GIConv cd; + + g_return_val_if_fail (str != NULL, NULL); + g_return_val_if_fail (to_codeset != NULL, NULL); + g_return_val_if_fail (from_codeset != NULL, NULL); + + cd = open_converter (to_codeset, from_codeset, error); + + if (cd == (GIConv) -1) + { + if (bytes_read) + *bytes_read = 0; + + if (bytes_written) + *bytes_written = 0; + + return NULL; + } + + res = g_convert_with_iconv (str, len, cd, + bytes_read, bytes_written, + error); + + close_converter (cd); + + return res; +} + +/** + * g_convert_with_fallback: + * @str: the string to convert + * @len: the length of the string, or -1 if the string is + * nul-terminated. + * @to_codeset: name of character set into which to convert @str + * @from_codeset: character set of @str. + * @fallback: UTF-8 string to use in place of character not + * present in the target encoding. (The string must be + * representable in the target encoding). + If %NULL, characters not in the target encoding will + be represented as Unicode escapes \uxxxx or \Uxxxxyyyy. + * @bytes_read: location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. + * @bytes_written: the number of bytes stored in the output buffer (not + * including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from one character set to another, possibly + * including fallback sequences for characters not representable + * in the output. Note that it is not guaranteed that the specification + * for the fallback sequences in @fallback will be honored. Some + * systems may do an approximate conversion from @from_codeset + * to @to_codeset in their iconv() functions, + * in which case GLib will simply return that approximate conversion. + * + * Note that you should use g_iconv() for streaming + * conversions. + * + * Return value: If the conversion was successful, a newly allocated + * nul-terminated string, which must be freed with + * g_free(). Otherwise %NULL and @error will be set. + **/ +gchar* +g_convert_with_fallback (const gchar *str, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + const gchar *fallback, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + gchar *utf8; + gchar *dest; + gchar *outp; + const gchar *insert_str = NULL; + const gchar *p; + gsize inbytes_remaining; + const gchar *save_p = NULL; + gsize save_inbytes = 0; + gsize outbytes_remaining; + gsize err; + GIConv cd; + gsize outbuf_size; + gboolean have_error = FALSE; + gboolean done = FALSE; + + GError *local_error = NULL; + + g_return_val_if_fail (str != NULL, NULL); + g_return_val_if_fail (to_codeset != NULL, NULL); + g_return_val_if_fail (from_codeset != NULL, NULL); + + if (len < 0) + len = strlen (str); + + /* Try an exact conversion; we only proceed if this fails + * due to an illegal sequence in the input string. + */ + dest = g_convert (str, len, to_codeset, from_codeset, + bytes_read, bytes_written, &local_error); + if (!local_error) + return dest; + + if (!g_error_matches (local_error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE)) + { + g_propagate_error (error, local_error); + return NULL; + } + else + g_error_free (local_error); + + local_error = NULL; + + /* No go; to proceed, we need a converter from "UTF-8" to + * to_codeset, and the string as UTF-8. + */ + cd = open_converter (to_codeset, "UTF-8", error); + if (cd == (GIConv) -1) + { + if (bytes_read) + *bytes_read = 0; + + if (bytes_written) + *bytes_written = 0; + + return NULL; + } + + utf8 = g_convert (str, len, "UTF-8", from_codeset, + bytes_read, &inbytes_remaining, error); + if (!utf8) + { + close_converter (cd); + if (bytes_written) + *bytes_written = 0; + return NULL; + } + + /* Now the heart of the code. We loop through the UTF-8 string, and + * whenever we hit an offending character, we form fallback, convert + * the fallback to the target codeset, and then go back to + * converting the original string after finishing with the fallback. + * + * The variables save_p and save_inbytes store the input state + * for the original string while we are converting the fallback + */ + p = utf8; + + outbuf_size = len + NUL_TERMINATOR_LENGTH; + outbytes_remaining = outbuf_size - NUL_TERMINATOR_LENGTH; + outp = dest = g_malloc (outbuf_size); + + while (!done && !have_error) + { + gsize inbytes_tmp = inbytes_remaining; + err = g_iconv (cd, (char **)&p, &inbytes_tmp, &outp, &outbytes_remaining); + inbytes_remaining = inbytes_tmp; + + if (err == (gsize) -1) + { + switch (errno) + { + case EINVAL: + g_assert_not_reached(); + break; + case E2BIG: + { + gsize used = outp - dest; + + outbuf_size *= 2; + dest = g_realloc (dest, outbuf_size); + + outp = dest + used; + outbytes_remaining = outbuf_size - used - NUL_TERMINATOR_LENGTH; + + break; + } + case EILSEQ: + if (save_p) + { + /* Error converting fallback string - fatal + */ + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Cannot convert fallback '%s' to codeset '%s'"), + insert_str, to_codeset); + have_error = TRUE; + break; + } + else if (p) + { + if (!fallback) + { + gunichar ch = g_utf8_get_char (p); + insert_str = g_strdup_printf (ch < 0x10000 ? "\\u%04x" : "\\U%08x", + ch); + } + else + insert_str = fallback; + + save_p = g_utf8_next_char (p); + save_inbytes = inbytes_remaining - (save_p - p); + p = insert_str; + inbytes_remaining = strlen (p); + break; + } + /* fall thru if p is NULL */ + default: + { + int errsv = errno; + + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Error during conversion: %s"), + g_strerror (errsv)); + } + + have_error = TRUE; + break; + } + } + else + { + if (save_p) + { + if (!fallback) + g_free ((gchar *)insert_str); + p = save_p; + inbytes_remaining = save_inbytes; + save_p = NULL; + } + else if (p) + { + /* call g_iconv with NULL inbuf to cleanup shift state */ + p = NULL; + inbytes_remaining = 0; + } + else + done = TRUE; + } + } + + /* Cleanup + */ + memset (outp, 0, NUL_TERMINATOR_LENGTH); + + close_converter (cd); + + if (bytes_written) + *bytes_written = outp - dest; /* Doesn't include '\0' */ + + g_free (utf8); + + if (have_error) + { + if (save_p && !fallback) + g_free ((gchar *)insert_str); + g_free (dest); + return NULL; + } + else + return dest; +} + +/* + * g_locale_to_utf8 + * + * + */ + +static gchar * +strdup_len (const gchar *string, + gssize len, + gsize *bytes_written, + gsize *bytes_read, + GError **error) + +{ + gsize real_len; + + if (!g_utf8_validate (string, len, NULL)) + { + if (bytes_read) + *bytes_read = 0; + if (bytes_written) + *bytes_written = 0; + + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + return NULL; + } + + if (len < 0) + real_len = strlen (string); + else + { + real_len = 0; + + while (real_len < len && string[real_len]) + real_len++; + } + + if (bytes_read) + *bytes_read = real_len; + if (bytes_written) + *bytes_written = real_len; + + return g_strndup (string, real_len); +} + +/** + * g_locale_to_utf8: + * @opsysstring: a string in the encoding of the current locale. On Windows + * this means the system codepage. + * @len: the length of the string, or -1 if the string is + * nul-terminated. + * @bytes_read: location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will the byte offset after the last valid + * input sequence. + * @bytes_written: the number of bytes stored in the output buffer (not + * including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string which is in the encoding used for strings by + * the C runtime (usually the same as that used by the operating + * system) in the current locale into a + * UTF-8 string. + * + * Return value: The converted string, or %NULL on an error. + **/ +gchar * +g_locale_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const char *charset; + + if (g_get_charset (&charset)) + return strdup_len (opsysstring, len, bytes_read, bytes_written, error); + else + return g_convert (opsysstring, len, + "UTF-8", charset, bytes_read, bytes_written, error); +} + +/** + * g_locale_from_utf8: + * @utf8string: a UTF-8 encoded string + * @len: the length of the string, or -1 if the string is + * nul-terminated. + * @bytes_read: location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will the byte offset after the last valid + * input sequence. + * @bytes_written: the number of bytes stored in the output buffer (not + * including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from UTF-8 to the encoding used for strings by + * the C runtime (usually the same as that used by the operating + * system) in the current locale. On + * Windows this means the system codepage. + * + * Return value: The converted string, or %NULL on an error. + **/ +gchar * +g_locale_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const gchar *charset; + + if (g_get_charset (&charset)) + return strdup_len (utf8string, len, bytes_read, bytes_written, error); + else + return g_convert (utf8string, len, + charset, "UTF-8", bytes_read, bytes_written, error); +} + +#ifndef G_PLATFORM_WIN32 + +typedef struct _GFilenameCharsetCache GFilenameCharsetCache; + +struct _GFilenameCharsetCache { + gboolean is_utf8; + gchar *charset; + gchar **filename_charsets; +}; + +static void +filename_charset_cache_free (gpointer data) +{ + GFilenameCharsetCache *cache = data; + g_free (cache->charset); + g_strfreev (cache->filename_charsets); + g_free (cache); +} + +/** + * g_get_filename_charsets: + * @charsets: return location for the %NULL-terminated list of encoding names + * + * Determines the preferred character sets used for filenames. + * The first character set from the @charsets is the filename encoding, the + * subsequent character sets are used when trying to generate a displayable + * representation of a filename, see g_filename_display_name(). + * + * On Unix, the character sets are determined by consulting the + * environment variables G_FILENAME_ENCODING and + * G_BROKEN_FILENAMES. On Windows, the character set + * used in the GLib API is always UTF-8 and said environment variables + * have no effect. + * + * G_FILENAME_ENCODING may be set to a comma-separated list + * of character set names. The special token "@locale" is taken to + * mean the character set for the current + * locale. If G_FILENAME_ENCODING is not set, but + * G_BROKEN_FILENAMES is, the character set of the current + * locale is taken as the filename encoding. If neither environment variable + * is set, UTF-8 is taken as the filename encoding, but the character + * set of the current locale is also put in the list of encodings. + * + * The returned @charsets belong to GLib and must not be freed. + * + * Note that on Unix, regardless of the locale character set or + * G_FILENAME_ENCODING value, the actual file names present + * on a system might be in any random encoding or just gibberish. + * + * Return value: %TRUE if the filename encoding is UTF-8. + * + * Since: 2.6 + */ +gboolean +g_get_filename_charsets (const gchar ***filename_charsets) +{ + static GPrivate cache_private = G_PRIVATE_INIT (filename_charset_cache_free); + GFilenameCharsetCache *cache = g_private_get (&cache_private); + const gchar *charset; + + if (!cache) + { + cache = g_new0 (GFilenameCharsetCache, 1); + g_private_set (&cache_private, cache); + } + + g_get_charset (&charset); + + if (!(cache->charset && strcmp (cache->charset, charset) == 0)) + { + const gchar *new_charset; + gchar *p; + gint i; + + g_free (cache->charset); + g_strfreev (cache->filename_charsets); + cache->charset = g_strdup (charset); + + p = getenv ("G_FILENAME_ENCODING"); + if (p != NULL && p[0] != '\0') + { + cache->filename_charsets = g_strsplit (p, ",", 0); + cache->is_utf8 = (strcmp (cache->filename_charsets[0], "UTF-8") == 0); + + for (i = 0; cache->filename_charsets[i]; i++) + { + if (strcmp ("@locale", cache->filename_charsets[i]) == 0) + { + g_get_charset (&new_charset); + g_free (cache->filename_charsets[i]); + cache->filename_charsets[i] = g_strdup (new_charset); + } + } + } + else if (getenv ("G_BROKEN_FILENAMES") != NULL) + { + cache->filename_charsets = g_new0 (gchar *, 2); + cache->is_utf8 = g_get_charset (&new_charset); + cache->filename_charsets[0] = g_strdup (new_charset); + } + else + { + cache->filename_charsets = g_new0 (gchar *, 3); + cache->is_utf8 = TRUE; + cache->filename_charsets[0] = g_strdup ("UTF-8"); + if (!g_get_charset (&new_charset)) + cache->filename_charsets[1] = g_strdup (new_charset); + } + } + + if (filename_charsets) + *filename_charsets = (const gchar **)cache->filename_charsets; + + return cache->is_utf8; +} + +#else /* G_PLATFORM_WIN32 */ + +gboolean +g_get_filename_charsets (const gchar ***filename_charsets) +{ + static const gchar *charsets[] = { + "UTF-8", + NULL + }; + +#ifdef G_OS_WIN32 + /* On Windows GLib pretends that the filename charset is UTF-8 */ + if (filename_charsets) + *filename_charsets = charsets; + + return TRUE; +#else + gboolean result; + + /* Cygwin works like before */ + result = g_get_charset (&(charsets[0])); + + if (filename_charsets) + *filename_charsets = charsets; + + return result; +#endif +} + +#endif /* G_PLATFORM_WIN32 */ + +static gboolean +get_filename_charset (const gchar **filename_charset) +{ + const gchar **charsets; + gboolean is_utf8; + + is_utf8 = g_get_filename_charsets (&charsets); + + if (filename_charset) + *filename_charset = charsets[0]; + + return is_utf8; +} + +/** + * g_filename_to_utf8: + * @opsysstring: a string in the encoding for filenames + * @len: the length of the string, or -1 if the string is + * nul-terminated. + * @bytes_read: location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will the byte offset after the last valid + * input sequence. + * @bytes_written: the number of bytes stored in the output buffer (not + * including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string which is in the encoding used by GLib for + * filenames into a UTF-8 string. Note that on Windows GLib uses UTF-8 + * for filenames; on other platforms, this function indirectly depends on + * the current locale. + * + * Return value: The converted string, or %NULL on an error. + **/ +gchar* +g_filename_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const gchar *charset; + + g_return_val_if_fail (opsysstring != NULL, NULL); + + if (get_filename_charset (&charset)) + return strdup_len (opsysstring, len, bytes_read, bytes_written, error); + else + return g_convert (opsysstring, len, + "UTF-8", charset, bytes_read, bytes_written, error); +} + +#if defined (G_OS_WIN32) && !defined (_WIN64) + +#undef g_filename_to_utf8 + +/* Binary compatibility version. Not for newly compiled code. Also not needed for + * 64-bit versions as there should be no old deployed binaries that would use + * the old versions. + */ + +gchar* +g_filename_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const gchar *charset; + + g_return_val_if_fail (opsysstring != NULL, NULL); + + if (g_get_charset (&charset)) + return strdup_len (opsysstring, len, bytes_read, bytes_written, error); + else + return g_convert (opsysstring, len, + "UTF-8", charset, bytes_read, bytes_written, error); +} + +#endif + +/** + * g_filename_from_utf8: + * @utf8string: a UTF-8 encoded string. + * @len: the length of the string, or -1 if the string is + * nul-terminated. + * @bytes_read: location to store the number of bytes in the + * input string that were successfully converted, or %NULL. + * Even if the conversion was successful, this may be + * less than @len if there were partial characters + * at the end of the input. If the error + * #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value + * stored will the byte offset after the last valid + * input sequence. + * @bytes_written: the number of bytes stored in the output buffer (not + * including the terminating nul). + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts a string from UTF-8 to the encoding GLib uses for + * filenames. Note that on Windows GLib uses UTF-8 for filenames; + * on other platforms, this function indirectly depends on the + * current locale. + * + * Return value: The converted string, or %NULL on an error. + **/ +gchar* +g_filename_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const gchar *charset; + + if (get_filename_charset (&charset)) + return strdup_len (utf8string, len, bytes_read, bytes_written, error); + else + return g_convert (utf8string, len, + charset, "UTF-8", bytes_read, bytes_written, error); +} + +#if defined (G_OS_WIN32) && !defined (_WIN64) + +#undef g_filename_from_utf8 + +/* Binary compatibility version. Not for newly compiled code. */ + +gchar* +g_filename_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) +{ + const gchar *charset; + + if (g_get_charset (&charset)) + return strdup_len (utf8string, len, bytes_read, bytes_written, error); + else + return g_convert (utf8string, len, + charset, "UTF-8", bytes_read, bytes_written, error); +} + +#endif + +/* Test of haystack has the needle prefix, comparing case + * insensitive. haystack may be UTF-8, but needle must + * contain only ascii. */ +static gboolean +has_case_prefix (const gchar *haystack, const gchar *needle) +{ + const gchar *h, *n; + + /* Eat one character at a time. */ + h = haystack; + n = needle; + + while (*n && *h && + g_ascii_tolower (*n) == g_ascii_tolower (*h)) + { + n++; + h++; + } + + return *n == '\0'; +} + +typedef enum { + UNSAFE_ALL = 0x1, /* Escape all unsafe characters */ + UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */ + UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */ + UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */ + UNSAFE_SLASHES = 0x20 /* Allows all characters except for '/' and '%' */ +} UnsafeCharacterSet; + +static const guchar acceptable[96] = { + /* A table of the ASCII chars from space (32) to DEL (127) */ + /* ! " # $ % & ' ( ) * + , - . / */ + 0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C, + /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20, + /* @ A B C D E F G H I J K L M N O */ + 0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + /* P Q R S T U V W X Y Z [ \ ] ^ _ */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F, + /* ` a b c d e f g h i j k l m n o */ + 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, + /* p q r s t u v w x y z { | } ~ DEL */ + 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20 +}; + +static const gchar hex[16] = "0123456789ABCDEF"; + +/* Note: This escape function works on file: URIs, but if you want to + * escape something else, please read RFC-2396 */ +static gchar * +g_escape_uri_string (const gchar *string, + UnsafeCharacterSet mask) +{ +#define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask)) + + const gchar *p; + gchar *q; + gchar *result; + int c; + gint unacceptable; + UnsafeCharacterSet use_mask; + + g_return_val_if_fail (mask == UNSAFE_ALL + || mask == UNSAFE_ALLOW_PLUS + || mask == UNSAFE_PATH + || mask == UNSAFE_HOST + || mask == UNSAFE_SLASHES, NULL); + + unacceptable = 0; + use_mask = mask; + for (p = string; *p != '\0'; p++) + { + c = (guchar) *p; + if (!ACCEPTABLE (c)) + unacceptable++; + } + + result = g_malloc (p - string + unacceptable * 2 + 1); + + use_mask = mask; + for (q = result, p = string; *p != '\0'; p++) + { + c = (guchar) *p; + + if (!ACCEPTABLE (c)) + { + *q++ = '%'; /* means hex coming */ + *q++ = hex[c >> 4]; + *q++ = hex[c & 15]; + } + else + *q++ = *p; + } + + *q = '\0'; + + return result; +} + + +static gchar * +g_escape_file_uri (const gchar *hostname, + const gchar *pathname) +{ + char *escaped_hostname = NULL; + char *escaped_path; + char *res; + +#ifdef G_OS_WIN32 + char *p, *backslash; + + /* Turn backslashes into forward slashes. That's what Netscape + * does, and they are actually more or less equivalent in Windows. + */ + + pathname = g_strdup (pathname); + p = (char *) pathname; + + while ((backslash = strchr (p, '\\')) != NULL) + { + *backslash = '/'; + p = backslash + 1; + } +#endif + + if (hostname && *hostname != '\0') + { + escaped_hostname = g_escape_uri_string (hostname, UNSAFE_HOST); + } + + escaped_path = g_escape_uri_string (pathname, UNSAFE_PATH); + + res = g_strconcat ("file://", + (escaped_hostname) ? escaped_hostname : "", + (*escaped_path != '/') ? "/" : "", + escaped_path, + NULL); + +#ifdef G_OS_WIN32 + g_free ((char *) pathname); +#endif + + g_free (escaped_hostname); + g_free (escaped_path); + + return res; +} + +static int +unescape_character (const char *scanner) +{ + int first_digit; + int second_digit; + + first_digit = g_ascii_xdigit_value (scanner[0]); + if (first_digit < 0) + return -1; + + second_digit = g_ascii_xdigit_value (scanner[1]); + if (second_digit < 0) + return -1; + + return (first_digit << 4) | second_digit; +} + +static gchar * +g_unescape_uri_string (const char *escaped, + int len, + const char *illegal_escaped_characters, + gboolean ascii_must_not_be_escaped) +{ + const gchar *in, *in_end; + gchar *out, *result; + int c; + + if (escaped == NULL) + return NULL; + + if (len < 0) + len = strlen (escaped); + + result = g_malloc (len + 1); + + out = result; + for (in = escaped, in_end = escaped + len; in < in_end; in++) + { + c = *in; + + if (c == '%') + { + /* catch partial escape sequences past the end of the substring */ + if (in + 3 > in_end) + break; + + c = unescape_character (in + 1); + + /* catch bad escape sequences and NUL characters */ + if (c <= 0) + break; + + /* catch escaped ASCII */ + if (ascii_must_not_be_escaped && c <= 0x7F) + break; + + /* catch other illegal escaped characters */ + if (strchr (illegal_escaped_characters, c) != NULL) + break; + + in += 2; + } + + *out++ = c; + } + + g_assert (out - result <= len); + *out = '\0'; + + if (in != in_end) + { + g_free (result); + return NULL; + } + + return result; +} + +static gboolean +is_asciialphanum (gunichar c) +{ + return c <= 0x7F && g_ascii_isalnum (c); +} + +static gboolean +is_asciialpha (gunichar c) +{ + return c <= 0x7F && g_ascii_isalpha (c); +} + +/* allows an empty string */ +static gboolean +hostname_validate (const char *hostname) +{ + const char *p; + gunichar c, first_char, last_char; + + p = hostname; + if (*p == '\0') + return TRUE; + do + { + /* read in a label */ + c = g_utf8_get_char (p); + p = g_utf8_next_char (p); + if (!is_asciialphanum (c)) + return FALSE; + first_char = c; + do + { + last_char = c; + c = g_utf8_get_char (p); + p = g_utf8_next_char (p); + } + while (is_asciialphanum (c) || c == '-'); + if (last_char == '-') + return FALSE; + + /* if that was the last label, check that it was a toplabel */ + if (c == '\0' || (c == '.' && *p == '\0')) + return is_asciialpha (first_char); + } + while (c == '.'); + return FALSE; +} + +/** + * g_filename_from_uri: + * @uri: a uri describing a filename (escaped, encoded in ASCII). + * @hostname: Location to store hostname for the URI, or %NULL. + * If there is no hostname in the URI, %NULL will be + * stored in this location. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts an escaped ASCII-encoded URI to a local filename in the + * encoding used for filenames. + * + * Return value: a newly-allocated string holding the resulting + * filename, or %NULL on an error. + **/ +gchar * +g_filename_from_uri (const gchar *uri, + gchar **hostname, + GError **error) +{ + const char *path_part; + const char *host_part; + char *unescaped_hostname; + char *result; + char *filename; + int offs; +#ifdef G_OS_WIN32 + char *p, *slash; +#endif + + if (hostname) + *hostname = NULL; + + if (!has_case_prefix (uri, "file:/")) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The URI '%s' is not an absolute URI using the \"file\" scheme"), + uri); + return NULL; + } + + path_part = uri + strlen ("file:"); + + if (strchr (path_part, '#') != NULL) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The local file URI '%s' may not include a '#'"), + uri); + return NULL; + } + + if (has_case_prefix (path_part, "///")) + path_part += 2; + else if (has_case_prefix (path_part, "//")) + { + path_part += 2; + host_part = path_part; + + path_part = strchr (path_part, '/'); + + if (path_part == NULL) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The URI '%s' is invalid"), + uri); + return NULL; + } + + unescaped_hostname = g_unescape_uri_string (host_part, path_part - host_part, "", TRUE); + + if (unescaped_hostname == NULL || + !hostname_validate (unescaped_hostname)) + { + g_free (unescaped_hostname); + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The hostname of the URI '%s' is invalid"), + uri); + return NULL; + } + + if (hostname) + *hostname = unescaped_hostname; + else + g_free (unescaped_hostname); + } + + filename = g_unescape_uri_string (path_part, -1, "/", FALSE); + + if (filename == NULL) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI, + _("The URI '%s' contains invalidly escaped characters"), + uri); + return NULL; + } + + offs = 0; +#ifdef G_OS_WIN32 + /* Drop localhost */ + if (hostname && *hostname != NULL && + g_ascii_strcasecmp (*hostname, "localhost") == 0) + { + g_free (*hostname); + *hostname = NULL; + } + + /* Turn slashes into backslashes, because that's the canonical spelling */ + p = filename; + while ((slash = strchr (p, '/')) != NULL) + { + *slash = '\\'; + p = slash + 1; + } + + /* Windows URIs with a drive letter can be like "file://host/c:/foo" + * or "file://host/c|/foo" (some Netscape versions). In those cases, start + * the filename from the drive letter. + */ + if (g_ascii_isalpha (filename[1])) + { + if (filename[2] == ':') + offs = 1; + else if (filename[2] == '|') + { + filename[2] = ':'; + offs = 1; + } + } +#endif + + result = g_strdup (filename + offs); + g_free (filename); + + return result; +} + +#if defined (G_OS_WIN32) && !defined (_WIN64) + +#undef g_filename_from_uri + +gchar * +g_filename_from_uri (const gchar *uri, + gchar **hostname, + GError **error) +{ + gchar *utf8_filename; + gchar *retval = NULL; + + utf8_filename = g_filename_from_uri_utf8 (uri, hostname, error); + if (utf8_filename) + { + retval = g_locale_from_utf8 (utf8_filename, -1, NULL, NULL, error); + g_free (utf8_filename); + } + return retval; +} + +#endif + +/** + * g_filename_to_uri: + * @filename: an absolute filename specified in the GLib file name encoding, + * which is the on-disk file name bytes on Unix, and UTF-8 on + * Windows + * @hostname: (allow-none): A UTF-8 encoded hostname, or %NULL for none. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError may occur. + * + * Converts an absolute filename to an escaped ASCII-encoded URI, with the path + * component following Section 3.3. of RFC 2396. + * + * Return value: a newly-allocated string holding the resulting + * URI, or %NULL on an error. + **/ +gchar * +g_filename_to_uri (const gchar *filename, + const gchar *hostname, + GError **error) +{ + char *escaped_uri; + + g_return_val_if_fail (filename != NULL, NULL); + + if (!g_path_is_absolute (filename)) + { + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH, + _("The pathname '%s' is not an absolute path"), + filename); + return NULL; + } + + if (hostname && + !(g_utf8_validate (hostname, -1, NULL) + && hostname_validate (hostname))) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid hostname")); + return NULL; + } + +#ifdef G_OS_WIN32 + /* Don't use localhost unnecessarily */ + if (hostname && g_ascii_strcasecmp (hostname, "localhost") == 0) + hostname = NULL; +#endif + + escaped_uri = g_escape_file_uri (hostname, filename); + + return escaped_uri; +} + +#if defined (G_OS_WIN32) && !defined (_WIN64) + +#undef g_filename_to_uri + +gchar * +g_filename_to_uri (const gchar *filename, + const gchar *hostname, + GError **error) +{ + gchar *utf8_filename; + gchar *retval = NULL; + + utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error); + + if (utf8_filename) + { + retval = g_filename_to_uri_utf8 (utf8_filename, hostname, error); + g_free (utf8_filename); + } + + return retval; +} + +#endif + +/** + * g_uri_list_extract_uris: + * @uri_list: an URI list + * + * Splits an URI list conforming to the text/uri-list + * mime type defined in RFC 2483 into individual URIs, + * discarding any comments. The URIs are not validated. + * + * Returns: a newly allocated %NULL-terminated list of + * strings holding the individual URIs. The array should + * be freed with g_strfreev(). + * + * Since: 2.6 + */ +gchar ** +g_uri_list_extract_uris (const gchar *uri_list) +{ + GSList *uris, *u; + const gchar *p, *q; + gchar **result; + gint n_uris = 0; + + uris = NULL; + + p = uri_list; + + /* We don't actually try to validate the URI according to RFC + * 2396, or even check for allowed characters - we just ignore + * comments and trim whitespace off the ends. We also + * allow LF delimination as well as the specified CRLF. + * + * We do allow comments like specified in RFC 2483. + */ + while (p) + { + if (*p != '#') + { + while (g_ascii_isspace (*p)) + p++; + + q = p; + while (*q && (*q != '\n') && (*q != '\r')) + q++; + + if (q > p) + { + q--; + while (q > p && g_ascii_isspace (*q)) + q--; + + if (q > p) + { + uris = g_slist_prepend (uris, g_strndup (p, q - p + 1)); + n_uris++; + } + } + } + p = strchr (p, '\n'); + if (p) + p++; + } + + result = g_new (gchar *, n_uris + 1); + + result[n_uris--] = NULL; + for (u = uris; u; u = u->next) + result[n_uris--] = u->data; + + g_slist_free (uris); + + return result; +} + +/** + * g_filename_display_basename: + * @filename: an absolute pathname in the GLib file name encoding + * + * Returns the display basename for the particular filename, guaranteed + * to be valid UTF-8. The display name might not be identical to the filename, + * for instance there might be problems converting it to UTF-8, and some files + * can be translated in the display. + * + * If GLib cannot make sense of the encoding of @filename, as a last resort it + * replaces unknown characters with U+FFFD, the Unicode replacement character. + * You can search the result for the UTF-8 encoding of this character (which is + * "\357\277\275" in octal notation) to find out if @filename was in an invalid + * encoding. + * + * You must pass the whole absolute pathname to this functions so that + * translation of well known locations can be done. + * + * This function is preferred over g_filename_display_name() if you know the + * whole path, as it allows translation. + * + * Return value: a newly allocated string containing + * a rendition of the basename of the filename in valid UTF-8 + * + * Since: 2.6 + **/ +gchar * +g_filename_display_basename (const gchar *filename) +{ + char *basename; + char *display_name; + + g_return_val_if_fail (filename != NULL, NULL); + + basename = g_path_get_basename (filename); + display_name = g_filename_display_name (basename); + g_free (basename); + return display_name; +} + +/** + * g_filename_display_name: + * @filename: a pathname hopefully in the GLib file name encoding + * + * Converts a filename into a valid UTF-8 string. The conversion is + * not necessarily reversible, so you should keep the original around + * and use the return value of this function only for display purposes. + * Unlike g_filename_to_utf8(), the result is guaranteed to be non-%NULL + * even if the filename actually isn't in the GLib file name encoding. + * + * If GLib cannot make sense of the encoding of @filename, as a last resort it + * replaces unknown characters with U+FFFD, the Unicode replacement character. + * You can search the result for the UTF-8 encoding of this character (which is + * "\357\277\275" in octal notation) to find out if @filename was in an invalid + * encoding. + * + * If you know the whole pathname of the file you should use + * g_filename_display_basename(), since that allows location-based + * translation of filenames. + * + * Return value: a newly allocated string containing + * a rendition of the filename in valid UTF-8 + * + * Since: 2.6 + **/ +gchar * +g_filename_display_name (const gchar *filename) +{ + gint i; + const gchar **charsets; + gchar *display_name = NULL; + gboolean is_utf8; + + is_utf8 = g_get_filename_charsets (&charsets); + + if (is_utf8) + { + if (g_utf8_validate (filename, -1, NULL)) + display_name = g_strdup (filename); + } + + if (!display_name) + { + /* Try to convert from the filename charsets to UTF-8. + * Skip the first charset if it is UTF-8. + */ + for (i = is_utf8 ? 1 : 0; charsets[i]; i++) + { + display_name = g_convert (filename, -1, "UTF-8", charsets[i], + NULL, NULL, NULL); + + if (display_name) + break; + } + } + + /* if all conversions failed, we replace invalid UTF-8 + * by a question mark + */ + if (!display_name) + display_name = _g_utf8_make_valid (filename); + + return display_name; +} diff --git a/glib/glib/gconvert.h b/glib/glib/gconvert.h new file mode 100644 index 0000000..7fd16c8 --- /dev/null +++ b/glib/glib/gconvert.h @@ -0,0 +1,164 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_CONVERT_H__ +#define __G_CONVERT_H__ + +#include + +G_BEGIN_DECLS + +/** + * GConvertError: + * @G_CONVERT_ERROR_NO_CONVERSION: Conversion between the requested character + * sets is not supported. + * @G_CONVERT_ERROR_ILLEGAL_SEQUENCE: Invalid byte sequence in conversion input. + * @G_CONVERT_ERROR_FAILED: Conversion failed for some reason. + * @G_CONVERT_ERROR_PARTIAL_INPUT: Partial character sequence at end of input. + * @G_CONVERT_ERROR_BAD_URI: URI is invalid. + * @G_CONVERT_ERROR_NOT_ABSOLUTE_PATH: Pathname is not an absolute path. + * + * Error codes returned by character set conversion routines. + */ +typedef enum +{ + G_CONVERT_ERROR_NO_CONVERSION, + G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + G_CONVERT_ERROR_FAILED, + G_CONVERT_ERROR_PARTIAL_INPUT, + G_CONVERT_ERROR_BAD_URI, + G_CONVERT_ERROR_NOT_ABSOLUTE_PATH +} GConvertError; + +/** + * G_CONVERT_ERROR: + * + * Error domain for character set conversions. Errors in this domain will + * be from the #GConvertError enumeration. See #GError for information on + * error domains. + */ +#define G_CONVERT_ERROR g_convert_error_quark() +GQuark g_convert_error_quark (void); + +/** + * GIconv: + * + * The GIConv struct wraps an + * iconv() conversion descriptor. It contains private data + * and should only be accessed using the following functions. + */ +typedef struct _GIConv *GIConv; + +GIConv g_iconv_open (const gchar *to_codeset, + const gchar *from_codeset); +gsize g_iconv (GIConv converter, + gchar **inbuf, + gsize *inbytes_left, + gchar **outbuf, + gsize *outbytes_left); +gint g_iconv_close (GIConv converter); + + +gchar* g_convert (const gchar *str, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +gchar* g_convert_with_iconv (const gchar *str, + gssize len, + GIConv converter, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +gchar* g_convert_with_fallback (const gchar *str, + gssize len, + const gchar *to_codeset, + const gchar *from_codeset, + const gchar *fallback, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; + + +/* Convert between libc's idea of strings and UTF-8. + */ +gchar* g_locale_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +gchar* g_locale_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; + +/* Convert between the operating system (or C runtime) + * representation of file names and UTF-8. + */ +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +#define g_filename_to_utf8 g_filename_to_utf8_utf8 +#define g_filename_from_utf8 g_filename_from_utf8_utf8 +#define g_filename_from_uri g_filename_from_uri_utf8 +#define g_filename_to_uri g_filename_to_uri_utf8 +#endif +#endif + +gchar* g_filename_to_utf8 (const gchar *opsysstring, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; +gchar* g_filename_from_utf8 (const gchar *utf8string, + gssize len, + gsize *bytes_read, + gsize *bytes_written, + GError **error) G_GNUC_MALLOC; + +gchar *g_filename_from_uri (const gchar *uri, + gchar **hostname, + GError **error) G_GNUC_MALLOC; + +gchar *g_filename_to_uri (const gchar *filename, + const gchar *hostname, + GError **error) G_GNUC_MALLOC; +gchar *g_filename_display_name (const gchar *filename) G_GNUC_MALLOC; +gboolean g_get_filename_charsets (const gchar ***charsets); + +gchar *g_filename_display_basename (const gchar *filename) G_GNUC_MALLOC; + +gchar **g_uri_list_extract_uris (const gchar *uri_list) G_GNUC_MALLOC; + +G_END_DECLS + +#endif /* __G_CONVERT_H__ */ diff --git a/glib/glib/gdataset.c b/glib/glib/gdataset.c new file mode 100644 index 0000000..263ae18 --- /dev/null +++ b/glib/glib/gdataset.c @@ -0,0 +1,1362 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gdataset.c: Generic dataset mechanism, similar to GtkObject data. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe ; except for g_data*_foreach() + */ + +#include "config.h" + +#include + +#include "gdataset.h" +#include "gbitlock.h" + +#include "gslice.h" +#include "gdatasetprivate.h" +#include "ghash.h" +#include "gquark.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gthread.h" +#include "glib_trace.h" + +/** + * SECTION:datasets + * @title: Datasets + * @short_description: associate groups of data elements with + * particular memory locations + * + * Datasets associate groups of data elements with particular memory + * locations. These are useful if you need to associate data with a + * structure returned from an external library. Since you cannot modify + * the structure, you use its location in memory as the key into a + * dataset, where you can associate any number of data elements with it. + * + * There are two forms of most of the dataset functions. The first form + * uses strings to identify the data elements associated with a + * location. The second form uses #GQuark identifiers, which are + * created with a call to g_quark_from_string() or + * g_quark_from_static_string(). The second form is quicker, since it + * does not require looking up the string in the hash table of #GQuark + * identifiers. + * + * There is no function to create a dataset. It is automatically + * created as soon as you add elements to it. + * + * To add data elements to a dataset use g_dataset_id_set_data(), + * g_dataset_id_set_data_full(), g_dataset_set_data() and + * g_dataset_set_data_full(). + * + * To get data elements from a dataset use g_dataset_id_get_data() and + * g_dataset_get_data(). + * + * To iterate over all data elements in a dataset use + * g_dataset_foreach() (not thread-safe). + * + * To remove data elements from a dataset use + * g_dataset_id_remove_data() and g_dataset_remove_data(). + * + * To destroy a dataset, use g_dataset_destroy(). + **/ + +/** + * SECTION:datalist + * @title: Keyed Data Lists + * @short_description: lists of data elements which are accessible by a + * string or GQuark identifier + * + * Keyed data lists provide lists of arbitrary data elements which can + * be accessed either with a string or with a #GQuark corresponding to + * the string. + * + * The #GQuark methods are quicker, since the strings have to be + * converted to #GQuarks anyway. + * + * Data lists are used for associating arbitrary data with #GObjects, + * using g_object_set_data() and related functions. + * + * To create a datalist, use g_datalist_init(). + * + * To add data elements to a datalist use g_datalist_id_set_data(), + * g_datalist_id_set_data_full(), g_datalist_set_data() and + * g_datalist_set_data_full(). + * + * To get data elements from a datalist use g_datalist_id_get_data() + * and g_datalist_get_data(). + * + * To iterate over all data elements in a datalist use + * g_datalist_foreach() (not thread-safe). + * + * To remove data elements from a datalist use + * g_datalist_id_remove_data() and g_datalist_remove_data(). + * + * To remove all data elements from a datalist, use g_datalist_clear(). + **/ + +/** + * GData: + * + * The #GData struct is an opaque data structure to represent a Keyed Data List. It should + * only be accessed via the following functions. + **/ + +/** + * GDestroyNotify: + * @data: the data element. + * + * Specifies the type of function which is called when a data element + * is destroyed. It is passed the pointer to the data element and + * should free any memory and resources allocated for it. + **/ + +/* --- defines --- */ +#define G_QUARK_BLOCK_SIZE (2048) + +#define G_DATALIST_FLAGS_MASK_INTERNAL 0x7 + +/* datalist pointer accesses have to be carried out atomically */ +#define G_DATALIST_GET_POINTER(datalist) \ + ((GData*) ((gsize) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK_INTERNAL)) + +#define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \ + gpointer _oldv, _newv; \ + do { \ + _oldv = g_atomic_pointer_get (datalist); \ + _newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK_INTERNAL) | (gsize) pointer); \ + } while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, _oldv, _newv)); \ +} G_STMT_END + +/* --- structures --- */ +typedef struct { + GQuark key; + gpointer data; + GDestroyNotify destroy; +} GDataElt; + +typedef struct _GDataset GDataset; +struct _GData +{ + guint32 len; /* Number of elements */ + guint32 alloc; /* Number of allocated elements */ + GDataElt data[1]; /* Flexible array */ +}; + +struct _GDataset +{ + gconstpointer location; + GData *datalist; +}; + + +/* --- prototypes --- */ +static inline GDataset* g_dataset_lookup (gconstpointer dataset_location); +static inline void g_datalist_clear_i (GData **datalist); +static void g_dataset_destroy_internal (GDataset *dataset); +static inline gpointer g_data_set_internal (GData **datalist, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func, + GDataset *dataset); +static void g_data_initialize (void); +static inline GQuark g_quark_new (gchar *string); + + +/* Locking model: + * Each standalone GDataList is protected by a bitlock in the datalist pointer, + * which protects that modification of the non-flags part of the datalist pointer + * and the contents of the datalist. + * + * For GDataSet we have a global lock g_dataset_global that protects + * the global dataset hash and cache, and additionally it protects the + * datalist such that we can avoid to use the bit lock in a few places + * where it is easy. + */ + +/* --- variables --- */ +G_LOCK_DEFINE_STATIC (g_dataset_global); +static GHashTable *g_dataset_location_ht = NULL; +static GDataset *g_dataset_cached = NULL; /* should this be + thread specific? */ +G_LOCK_DEFINE_STATIC (g_quark_global); +static GHashTable *g_quark_ht = NULL; +static gchar **g_quarks = NULL; +static int g_quark_seq_id = 0; + +/* --- functions --- */ + +#define DATALIST_LOCK_BIT 2 + +static void +g_datalist_lock (GData **datalist) +{ + g_pointer_bit_lock ((void **)datalist, DATALIST_LOCK_BIT); +} + +static void +g_datalist_unlock (GData **datalist) +{ + g_pointer_bit_unlock ((void **)datalist, DATALIST_LOCK_BIT); +} + +/* Called with the datalist lock held, or the dataset global + * lock for dataset lists + */ +static void +g_datalist_clear_i (GData **datalist) +{ + GData *data; + gint i; + + data = G_DATALIST_GET_POINTER (datalist); + G_DATALIST_SET_POINTER (datalist, NULL); + + if (data) + { + G_UNLOCK (g_dataset_global); + for (i = 0; i < data->len; i++) + { + if (data->data[i].data && data->data[i].destroy) + data->data[i].destroy (data->data[i].data); + } + G_LOCK (g_dataset_global); + + g_free (data); + } + +} + +/** + * g_datalist_clear: + * @datalist: a datalist. + * + * Frees all the data elements of the datalist. + * The data elements' destroy functions are called + * if they have been set. + **/ +void +g_datalist_clear (GData **datalist) +{ + GData *data; + gint i; + + g_return_if_fail (datalist != NULL); + + g_datalist_lock (datalist); + + data = G_DATALIST_GET_POINTER (datalist); + G_DATALIST_SET_POINTER (datalist, NULL); + + g_datalist_unlock (datalist); + + if (data) + { + for (i = 0; i < data->len; i++) + { + if (data->data[i].data && data->data[i].destroy) + data->data[i].destroy (data->data[i].data); + } + + g_free (data); + } +} + +/* HOLDS: g_dataset_global_lock */ +static inline GDataset* +g_dataset_lookup (gconstpointer dataset_location) +{ + register GDataset *dataset; + + if (g_dataset_cached && g_dataset_cached->location == dataset_location) + return g_dataset_cached; + + dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location); + if (dataset) + g_dataset_cached = dataset; + + return dataset; +} + +/* HOLDS: g_dataset_global_lock */ +static void +g_dataset_destroy_internal (GDataset *dataset) +{ + register gconstpointer dataset_location; + + dataset_location = dataset->location; + while (dataset) + { + if (G_DATALIST_GET_POINTER(&dataset->datalist) == NULL) + { + if (dataset == g_dataset_cached) + g_dataset_cached = NULL; + g_hash_table_remove (g_dataset_location_ht, dataset_location); + g_slice_free (GDataset, dataset); + break; + } + + g_datalist_clear_i (&dataset->datalist); + dataset = g_dataset_lookup (dataset_location); + } +} + +/** + * g_dataset_destroy: + * @dataset_location: the location identifying the dataset. + * + * Destroys the dataset, freeing all memory allocated, and calling any + * destroy functions set for data elements. + */ +void +g_dataset_destroy (gconstpointer dataset_location) +{ + g_return_if_fail (dataset_location != NULL); + + G_LOCK (g_dataset_global); + if (g_dataset_location_ht) + { + register GDataset *dataset; + + dataset = g_dataset_lookup (dataset_location); + if (dataset) + g_dataset_destroy_internal (dataset); + } + G_UNLOCK (g_dataset_global); +} + +/* HOLDS: g_dataset_global_lock if dataset != null */ +static inline gpointer +g_data_set_internal (GData **datalist, + GQuark key_id, + gpointer new_data, + GDestroyNotify new_destroy_func, + GDataset *dataset) +{ + GData *d, *old_d; + GDataElt old, *data, *data_last, *data_end; + + g_datalist_lock (datalist); + + d = G_DATALIST_GET_POINTER (datalist); + + if (new_data == NULL) /* remove */ + { + if (d) + { + data = d->data; + data_last = data + d->len - 1; + while (data <= data_last) + { + if (data->key == key_id) + { + old = *data; + if (data != data_last) + *data = *data_last; + d->len--; + + /* We don't bother to shrink, but if all data are now gone + * we at least free the memory + */ + if (d->len == 0) + { + G_DATALIST_SET_POINTER (datalist, NULL); + g_free (d); + /* datalist may be situated in dataset, so must not be + * unlocked after we free it + */ + g_datalist_unlock (datalist); + + /* the dataset destruction *must* be done + * prior to invocation of the data destroy function + */ + if (dataset) + g_dataset_destroy_internal (dataset); + } + else + { + g_datalist_unlock (datalist); + } + + /* We found and removed an old value + * the GData struct *must* already be unlinked + * when invoking the destroy function. + * we use (new_data==NULL && new_destroy_func!=NULL) as + * a special hint combination to "steal" + * data without destroy notification + */ + if (old.destroy && !new_destroy_func) + { + if (dataset) + G_UNLOCK (g_dataset_global); + old.destroy (old.data); + if (dataset) + G_LOCK (g_dataset_global); + old.data = NULL; + } + + return old.data; + } + data++; + } + } + } + else + { + old.data = NULL; + if (d) + { + data = d->data; + data_end = data + d->len; + while (data < data_end) + { + if (data->key == key_id) + { + if (!data->destroy) + { + data->data = new_data; + data->destroy = new_destroy_func; + g_datalist_unlock (datalist); + } + else + { + old = *data; + data->data = new_data; + data->destroy = new_destroy_func; + + g_datalist_unlock (datalist); + + /* We found and replaced an old value + * the GData struct *must* already be unlinked + * when invoking the destroy function. + */ + if (dataset) + G_UNLOCK (g_dataset_global); + old.destroy (old.data); + if (dataset) + G_LOCK (g_dataset_global); + } + return NULL; + } + data++; + } + } + + /* The key was not found, insert it */ + old_d = d; + if (d == NULL) + { + d = g_malloc (sizeof (GData)); + d->len = 0; + d->alloc = 1; + } + else if (d->len == d->alloc) + { + d->alloc = d->alloc * 2; + d = g_realloc (d, sizeof (GData) + (d->alloc - 1) * sizeof (GDataElt)); + } + if (old_d != d) + G_DATALIST_SET_POINTER (datalist, d); + + d->data[d->len].key = key_id; + d->data[d->len].data = new_data; + d->data[d->len].destroy = new_destroy_func; + d->len++; + } + + g_datalist_unlock (datalist); + + return NULL; + +} + +/** + * g_dataset_id_set_data_full: + * @dataset_location: the location identifying the dataset. + * @key_id: the #GQuark id to identify the data element. + * @data: the data element. + * @destroy_func: the function to call when the data element is + * removed. This function will be called with the data + * element and can be used to free any memory allocated + * for it. + * + * Sets the data element associated with the given #GQuark id, and also + * the function to call when the data element is destroyed. Any + * previous data with the same key is removed, and its destroy function + * is called. + **/ +/** + * g_dataset_set_data_full: + * @l: the location identifying the dataset. + * @k: the string to identify the data element. + * @d: the data element. + * @f: the function to call when the data element is removed. This + * function will be called with the data element and can be used to + * free any memory allocated for it. + * + * Sets the data corresponding to the given string identifier, and the + * function to call when the data element is destroyed. + **/ +/** + * g_dataset_id_set_data: + * @l: the location identifying the dataset. + * @k: the #GQuark id to identify the data element. + * @d: the data element. + * + * Sets the data element associated with the given #GQuark id. Any + * previous data with the same key is removed, and its destroy function + * is called. + **/ +/** + * g_dataset_set_data: + * @l: the location identifying the dataset. + * @k: the string to identify the data element. + * @d: the data element. + * + * Sets the data corresponding to the given string identifier. + **/ +/** + * g_dataset_id_remove_data: + * @l: the location identifying the dataset. + * @k: the #GQuark id identifying the data element. + * + * Removes a data element from a dataset. The data element's destroy + * function is called if it has been set. + **/ +/** + * g_dataset_remove_data: + * @l: the location identifying the dataset. + * @k: the string identifying the data element. + * + * Removes a data element corresponding to a string. Its destroy + * function is called if it has been set. + **/ +void +g_dataset_id_set_data_full (gconstpointer dataset_location, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func) +{ + register GDataset *dataset; + + g_return_if_fail (dataset_location != NULL); + if (!data) + g_return_if_fail (destroy_func == NULL); + if (!key_id) + { + if (data) + g_return_if_fail (key_id > 0); + else + return; + } + + G_LOCK (g_dataset_global); + if (!g_dataset_location_ht) + g_data_initialize (); + + dataset = g_dataset_lookup (dataset_location); + if (!dataset) + { + dataset = g_slice_new (GDataset); + dataset->location = dataset_location; + g_datalist_init (&dataset->datalist); + g_hash_table_insert (g_dataset_location_ht, + (gpointer) dataset->location, + dataset); + } + + g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset); + G_UNLOCK (g_dataset_global); +} + +/** + * g_datalist_id_set_data_full: + * @datalist: a datalist. + * @key_id: the #GQuark to identify the data element. + * @data: the data element or %NULL to remove any previous element + * corresponding to @key_id. + * @destroy_func: the function to call when the data element is + * removed. This function will be called with the data + * element and can be used to free any memory allocated + * for it. If @data is %NULL, then @destroy_func must + * also be %NULL. + * + * Sets the data corresponding to the given #GQuark id, and the + * function to be called when the element is removed from the datalist. + * Any previous data with the same key is removed, and its destroy + * function is called. + **/ +/** + * g_datalist_set_data_full: + * @dl: a datalist. + * @k: the string to identify the data element. + * @d: the data element, or %NULL to remove any previous element + * corresponding to @k. + * @f: the function to call when the data element is removed. This + * function will be called with the data element and can be used to + * free any memory allocated for it. If @d is %NULL, then @f must + * also be %NULL. + * + * Sets the data element corresponding to the given string identifier, + * and the function to be called when the data element is removed. + **/ +/** + * g_datalist_id_set_data: + * @dl: a datalist. + * @q: the #GQuark to identify the data element. + * @d: the data element, or %NULL to remove any previous element + * corresponding to @q. + * + * Sets the data corresponding to the given #GQuark id. Any previous + * data with the same key is removed, and its destroy function is + * called. + **/ +/** + * g_datalist_set_data: + * @dl: a datalist. + * @k: the string to identify the data element. + * @d: the data element, or %NULL to remove any previous element + * corresponding to @k. + * + * Sets the data element corresponding to the given string identifier. + **/ +/** + * g_datalist_id_remove_data: + * @dl: a datalist. + * @q: the #GQuark identifying the data element. + * + * Removes an element, using its #GQuark identifier. + **/ +/** + * g_datalist_remove_data: + * @dl: a datalist. + * @k: the string identifying the data element. + * + * Removes an element using its string identifier. The data element's + * destroy function is called if it has been set. + **/ +void +g_datalist_id_set_data_full (GData **datalist, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func) +{ + g_return_if_fail (datalist != NULL); + if (!data) + g_return_if_fail (destroy_func == NULL); + if (!key_id) + { + if (data) + g_return_if_fail (key_id > 0); + else + return; + } + + g_data_set_internal (datalist, key_id, data, destroy_func, NULL); +} + +/** + * g_dataset_id_remove_no_notify: + * @dataset_location: the location identifying the dataset. + * @key_id: the #GQuark ID identifying the data element. + * @Returns: the data previously stored at @key_id, or %NULL if none. + * + * Removes an element, without calling its destroy notification + * function. + **/ +/** + * g_dataset_remove_no_notify: + * @l: the location identifying the dataset. + * @k: the string identifying the data element. + * + * Removes an element, without calling its destroy notifier. + **/ +gpointer +g_dataset_id_remove_no_notify (gconstpointer dataset_location, + GQuark key_id) +{ + gpointer ret_data = NULL; + + g_return_val_if_fail (dataset_location != NULL, NULL); + + G_LOCK (g_dataset_global); + if (key_id && g_dataset_location_ht) + { + GDataset *dataset; + + dataset = g_dataset_lookup (dataset_location); + if (dataset) + ret_data = g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset); + } + G_UNLOCK (g_dataset_global); + + return ret_data; +} + +/** + * g_datalist_id_remove_no_notify: + * @datalist: a datalist. + * @key_id: the #GQuark identifying a data element. + * @Returns: the data previously stored at @key_id, or %NULL if none. + * + * Removes an element, without calling its destroy notification + * function. + **/ +/** + * g_datalist_remove_no_notify: + * @dl: a datalist. + * @k: the string identifying the data element. + * + * Removes an element, without calling its destroy notifier. + **/ +gpointer +g_datalist_id_remove_no_notify (GData **datalist, + GQuark key_id) +{ + gpointer ret_data = NULL; + + g_return_val_if_fail (datalist != NULL, NULL); + + if (key_id) + ret_data = g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL); + + return ret_data; +} + +/** + * g_dataset_id_get_data: + * @dataset_location: the location identifying the dataset. + * @key_id: the #GQuark id to identify the data element. + * @Returns: the data element corresponding to the #GQuark, or %NULL if + * it is not found. + * + * Gets the data element corresponding to a #GQuark. + **/ +/** + * g_dataset_get_data: + * @l: the location identifying the dataset. + * @k: the string identifying the data element. + * @Returns: the data element corresponding to the string, or %NULL if + * it is not found. + * + * Gets the data element corresponding to a string. + **/ +gpointer +g_dataset_id_get_data (gconstpointer dataset_location, + GQuark key_id) +{ + gpointer retval = NULL; + + g_return_val_if_fail (dataset_location != NULL, NULL); + + G_LOCK (g_dataset_global); + if (key_id && g_dataset_location_ht) + { + GDataset *dataset; + + dataset = g_dataset_lookup (dataset_location); + if (dataset) + retval = g_datalist_id_get_data (&dataset->datalist, key_id); + } + G_UNLOCK (g_dataset_global); + + return retval; +} + +/** + * g_datalist_id_get_data: + * @datalist: a datalist. + * @key_id: the #GQuark identifying a data element. + * @Returns: the data element, or %NULL if it is not found. + * + * Retrieves the data element corresponding to @key_id. + **/ +gpointer +g_datalist_id_get_data (GData **datalist, + GQuark key_id) +{ + gpointer res = NULL; + + g_return_val_if_fail (datalist != NULL, NULL); + if (key_id) + { + GData *d; + GDataElt *data, *data_end; + + g_datalist_lock (datalist); + + d = G_DATALIST_GET_POINTER (datalist); + if (d) + { + data = d->data; + data_end = data + d->len; + while (data < data_end) + { + if (data->key == key_id) + { + res = data->data; + break; + } + data++; + } + } + + g_datalist_unlock (datalist); + } + + return res; +} + +/** + * g_datalist_get_data: + * @datalist: a datalist. + * @key: the string identifying a data element. + * @Returns: the data element, or %NULL if it is not found. + * + * Gets a data element, using its string identifier. This is slower than + * g_datalist_id_get_data() because it compares strings. + **/ +gpointer +g_datalist_get_data (GData **datalist, + const gchar *key) +{ + gpointer res = NULL; + GData *d; + GDataElt *data, *data_end; + + g_return_val_if_fail (datalist != NULL, NULL); + + g_datalist_lock (datalist); + + d = G_DATALIST_GET_POINTER (datalist); + if (d) + { + data = d->data; + data_end = data + d->len; + while (data < data_end) + { + if (strcmp (g_quark_to_string (data->key), key) == 0) + { + res = data->data; + break; + } + data++; + } + } + + g_datalist_unlock (datalist); + + return res; +} + +/** + * GDataForeachFunc: + * @key_id: the #GQuark id to identifying the data element. + * @data: the data element. + * @user_data: user data passed to g_dataset_foreach(). + * + * Specifies the type of function passed to g_dataset_foreach(). It is + * called with each #GQuark id and associated data element, together + * with the @user_data parameter supplied to g_dataset_foreach(). + **/ + +/** + * g_dataset_foreach: + * @dataset_location: the location identifying the dataset. + * @func: the function to call for each data element. + * @user_data: user data to pass to the function. + * + * Calls the given function for each data element which is associated + * with the given location. Note that this function is NOT thread-safe. + * So unless @datalist can be protected from any modifications during + * invocation of this function, it should not be called. + **/ +void +g_dataset_foreach (gconstpointer dataset_location, + GDataForeachFunc func, + gpointer user_data) +{ + register GDataset *dataset; + + g_return_if_fail (dataset_location != NULL); + g_return_if_fail (func != NULL); + + G_LOCK (g_dataset_global); + if (g_dataset_location_ht) + { + dataset = g_dataset_lookup (dataset_location); + G_UNLOCK (g_dataset_global); + if (dataset) + g_datalist_foreach (&dataset->datalist, func, user_data); + } + else + { + G_UNLOCK (g_dataset_global); + } +} + +/** + * g_datalist_foreach: + * @datalist: a datalist. + * @func: the function to call for each data element. + * @user_data: user data to pass to the function. + * + * Calls the given function for each data element of the datalist. The + * function is called with each data element's #GQuark id and data, + * together with the given @user_data parameter. Note that this + * function is NOT thread-safe. So unless @datalist can be protected + * from any modifications during invocation of this function, it should + * not be called. + **/ +void +g_datalist_foreach (GData **datalist, + GDataForeachFunc func, + gpointer user_data) +{ + GData *d; + int i, j, len; + GQuark *keys; + + g_return_if_fail (datalist != NULL); + g_return_if_fail (func != NULL); + + d = G_DATALIST_GET_POINTER (datalist); + if (d == NULL) + return; + + /* We make a copy of the keys so that we can handle it changing + in the callback */ + len = d->len; + keys = g_new (GQuark, len); + for (i = 0; i < len; i++) + keys[i] = d->data[i].key; + + for (i = 0; i < len; i++) + { + /* A previous callback might have removed a later item, so always check that + it still exists before calling */ + d = G_DATALIST_GET_POINTER (datalist); + + if (d == NULL) + break; + for (j = 0; j < d->len; j++) + { + if (d->data[j].key == keys[i]) { + func (d->data[i].key, d->data[i].data, user_data); + break; + } + } + } + g_free (keys); +} + +/** + * g_datalist_init: + * @datalist: a pointer to a pointer to a datalist. + * + * Resets the datalist to %NULL. It does not free any memory or call + * any destroy functions. + **/ +void +g_datalist_init (GData **datalist) +{ + g_return_if_fail (datalist != NULL); + + g_atomic_pointer_set (datalist, NULL); +} + +/** + * g_datalist_set_flags: + * @datalist: pointer to the location that holds a list + * @flags: the flags to turn on. The values of the flags are + * restricted by %G_DATALIST_FLAGS_MASK (currently + * 3; giving two possible boolean flags). + * A value for @flags that doesn't fit within the mask is + * an error. + * + * Turns on flag values for a data list. This function is used + * to keep a small number of boolean flags in an object with + * a data list without using any additional space. It is + * not generally useful except in circumstances where space + * is very tight. (It is used in the base #GObject type, for + * example.) + * + * Since: 2.8 + **/ +void +g_datalist_set_flags (GData **datalist, + guint flags) +{ + g_return_if_fail (datalist != NULL); + g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); + + g_atomic_pointer_or (datalist, (gsize)flags); +} + +/** + * g_datalist_unset_flags: + * @datalist: pointer to the location that holds a list + * @flags: the flags to turn off. The values of the flags are + * restricted by %G_DATALIST_FLAGS_MASK (currently + * 3: giving two possible boolean flags). + * A value for @flags that doesn't fit within the mask is + * an error. + * + * Turns off flag values for a data list. See g_datalist_unset_flags() + * + * Since: 2.8 + **/ +void +g_datalist_unset_flags (GData **datalist, + guint flags) +{ + g_return_if_fail (datalist != NULL); + g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0); + + g_atomic_pointer_and (datalist, ~(gsize)flags); +} + +/** + * g_datalist_get_flags: + * @datalist: pointer to the location that holds a list + * + * Gets flags values packed in together with the datalist. + * See g_datalist_set_flags(). + * + * Return value: the flags of the datalist + * + * Since: 2.8 + **/ +guint +g_datalist_get_flags (GData **datalist) +{ + g_return_val_if_fail (datalist != NULL, 0); + + return G_DATALIST_GET_FLAGS (datalist); /* atomic macro */ +} + +/* HOLDS: g_dataset_global_lock */ +static void +g_data_initialize (void) +{ + g_return_if_fail (g_dataset_location_ht == NULL); + + g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL); + g_dataset_cached = NULL; +} + +/** + * SECTION:quarks + * @title: Quarks + * @short_description: a 2-way association between a string and a + * unique integer identifier + * + * Quarks are associations between strings and integer identifiers. + * Given either the string or the #GQuark identifier it is possible to + * retrieve the other. + * + * Quarks are used for both Datasets and Keyed Data Lists. + * + * To create a new quark from a string, use g_quark_from_string() or + * g_quark_from_static_string(). + * + * To find the string corresponding to a given #GQuark, use + * g_quark_to_string(). + * + * To find the #GQuark corresponding to a given string, use + * g_quark_try_string(). + * + * Another use for the string pool maintained for the quark functions + * is string interning, using g_intern_string() or + * g_intern_static_string(). An interned string is a canonical + * representation for a string. One important advantage of interned + * strings is that they can be compared for equality by a simple + * pointer comparison, rather than using strcmp(). + **/ + +/** + * GQuark: + * + * A GQuark is a non-zero integer which uniquely identifies a + * particular string. A GQuark value of zero is associated to %NULL. + **/ + +/** + * g_quark_try_string: + * @string: (allow-none): a string. + * @Returns: the #GQuark associated with the string, or 0 if @string is + * %NULL or there is no #GQuark associated with it. + * + * Gets the #GQuark associated with the given string, or 0 if string is + * %NULL or it has no associated #GQuark. + * + * If you want the GQuark to be created if it doesn't already exist, + * use g_quark_from_string() or g_quark_from_static_string(). + **/ +GQuark +g_quark_try_string (const gchar *string) +{ + GQuark quark = 0; + + if (string == NULL) + return 0; + + G_LOCK (g_quark_global); + if (g_quark_ht) + quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string)); + G_UNLOCK (g_quark_global); + + return quark; +} + +#define QUARK_STRING_BLOCK_SIZE (4096 - sizeof (gsize)) +static char *quark_block = NULL; +static int quark_block_offset = 0; + +/* HOLDS: g_quark_global_lock */ +static char * +quark_strdup(const gchar *string) +{ + gchar *copy; + gsize len; + + len = strlen (string) + 1; + + /* For strings longer than half the block size, fall back + to strdup so that we fill our blocks at least 50%. */ + if (len > QUARK_STRING_BLOCK_SIZE / 2) + return g_strdup (string); + + if (quark_block == NULL || + QUARK_STRING_BLOCK_SIZE - quark_block_offset < len) + { + quark_block = g_malloc (QUARK_STRING_BLOCK_SIZE); + quark_block_offset = 0; + } + + copy = quark_block + quark_block_offset; + memcpy (copy, string, len); + quark_block_offset += len; + + return copy; +} + +/* HOLDS: g_quark_global_lock */ +static inline GQuark +g_quark_from_string_internal (const gchar *string, + gboolean duplicate) +{ + GQuark quark = 0; + + if (g_quark_ht) + quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string)); + + if (!quark) + { + quark = g_quark_new (duplicate ? quark_strdup (string) : (gchar *)string); + TRACE(GLIB_QUARK_NEW(string, quark)); + } + + return quark; +} + +/** + * g_quark_from_string: + * @string: (allow-none): a string. + * @Returns: the #GQuark identifying the string, or 0 if @string is + * %NULL. + * + * Gets the #GQuark identifying the given string. If the string does + * not currently have an associated #GQuark, a new #GQuark is created, + * using a copy of the string. + **/ +GQuark +g_quark_from_string (const gchar *string) +{ + GQuark quark; + + if (!string) + return 0; + + G_LOCK (g_quark_global); + quark = g_quark_from_string_internal (string, TRUE); + G_UNLOCK (g_quark_global); + + return quark; +} + +/** + * g_quark_from_static_string: + * @string: (allow-none): a string. + * @Returns: the #GQuark identifying the string, or 0 if @string is + * %NULL. + * + * Gets the #GQuark identifying the given (static) string. If the + * string does not currently have an associated #GQuark, a new #GQuark + * is created, linked to the given string. + * + * Note that this function is identical to g_quark_from_string() except + * that if a new #GQuark is created the string itself is used rather + * than a copy. This saves memory, but can only be used if the string + * will always exist. It can be used with + * statically allocated strings in the main program, but not with + * statically allocated memory in dynamically loaded modules, if you + * expect to ever unload the module again (e.g. do not use this + * function in GTK+ theme engines). + **/ +GQuark +g_quark_from_static_string (const gchar *string) +{ + GQuark quark; + + if (!string) + return 0; + + G_LOCK (g_quark_global); + quark = g_quark_from_string_internal (string, FALSE); + G_UNLOCK (g_quark_global); + + return quark; +} + +/** + * g_quark_to_string: + * @quark: a #GQuark. + * @Returns: the string associated with the #GQuark. + * + * Gets the string associated with the given #GQuark. + **/ +const gchar * +g_quark_to_string (GQuark quark) +{ + gchar* result = NULL; + gchar **quarks; + gint quark_seq_id; + + quark_seq_id = g_atomic_int_get (&g_quark_seq_id); + quarks = g_atomic_pointer_get (&g_quarks); + + if (quark < quark_seq_id) + result = quarks[quark]; + + return result; +} + +/* HOLDS: g_quark_global_lock */ +static inline GQuark +g_quark_new (gchar *string) +{ + GQuark quark; + gchar **g_quarks_new; + + if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0) + { + g_quarks_new = g_new (gchar*, g_quark_seq_id + G_QUARK_BLOCK_SIZE); + if (g_quark_seq_id != 0) + memcpy (g_quarks_new, g_quarks, sizeof (char *) * g_quark_seq_id); + memset (g_quarks_new + g_quark_seq_id, 0, sizeof (char *) * G_QUARK_BLOCK_SIZE); + /* This leaks the old quarks array. Its unfortunate, but it allows + us to do lockless lookup of the arrays, and there shouldn't be that + many quarks in an app */ + g_atomic_pointer_set (&g_quarks, g_quarks_new); + } + if (!g_quark_ht) + { + g_assert (g_quark_seq_id == 0); + g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal); + g_quarks[g_quark_seq_id] = NULL; + g_atomic_int_inc (&g_quark_seq_id); + } + + quark = g_quark_seq_id; + g_atomic_pointer_set (&g_quarks[quark], string); + g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark)); + g_atomic_int_inc (&g_quark_seq_id); + + return quark; +} + +/** + * g_intern_string: + * @string: (allow-none): a string + * + * Returns a canonical representation for @string. Interned strings can + * be compared for equality by comparing the pointers, instead of using strcmp(). + * + * Returns: a canonical representation for the string + * + * Since: 2.10 + */ +const gchar * +g_intern_string (const gchar *string) +{ + const gchar *result; + GQuark quark; + + if (!string) + return NULL; + + G_LOCK (g_quark_global); + quark = g_quark_from_string_internal (string, TRUE); + result = g_quarks[quark]; + G_UNLOCK (g_quark_global); + + return result; +} + +/** + * g_intern_static_string: + * @string: (allow-none): a static string + * + * Returns a canonical representation for @string. Interned strings can + * be compared for equality by comparing the pointers, instead of using strcmp(). + * g_intern_static_string() does not copy the string, therefore @string must + * not be freed or modified. + * + * Returns: a canonical representation for the string + * + * Since: 2.10 + */ +const gchar * +g_intern_static_string (const gchar *string) +{ + GQuark quark; + const gchar *result; + + if (!string) + return NULL; + + G_LOCK (g_quark_global); + quark = g_quark_from_string_internal (string, FALSE); + result = g_quarks[quark]; + G_UNLOCK (g_quark_global); + + return result; +} diff --git a/glib/glib/gdataset.h b/glib/glib/gdataset.h new file mode 100644 index 0000000..eab296b --- /dev/null +++ b/glib/glib/gdataset.h @@ -0,0 +1,122 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_DATASET_H__ +#define __G_DATASET_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GData GData; + +typedef void (*GDataForeachFunc) (GQuark key_id, + gpointer data, + gpointer user_data); + +/* Keyed Data List + */ +void g_datalist_init (GData **datalist); +void g_datalist_clear (GData **datalist); +gpointer g_datalist_id_get_data (GData **datalist, + GQuark key_id); +void g_datalist_id_set_data_full (GData **datalist, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func); +gpointer g_datalist_id_remove_no_notify (GData **datalist, + GQuark key_id); +void g_datalist_foreach (GData **datalist, + GDataForeachFunc func, + gpointer user_data); + +/** + * G_DATALIST_FLAGS_MASK: + * + * A bitmask that restricts the possible flags passed to + * g_datalist_set_flags(). Passing a flags value where + * flags & ~G_DATALIST_FLAGS_MASK != 0 is an error. + */ +#define G_DATALIST_FLAGS_MASK 0x3 + +void g_datalist_set_flags (GData **datalist, + guint flags); +void g_datalist_unset_flags (GData **datalist, + guint flags); +guint g_datalist_get_flags (GData **datalist); + +#define g_datalist_id_set_data(dl, q, d) \ + g_datalist_id_set_data_full ((dl), (q), (d), NULL) +#define g_datalist_id_remove_data(dl, q) \ + g_datalist_id_set_data ((dl), (q), NULL) +#define g_datalist_set_data_full(dl, k, d, f) \ + g_datalist_id_set_data_full ((dl), g_quark_from_string (k), (d), (f)) +#define g_datalist_remove_no_notify(dl, k) \ + g_datalist_id_remove_no_notify ((dl), g_quark_try_string (k)) +#define g_datalist_set_data(dl, k, d) \ + g_datalist_set_data_full ((dl), (k), (d), NULL) +#define g_datalist_remove_data(dl, k) \ + g_datalist_id_set_data ((dl), g_quark_try_string (k), NULL) + + +/* Location Associated Keyed Data + */ +void g_dataset_destroy (gconstpointer dataset_location); +gpointer g_dataset_id_get_data (gconstpointer dataset_location, + GQuark key_id); +gpointer g_datalist_get_data (GData **datalist, + const gchar *key); +void g_dataset_id_set_data_full (gconstpointer dataset_location, + GQuark key_id, + gpointer data, + GDestroyNotify destroy_func); +gpointer g_dataset_id_remove_no_notify (gconstpointer dataset_location, + GQuark key_id); +void g_dataset_foreach (gconstpointer dataset_location, + GDataForeachFunc func, + gpointer user_data); +#define g_dataset_id_set_data(l, k, d) \ + g_dataset_id_set_data_full ((l), (k), (d), NULL) +#define g_dataset_id_remove_data(l, k) \ + g_dataset_id_set_data ((l), (k), NULL) +#define g_dataset_get_data(l, k) \ + (g_dataset_id_get_data ((l), g_quark_try_string (k))) +#define g_dataset_set_data_full(l, k, d, f) \ + g_dataset_id_set_data_full ((l), g_quark_from_string (k), (d), (f)) +#define g_dataset_remove_no_notify(l, k) \ + g_dataset_id_remove_no_notify ((l), g_quark_try_string (k)) +#define g_dataset_set_data(l, k, d) \ + g_dataset_set_data_full ((l), (k), (d), NULL) +#define g_dataset_remove_data(l, k) \ + g_dataset_id_set_data ((l), g_quark_try_string (k), NULL) + +G_END_DECLS + +#endif /* __G_DATASET_H__ */ diff --git a/glib/glib/gdatasetprivate.h b/glib/glib/gdatasetprivate.h new file mode 100644 index 0000000..80d0ccf --- /dev/null +++ b/glib/glib/gdatasetprivate.h @@ -0,0 +1,44 @@ +/* GLIB - Library of useful routines for C programming + * gdataset-private.h: Internal macros for accessing dataset values + * Copyright (C) 2005 Red Hat + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_DATASETPRIVATE_H__ +#define __G_DATASETPRIVATE_H__ + +#include + +G_BEGIN_DECLS + +/* GET_FLAGS is implemented via atomic pointer access, to allow memory + * barriers to take effect without acquiring the global dataset mutex. + */ +#define G_DATALIST_GET_FLAGS(datalist) \ + ((gsize) g_atomic_pointer_get (datalist) & G_DATALIST_FLAGS_MASK) + + +G_END_DECLS + +#endif /* __G_DATASETPRIVATE_H__ */ diff --git a/glib/glib/gdate.c b/glib/glib/gdate.c new file mode 100644 index 0000000..d9b25f3 --- /dev/null +++ b/glib/glib/gdate.c @@ -0,0 +1,2551 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" +#include "glibconfig.h" + +#define DEBUG_MSG(x) /* */ +#ifdef G_ENABLE_DEBUG +/* #define DEBUG_MSG(args) g_message args ; */ +#endif + +#include +#include +#include +#include + +#ifdef G_OS_WIN32 +#include +#endif + +#include "gdate.h" + +#include "gconvert.h" +#include "gmem.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gthread.h" +#include "gunicode.h" + +#ifdef G_OS_WIN32 +#include "garray.h" +#endif + +/** + * SECTION:date + * @title: Date and Time Functions + * @short_description: calendrical calculations and miscellaneous time stuff + * + * The #GDate data structure represents a day between January 1, Year 1, + * and sometime a few thousand years in the future (right now it will go + * to the year 65535 or so, but g_date_set_parse() only parses up to the + * year 8000 or so - just count on "a few thousand"). #GDate is meant to + * represent everyday dates, not astronomical dates or historical dates + * or ISO timestamps or the like. It extrapolates the current Gregorian + * calendar forward and backward in time; there is no attempt to change + * the calendar to match time periods or locations. #GDate does not store + * time information; it represents a day. + * + * The #GDate implementation has several nice features; it is only a + * 64-bit struct, so storing large numbers of dates is very efficient. It + * can keep both a Julian and day-month-year representation of the date, + * since some calculations are much easier with one representation or the + * other. A Julian representation is simply a count of days since some + * fixed day in the past; for #GDate the fixed day is January 1, 1 AD. + * ("Julian" dates in the #GDate API aren't really Julian dates in the + * technical sense; technically, Julian dates count from the start of the + * Julian period, Jan 1, 4713 BC). + * + * #GDate is simple to use. First you need a "blank" date; you can get a + * dynamically allocated date from g_date_new(), or you can declare an + * automatic variable or array and initialize it to a sane state by + * calling g_date_clear(). A cleared date is sane; it's safe to call + * g_date_set_dmy() and the other mutator functions to initialize the + * value of a cleared date. However, a cleared date is initially + * invalid, meaning that it doesn't represent a day + * that exists. It is undefined to call any of the date calculation + * routines on an invalid date. If you obtain a date from a user or other + * unpredictable source, you should check its validity with the + * g_date_valid() predicate. g_date_valid() is also used to check for + * errors with g_date_set_parse() and other functions that can + * fail. Dates can be invalidated by calling g_date_clear() again. + * + * It is very important to use the API to access the #GDate + * struct. Often only the day-month-year or only the Julian + * representation is valid. Sometimes neither is valid. Use the API. + * + * GLib also features #GDateTime which represents a precise time. + */ + +/** + * G_USEC_PER_SEC: + * + * Number of microseconds in one second (1 million). + * This macro is provided for code readability. + */ + +/** + * GTimeVal: + * @tv_sec: seconds + * @tv_usec: microseconds + * + * Represents a precise time, with seconds and microseconds. + * Similar to the struct timeval returned by + * the gettimeofday() UNIX system call. + * + * GLib is attempting to unify around the use of 64bit integers to + * represent microsecond-precision time. As such, this type will be + * removed from a future version of GLib. + */ + +/** + * GDate: + * @julian_days: the Julian representation of the date + * @julian: this bit is set if @julian_days is valid + * @dmy: this is set if @day, @month and @year are valid + * @day: the day of the day-month-year representation of the date, + * as a number between 1 and 31 + * @month: the day of the day-month-year representation of the date, + * as a number between 1 and 12 + * @year: the day of the day-month-year representation of the date + * + * Represents a day between January 1, Year 1 and a few thousand years in + * the future. None of its members should be accessed directly. If the + * GDate is obtained from g_date_new(), it will + * be safe to mutate but invalid and thus not safe for calendrical + * computations. If it's declared on the stack, it will contain garbage + * so must be initialized with g_date_clear(). g_date_clear() makes the + * date invalid but sane. An invalid date doesn't represent a day, it's + * "empty." A date becomes valid after you set it to a Julian day or you + * set a day, month, and year. + */ + +/** + * GTime: + * + * Simply a replacement for time_t. It has been deprecated + * since it is not equivalent to time_t + * on 64-bit platforms with a 64-bit time_t. + * Unrelated to #GTimer. + * + * Note that GTime is defined to always be a 32bit integer, + * unlike time_t which may be 64bit on some systems. + * Therefore, GTime will overflow in the year 2038, and + * you cannot use the address of a GTime variable as argument + * to the UNIX time() function. Instead, do the following: + * |[ + * time_t ttime; + * GTime gtime; + * + * time (&ttime); + * gtime = (GTime)ttime; + * ]| + */ + +/** + * GDateDMY: + * @G_DATE_DAY: a day + * @G_DATE_MONTH: a month + * @G_DATE_YEAR: a year + * + * This enumeration isn't used in the API, but may be useful if you need + * to mark a number as a day, month, or year. + */ + +/** + * GDateDay: + * + * Integer representing a day of the month; between 1 and + * 31. #G_DATE_BAD_DAY represents an invalid day of the month. + */ + +/** + * GDateMonth: + * @G_DATE_BAD_MONTH: invalid value + * @G_DATE_JANUARY: January + * @G_DATE_FEBRUARY: February + * @G_DATE_MARCH: March + * @G_DATE_APRIL: April + * @G_DATE_MAY: May + * @G_DATE_JUNE: June + * @G_DATE_JULY: July + * @G_DATE_AUGUST: August + * @G_DATE_SEPTEMBER: September + * @G_DATE_OCTOBER: October + * @G_DATE_NOVEMBER: November + * @G_DATE_DECEMBER: December + * + * Enumeration representing a month; values are #G_DATE_JANUARY, + * #G_DATE_FEBRUARY, etc. #G_DATE_BAD_MONTH is the invalid value. + */ + +/** + * GDateYear: + * + * Integer representing a year; #G_DATE_BAD_YEAR is the invalid + * value. The year must be 1 or higher; negative (BC) years are not + * allowed. The year is represented with four digits. + */ + +/** + * GDateWeekday: + * @G_DATE_BAD_WEEKDAY: invalid value + * @G_DATE_MONDAY: Monday + * @G_DATE_TUESDAY: Tuesday + * @G_DATE_WEDNESDAY: Wednesday + * @G_DATE_THURSDAY: Thursday + * @G_DATE_FRIDAY: Friday + * @G_DATE_SATURDAY: Saturday + * @G_DATE_SUNDAY: Sunday + * + * Enumeration representing a day of the week; #G_DATE_MONDAY, + * #G_DATE_TUESDAY, etc. #G_DATE_BAD_WEEKDAY is an invalid weekday. + */ + +/** + * G_DATE_BAD_DAY: + * + * Represents an invalid #GDateDay. + */ + +/** + * G_DATE_BAD_JULIAN: + * + * Represents an invalid Julian day number. + */ + +/** + * G_DATE_BAD_YEAR: + * + * Represents an invalid year. + */ + +/** + * g_date_new: + * + * Allocates a #GDate and initializes + * it to a sane state. The new date will + * be cleared (as if you'd called g_date_clear()) but invalid (it won't + * represent an existing day). Free the return value with g_date_free(). + * + * Returns: a newly-allocated #GDate + */ +GDate* +g_date_new (void) +{ + GDate *d = g_new0 (GDate, 1); /* happily, 0 is the invalid flag for everything. */ + + return d; +} + +/** + * g_date_new_dmy: + * @day: day of the month + * @month: month of the year + * @year: year + * + * Like g_date_new(), but also sets the value of the date. Assuming the + * day-month-year triplet you pass in represents an existing day, the + * returned date will be valid. + * + * Returns: a newly-allocated #GDate initialized with @day, @month, and @year + */ +GDate* +g_date_new_dmy (GDateDay day, + GDateMonth m, + GDateYear y) +{ + GDate *d; + g_return_val_if_fail (g_date_valid_dmy (day, m, y), NULL); + + d = g_new (GDate, 1); + + d->julian = FALSE; + d->dmy = TRUE; + + d->month = m; + d->day = day; + d->year = y; + + g_assert (g_date_valid (d)); + + return d; +} + +/** + * g_date_new_julian: + * @julian_day: days since January 1, Year 1 + * + * Like g_date_new(), but also sets the value of the date. Assuming the + * Julian day number you pass in is valid (greater than 0, less than an + * unreasonably large number), the returned date will be valid. + * + * Returns: a newly-allocated #GDate initialized with @julian_day + */ +GDate* +g_date_new_julian (guint32 julian_day) +{ + GDate *d; + g_return_val_if_fail (g_date_valid_julian (julian_day), NULL); + + d = g_new (GDate, 1); + + d->julian = TRUE; + d->dmy = FALSE; + + d->julian_days = julian_day; + + g_assert (g_date_valid (d)); + + return d; +} + +/** + * g_date_free: + * @date: a #GDate to free + * + * Frees a #GDate returned from g_date_new(). + */ +void +g_date_free (GDate *date) +{ + g_return_if_fail (date != NULL); + + g_free (date); +} + +/** + * g_date_valid: + * @date: a #GDate to check + * + * Returns %TRUE if the #GDate represents an existing day. The date must not + * contain garbage; it should have been initialized with g_date_clear() + * if it wasn't allocated by one of the g_date_new() variants. + * + * Returns: Whether the date is valid + */ +gboolean +g_date_valid (const GDate *d) +{ + g_return_val_if_fail (d != NULL, FALSE); + + return (d->julian || d->dmy); +} + +static const guint8 days_in_months[2][13] = +{ /* error, jan feb mar apr may jun jul aug sep oct nov dec */ + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } /* leap year */ +}; + +static const guint16 days_in_year[2][14] = +{ /* 0, jan feb mar apr may jun jul aug sep oct nov dec */ + { 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + { 0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +/** + * g_date_valid_month: + * @month: month + * + * Returns %TRUE if the month value is valid. The 12 #GDateMonth + * enumeration values are the only valid months. + * + * Returns: %TRUE if the month is valid + */ +gboolean +g_date_valid_month (GDateMonth m) +{ + return ( (m > G_DATE_BAD_MONTH) && (m < 13) ); +} + +/** + * g_date_valid_year: + * @year: year + * + * Returns %TRUE if the year is valid. Any year greater than 0 is valid, + * though there is a 16-bit limit to what #GDate will understand. + * + * Returns: %TRUE if the year is valid + */ +gboolean +g_date_valid_year (GDateYear y) +{ + return ( y > G_DATE_BAD_YEAR ); +} + +/** + * g_date_valid_day: + * @day: day to check + * + * Returns %TRUE if the day of the month is valid (a day is valid if it's + * between 1 and 31 inclusive). + * + * Returns: %TRUE if the day is valid + */ + +gboolean +g_date_valid_day (GDateDay d) +{ + return ( (d > G_DATE_BAD_DAY) && (d < 32) ); +} + +/** + * g_date_valid_weekday: + * @weekday: weekday + * + * Returns %TRUE if the weekday is valid. The seven #GDateWeekday enumeration + * values are the only valid weekdays. + * + * Returns: %TRUE if the weekday is valid + */ +gboolean +g_date_valid_weekday (GDateWeekday w) +{ + return ( (w > G_DATE_BAD_WEEKDAY) && (w < 8) ); +} + +/** + * g_date_valid_julian: + * @julian_date: Julian day to check + * + * Returns %TRUE if the Julian day is valid. Anything greater than zero + * is basically a valid Julian, though there is a 32-bit limit. + * + * Returns: %TRUE if the Julian day is valid + */ +gboolean +g_date_valid_julian (guint32 j) +{ + return (j > G_DATE_BAD_JULIAN); +} + +/** + * g_date_valid_dmy: + * @day: day + * @month: month + * @year: year + * + * Returns %TRUE if the day-month-year triplet forms a valid, existing day + * in the range of days #GDate understands (Year 1 or later, no more than + * a few thousand years in the future). + * + * Returns: %TRUE if the date is a valid one + */ +gboolean +g_date_valid_dmy (GDateDay d, + GDateMonth m, + GDateYear y) +{ + return ( (m > G_DATE_BAD_MONTH) && + (m < 13) && + (d > G_DATE_BAD_DAY) && + (y > G_DATE_BAD_YEAR) && /* must check before using g_date_is_leap_year */ + (d <= (g_date_is_leap_year (y) ? + days_in_months[1][m] : days_in_months[0][m])) ); +} + + +/* "Julian days" just means an absolute number of days, where Day 1 == + * Jan 1, Year 1 + */ +static void +g_date_update_julian (const GDate *const_d) +{ + GDate *d = (GDate *) const_d; + GDateYear year; + gint idx; + + g_return_if_fail (d != NULL); + g_return_if_fail (d->dmy); + g_return_if_fail (!d->julian); + g_return_if_fail (g_date_valid_dmy (d->day, d->month, d->year)); + + /* What we actually do is: multiply years * 365 days in the year, + * add the number of years divided by 4, subtract the number of + * years divided by 100 and add the number of years divided by 400, + * which accounts for leap year stuff. Code from Steffen Beyer's + * DateCalc. + */ + + year = d->year - 1; /* we know d->year > 0 since it's valid */ + + d->julian_days = year * 365U; + d->julian_days += (year >>= 2); /* divide by 4 and add */ + d->julian_days -= (year /= 25); /* divides original # years by 100 */ + d->julian_days += year >> 2; /* divides by 4, which divides original by 400 */ + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + d->julian_days += days_in_year[idx][d->month] + d->day; + + g_return_if_fail (g_date_valid_julian (d->julian_days)); + + d->julian = TRUE; +} + +static void +g_date_update_dmy (const GDate *const_d) +{ + GDate *d = (GDate *) const_d; + GDateYear y; + GDateMonth m; + GDateDay day; + + guint32 A, B, C, D, E, M; + + g_return_if_fail (d != NULL); + g_return_if_fail (d->julian); + g_return_if_fail (!d->dmy); + g_return_if_fail (g_date_valid_julian (d->julian_days)); + + /* Formula taken from the Calendar FAQ; the formula was for the + * Julian Period which starts on 1 January 4713 BC, so we add + * 1,721,425 to the number of days before doing the formula. + * + * I'm sure this can be simplified for our 1 January 1 AD period + * start, but I can't figure out how to unpack the formula. + */ + + A = d->julian_days + 1721425 + 32045; + B = ( 4 *(A + 36524) )/ 146097 - 1; + C = A - (146097 * B)/4; + D = ( 4 * (C + 365) ) / 1461 - 1; + E = C - ((1461*D) / 4); + M = (5 * (E - 1) + 2)/153; + + m = M + 3 - (12*(M/10)); + day = E - (153*M + 2)/5; + y = 100 * B + D - 4800 + (M/10); + +#ifdef G_ENABLE_DEBUG + if (!g_date_valid_dmy (day, m, y)) + g_warning ("\nOOPS julian: %u computed dmy: %u %u %u\n", + d->julian_days, day, m, y); +#endif + + d->month = m; + d->day = day; + d->year = y; + + d->dmy = TRUE; +} + +/** + * g_date_get_weekday: + * @date: a #GDate + * + * Returns the day of the week for a #GDate. The date must be valid. + * + * Returns: day of the week as a #GDateWeekday. + */ +GDateWeekday +g_date_get_weekday (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_WEEKDAY); + + if (!d->julian) + g_date_update_julian (d); + + g_return_val_if_fail (d->julian, G_DATE_BAD_WEEKDAY); + + return ((d->julian_days - 1) % 7) + 1; +} + +/** + * g_date_get_month: + * @date: a #GDate to get the month from + * + * Returns the month of the year. The date must be valid. + * + * Returns: month of the year as a #GDateMonth + */ +GDateMonth +g_date_get_month (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_MONTH); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, G_DATE_BAD_MONTH); + + return d->month; +} + +/** + * g_date_get_year: + * @date: a #GDate + * + * Returns the year of a #GDate. The date must be valid. + * + * Returns: year in which the date falls + */ +GDateYear +g_date_get_year (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_YEAR); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, G_DATE_BAD_YEAR); + + return d->year; +} + +/** + * g_date_get_day: + * @date: a #GDate to extract the day of the month from + * + * Returns the day of the month. The date must be valid. + * + * Returns: day of the month + */ +GDateDay +g_date_get_day (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_DAY); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, G_DATE_BAD_DAY); + + return d->day; +} + +/** + * g_date_get_julian: + * @date: a #GDate to extract the Julian day from + * + * Returns the Julian day or "serial number" of the #GDate. The + * Julian day is simply the number of days since January 1, Year 1; i.e., + * January 1, Year 1 is Julian day 1; January 2, Year 1 is Julian day 2, + * etc. The date must be valid. + * + * Returns: Julian day + */ +guint32 +g_date_get_julian (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_JULIAN); + + if (!d->julian) + g_date_update_julian (d); + + g_return_val_if_fail (d->julian, G_DATE_BAD_JULIAN); + + return d->julian_days; +} + +/** + * g_date_get_day_of_year: + * @date: a #GDate to extract day of year from + * + * Returns the day of the year, where Jan 1 is the first day of the + * year. The date must be valid. + * + * Returns: day of the year + */ +guint +g_date_get_day_of_year (const GDate *d) +{ + gint idx; + + g_return_val_if_fail (g_date_valid (d), 0); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, 0); + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + return (days_in_year[idx][d->month] + d->day); +} + +/** + * g_date_get_monday_week_of_year: + * @date: a #GDate + * + * Returns the week of the year, where weeks are understood to start on + * Monday. If the date is before the first Monday of the year, return + * 0. The date must be valid. + * + * Returns: week of the year + */ +guint +g_date_get_monday_week_of_year (const GDate *d) +{ + GDateWeekday wd; + guint day; + GDate first; + + g_return_val_if_fail (g_date_valid (d), 0); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, 0); + + g_date_clear (&first, 1); + + g_date_set_dmy (&first, 1, 1, d->year); + + wd = g_date_get_weekday (&first) - 1; /* make Monday day 0 */ + day = g_date_get_day_of_year (d) - 1; + + return ((day + wd)/7U + (wd == 0 ? 1 : 0)); +} + +/** + * g_date_get_sunday_week_of_year: + * @date: a #GDate + * + * Returns the week of the year during which this date falls, if weeks + * are understood to being on Sunday. The date must be valid. Can return + * 0 if the day is before the first Sunday of the year. + * + * Returns: week number + */ +guint +g_date_get_sunday_week_of_year (const GDate *d) +{ + GDateWeekday wd; + guint day; + GDate first; + + g_return_val_if_fail (g_date_valid (d), 0); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, 0); + + g_date_clear (&first, 1); + + g_date_set_dmy (&first, 1, 1, d->year); + + wd = g_date_get_weekday (&first); + if (wd == 7) wd = 0; /* make Sunday day 0 */ + day = g_date_get_day_of_year (d) - 1; + + return ((day + wd)/7U + (wd == 0 ? 1 : 0)); +} + +/** + * g_date_get_iso8601_week_of_year: + * @date: a valid #GDate + * + * Returns the week of the year, where weeks are interpreted according + * to ISO 8601. + * + * Returns: ISO 8601 week number of the year. + * + * Since: 2.6 + **/ +guint +g_date_get_iso8601_week_of_year (const GDate *d) +{ + guint j, d4, L, d1, w; + + g_return_val_if_fail (g_date_valid (d), 0); + + if (!d->julian) + g_date_update_julian (d); + + g_return_val_if_fail (d->julian, 0); + + /* Formula taken from the Calendar FAQ; the formula was for the + * Julian Period which starts on 1 January 4713 BC, so we add + * 1,721,425 to the number of days before doing the formula. + */ + j = d->julian_days + 1721425; + d4 = (j + 31741 - (j % 7)) % 146097 % 36524 % 1461; + L = d4 / 1460; + d1 = ((d4 - L) % 365) + L; + w = d1 / 7 + 1; + + return w; +} + +/** + * g_date_days_between: + * @date1: the first date + * @date2: the second date + * + * Computes the number of days between two dates. + * If @date2 is prior to @date1, the returned value is negative. + * Both dates must be valid. + * + * Returns: the number of days between @date1 and @date2 + */ +gint +g_date_days_between (const GDate *d1, + const GDate *d2) +{ + g_return_val_if_fail (g_date_valid (d1), 0); + g_return_val_if_fail (g_date_valid (d2), 0); + + return (gint)g_date_get_julian (d2) - (gint)g_date_get_julian (d1); +} + +/** + * g_date_clear: + * @date: pointer to one or more dates to clear + * @n_dates: number of dates to clear + * + * Initializes one or more #GDate structs to a sane but invalid + * state. The cleared dates will not represent an existing date, but will + * not contain garbage. Useful to init a date declared on the stack. + * Validity can be tested with g_date_valid(). + */ +void +g_date_clear (GDate *d, guint ndates) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (ndates != 0); + + memset (d, 0x0, ndates*sizeof (GDate)); +} + +G_LOCK_DEFINE_STATIC (g_date_global); + +/* These are for the parser, output to the user should use * + * g_date_strftime () - this creates more never-freed memory to annoy + * all those memory debugger users. :-) + */ + +static gchar *long_month_names[13] = +{ + NULL, +}; + +static gchar *short_month_names[13] = +{ + NULL, +}; + +/* This tells us if we need to update the parse info */ +static gchar *current_locale = NULL; + +/* order of these in the current locale */ +static GDateDMY dmy_order[3] = +{ + G_DATE_DAY, G_DATE_MONTH, G_DATE_YEAR +}; + +/* Where to chop two-digit years: i.e., for the 1930 default, numbers + * 29 and below are counted as in the year 2000, numbers 30 and above + * are counted as in the year 1900. + */ + +static const GDateYear twodigit_start_year = 1930; + +/* It is impossible to enter a year between 1 AD and 99 AD with this + * in effect. + */ +static gboolean using_twodigit_years = FALSE; + +/* Adjustment of locale era to AD, non-zero means using locale era + */ +static gint locale_era_adjust = 0; + +struct _GDateParseTokens { + gint num_ints; + gint n[3]; + guint month; +}; + +typedef struct _GDateParseTokens GDateParseTokens; + +#define NUM_LEN 10 + +/* HOLDS: g_date_global_lock */ +static void +g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt) +{ + gchar num[4][NUM_LEN+1]; + gint i; + const guchar *s; + + /* We count 4, but store 3; so we can give an error + * if there are 4. + */ + num[0][0] = num[1][0] = num[2][0] = num[3][0] = '\0'; + + s = (const guchar *) str; + pt->num_ints = 0; + while (*s && pt->num_ints < 4) + { + + i = 0; + while (*s && g_ascii_isdigit (*s) && i < NUM_LEN) + { + num[pt->num_ints][i] = *s; + ++s; + ++i; + } + + if (i > 0) + { + num[pt->num_ints][i] = '\0'; + ++(pt->num_ints); + } + + if (*s == '\0') break; + + ++s; + } + + pt->n[0] = pt->num_ints > 0 ? atoi (num[0]) : 0; + pt->n[1] = pt->num_ints > 1 ? atoi (num[1]) : 0; + pt->n[2] = pt->num_ints > 2 ? atoi (num[2]) : 0; + + pt->month = G_DATE_BAD_MONTH; + + if (pt->num_ints < 3) + { + gchar *casefold; + gchar *normalized; + + casefold = g_utf8_casefold (str, -1); + normalized = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL); + g_free (casefold); + + i = 1; + while (i < 13) + { + if (long_month_names[i] != NULL) + { + const gchar *found = strstr (normalized, long_month_names[i]); + + if (found != NULL) + { + pt->month = i; + break; + } + } + + if (short_month_names[i] != NULL) + { + const gchar *found = strstr (normalized, short_month_names[i]); + + if (found != NULL) + { + pt->month = i; + break; + } + } + + ++i; + } + + g_free (normalized); + } +} + +/* HOLDS: g_date_global_lock */ +static void +g_date_prepare_to_parse (const gchar *str, + GDateParseTokens *pt) +{ + const gchar *locale = setlocale (LC_TIME, NULL); + gboolean recompute_localeinfo = FALSE; + GDate d; + + g_return_if_fail (locale != NULL); /* should not happen */ + + g_date_clear (&d, 1); /* clear for scratch use */ + + if ( (current_locale == NULL) || (strcmp (locale, current_locale) != 0) ) + recompute_localeinfo = TRUE; /* Uh, there used to be a reason for the temporary */ + + if (recompute_localeinfo) + { + int i = 1; + GDateParseTokens testpt; + gchar buf[128]; + + g_free (current_locale); /* still works if current_locale == NULL */ + + current_locale = g_strdup (locale); + + short_month_names[0] = "Error"; + long_month_names[0] = "Error"; + + while (i < 13) + { + gchar *casefold; + + g_date_set_dmy (&d, 1, i, 1); + + g_return_if_fail (g_date_valid (&d)); + + g_date_strftime (buf, 127, "%b", &d); + + casefold = g_utf8_casefold (buf, -1); + g_free (short_month_names[i]); + short_month_names[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL); + g_free (casefold); + + g_date_strftime (buf, 127, "%B", &d); + casefold = g_utf8_casefold (buf, -1); + g_free (long_month_names[i]); + long_month_names[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL); + g_free (casefold); + + ++i; + } + + /* Determine DMY order */ + + /* had to pick a random day - don't change this, some strftimes + * are broken on some days, and this one is good so far. */ + g_date_set_dmy (&d, 4, 7, 1976); + + g_date_strftime (buf, 127, "%x", &d); + + g_date_fill_parse_tokens (buf, &testpt); + + i = 0; + while (i < testpt.num_ints) + { + switch (testpt.n[i]) + { + case 7: + dmy_order[i] = G_DATE_MONTH; + break; + case 4: + dmy_order[i] = G_DATE_DAY; + break; + case 76: + using_twodigit_years = TRUE; /* FALL THRU */ + case 1976: + dmy_order[i] = G_DATE_YEAR; + break; + default: + /* assume locale era */ + locale_era_adjust = 1976 - testpt.n[i]; + dmy_order[i] = G_DATE_YEAR; + break; + } + ++i; + } + +#if defined(G_ENABLE_DEBUG) && 0 + DEBUG_MSG (("**GDate prepared a new set of locale-specific parse rules.")); + i = 1; + while (i < 13) + { + DEBUG_MSG ((" %s %s", long_month_names[i], short_month_names[i])); + ++i; + } + if (using_twodigit_years) + { + DEBUG_MSG (("**Using twodigit years with cutoff year: %u", twodigit_start_year)); + } + { + gchar *strings[3]; + i = 0; + while (i < 3) + { + switch (dmy_order[i]) + { + case G_DATE_MONTH: + strings[i] = "Month"; + break; + case G_DATE_YEAR: + strings[i] = "Year"; + break; + case G_DATE_DAY: + strings[i] = "Day"; + break; + default: + strings[i] = NULL; + break; + } + ++i; + } + DEBUG_MSG (("**Order: %s, %s, %s", strings[0], strings[1], strings[2])); + DEBUG_MSG (("**Sample date in this locale: `%s'", buf)); + } +#endif + } + + g_date_fill_parse_tokens (str, pt); +} + +/** + * g_date_set_parse: + * @date: a #GDate to fill in + * @str: string to parse + * + * Parses a user-inputted string @str, and try to figure out what date it + * represents, taking the current locale + * into account. If the string is successfully parsed, the date will be + * valid after the call. Otherwise, it will be invalid. You should check + * using g_date_valid() to see whether the parsing succeeded. + * + * This function is not appropriate for file formats and the like; it + * isn't very precise, and its exact behavior varies with the locale. + * It's intended to be a heuristic routine that guesses what the user + * means by a given string (and it does work pretty well in that + * capacity). + */ +void +g_date_set_parse (GDate *d, + const gchar *str) +{ + GDateParseTokens pt; + guint m = G_DATE_BAD_MONTH, day = G_DATE_BAD_DAY, y = G_DATE_BAD_YEAR; + + g_return_if_fail (d != NULL); + + /* set invalid */ + g_date_clear (d, 1); + + G_LOCK (g_date_global); + + g_date_prepare_to_parse (str, &pt); + + DEBUG_MSG (("Found %d ints, `%d' `%d' `%d' and written out month %d", + pt.num_ints, pt.n[0], pt.n[1], pt.n[2], pt.month)); + + + if (pt.num_ints == 4) + { + G_UNLOCK (g_date_global); + return; /* presumably a typo; bail out. */ + } + + if (pt.num_ints > 1) + { + int i = 0; + int j = 0; + + g_assert (pt.num_ints < 4); /* i.e., it is 2 or 3 */ + + while (i < pt.num_ints && j < 3) + { + switch (dmy_order[j]) + { + case G_DATE_MONTH: + { + if (pt.num_ints == 2 && pt.month != G_DATE_BAD_MONTH) + { + m = pt.month; + ++j; /* skip months, but don't skip this number */ + continue; + } + else + m = pt.n[i]; + } + break; + case G_DATE_DAY: + { + if (pt.num_ints == 2 && pt.month == G_DATE_BAD_MONTH) + { + day = 1; + ++j; /* skip days, since we may have month/year */ + continue; + } + day = pt.n[i]; + } + break; + case G_DATE_YEAR: + { + y = pt.n[i]; + + if (locale_era_adjust != 0) + { + y += locale_era_adjust; + } + else if (using_twodigit_years && y < 100) + { + guint two = twodigit_start_year % 100; + guint century = (twodigit_start_year / 100) * 100; + + if (y < two) + century += 100; + + y += century; + } + } + break; + default: + break; + } + + ++i; + ++j; + } + + + if (pt.num_ints == 3 && !g_date_valid_dmy (day, m, y)) + { + /* Try YYYY MM DD */ + y = pt.n[0]; + m = pt.n[1]; + day = pt.n[2]; + + if (using_twodigit_years && y < 100) + y = G_DATE_BAD_YEAR; /* avoids ambiguity */ + } + else if (pt.num_ints == 2) + { + if (m == G_DATE_BAD_MONTH && pt.month != G_DATE_BAD_MONTH) + m = pt.month; + } + } + else if (pt.num_ints == 1) + { + if (pt.month != G_DATE_BAD_MONTH) + { + /* Month name and year? */ + m = pt.month; + day = 1; + y = pt.n[0]; + } + else + { + /* Try yyyymmdd and yymmdd */ + + m = (pt.n[0]/100) % 100; + day = pt.n[0] % 100; + y = pt.n[0]/10000; + + /* FIXME move this into a separate function */ + if (using_twodigit_years && y < 100) + { + guint two = twodigit_start_year % 100; + guint century = (twodigit_start_year / 100) * 100; + + if (y < two) + century += 100; + + y += century; + } + } + } + + /* See if we got anything valid out of all this. */ + /* y < 8000 is to catch 19998 style typos; the library is OK up to 65535 or so */ + if (y < 8000 && g_date_valid_dmy (day, m, y)) + { + d->month = m; + d->day = day; + d->year = y; + d->dmy = TRUE; + } +#ifdef G_ENABLE_DEBUG + else + { + DEBUG_MSG (("Rejected DMY %u %u %u", day, m, y)); + } +#endif + G_UNLOCK (g_date_global); +} + +/** + * g_date_set_time_t: + * @date: a #GDate + * @timet: time_t value to set + * + * Sets the value of a date to the date corresponding to a time + * specified as a time_t. The time to date conversion is done using + * the user's current timezone. + * + * To set the value of a date to the current day, you could write: + * |[ + * g_date_set_time_t (date, time (NULL)); + * ]| + * + * Since: 2.10 + */ +void +g_date_set_time_t (GDate *date, + time_t timet) +{ + struct tm tm; + + g_return_if_fail (date != NULL); + +#ifdef HAVE_LOCALTIME_R + localtime_r (&timet, &tm); +#else + { + struct tm *ptm = localtime (&timet); + + if (ptm == NULL) + { + /* Happens at least in Microsoft's C library if you pass a + * negative time_t. Use 2000-01-01 as default date. + */ +#ifndef G_DISABLE_CHECKS + g_return_if_fail_warning (G_LOG_DOMAIN, "g_date_set_time", "ptm != NULL"); +#endif + + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_year = 100; + } + else + memcpy ((void *) &tm, (void *) ptm, sizeof(struct tm)); + } +#endif + + date->julian = FALSE; + + date->month = tm.tm_mon + 1; + date->day = tm.tm_mday; + date->year = tm.tm_year + 1900; + + g_return_if_fail (g_date_valid_dmy (date->day, date->month, date->year)); + + date->dmy = TRUE; +} + + +/** + * g_date_set_time: + * @date: a #GDate. + * @time_: #GTime value to set. + * + * Sets the value of a date from a #GTime value. + * The time to date conversion is done using the user's current timezone. + * + * Deprecated: 2.10: Use g_date_set_time_t() instead. + */ +void +g_date_set_time (GDate *date, + GTime time_) +{ + g_date_set_time_t (date, (time_t) time_); +} + +/** + * g_date_set_time_val: + * @date: a #GDate + * @timeval: #GTimeVal value to set + * + * Sets the value of a date from a #GTimeVal value. Note that the + * @tv_usec member is ignored, because #GDate can't make use of the + * additional precision. + * + * The time to date conversion is done using the user's current timezone. + * + * Since: 2.10 + */ +void +g_date_set_time_val (GDate *date, + GTimeVal *timeval) +{ + g_date_set_time_t (date, (time_t) timeval->tv_sec); +} + +/** + * g_date_set_month: + * @date: a #GDate + * @month: month to set + * + * Sets the month of the year for a #GDate. If the resulting + * day-month-year triplet is invalid, the date will be invalid. + */ +void +g_date_set_month (GDate *d, + GDateMonth m) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_month (m)); + + if (d->julian && !d->dmy) g_date_update_dmy(d); + d->julian = FALSE; + + d->month = m; + + if (g_date_valid_dmy (d->day, d->month, d->year)) + d->dmy = TRUE; + else + d->dmy = FALSE; +} + +/** + * g_date_set_day: + * @date: a #GDate + * @day: day to set + * + * Sets the day of the month for a #GDate. If the resulting + * day-month-year triplet is invalid, the date will be invalid. + */ +void +g_date_set_day (GDate *d, + GDateDay day) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_day (day)); + + if (d->julian && !d->dmy) g_date_update_dmy(d); + d->julian = FALSE; + + d->day = day; + + if (g_date_valid_dmy (d->day, d->month, d->year)) + d->dmy = TRUE; + else + d->dmy = FALSE; +} + +/** + * g_date_set_year: + * @date: a #GDate + * @year: year to set + * + * Sets the year for a #GDate. If the resulting day-month-year + * triplet is invalid, the date will be invalid. + */ +void +g_date_set_year (GDate *d, + GDateYear y) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_year (y)); + + if (d->julian && !d->dmy) g_date_update_dmy(d); + d->julian = FALSE; + + d->year = y; + + if (g_date_valid_dmy (d->day, d->month, d->year)) + d->dmy = TRUE; + else + d->dmy = FALSE; +} + +/** + * g_date_set_dmy: + * @date: a #GDate + * @day: day + * @month: month + * @y: year + * + * Sets the value of a #GDate from a day, month, and year. + * The day-month-year triplet must be valid; if you aren't + * sure it is, call g_date_valid_dmy() to check before you + * set it. + */ +void +g_date_set_dmy (GDate *d, + GDateDay day, + GDateMonth m, + GDateYear y) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_dmy (day, m, y)); + + d->julian = FALSE; + + d->month = m; + d->day = day; + d->year = y; + + d->dmy = TRUE; +} + +/** + * g_date_set_julian: + * @date: a #GDate + * @julian_date: Julian day number (days since January 1, Year 1) + * + * Sets the value of a #GDate from a Julian day number. + */ +void +g_date_set_julian (GDate *d, + guint32 j) +{ + g_return_if_fail (d != NULL); + g_return_if_fail (g_date_valid_julian (j)); + + d->julian_days = j; + d->julian = TRUE; + d->dmy = FALSE; +} + +/** + * g_date_is_first_of_month: + * @date: a #GDate to check + * + * Returns %TRUE if the date is on the first of a month. + * The date must be valid. + * + * Returns: %TRUE if the date is the first of the month + */ +gboolean +g_date_is_first_of_month (const GDate *d) +{ + g_return_val_if_fail (g_date_valid (d), FALSE); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, FALSE); + + if (d->day == 1) return TRUE; + else return FALSE; +} + +/** + * g_date_is_last_of_month: + * @date: a #GDate to check + * + * Returns %TRUE if the date is the last day of the month. + * The date must be valid. + * + * Returns: %TRUE if the date is the last day of the month + */ +gboolean +g_date_is_last_of_month (const GDate *d) +{ + gint idx; + + g_return_val_if_fail (g_date_valid (d), FALSE); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_val_if_fail (d->dmy, FALSE); + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + if (d->day == days_in_months[idx][d->month]) return TRUE; + else return FALSE; +} + +/** + * g_date_add_days: + * @date: a #GDate to increment + * @n_days: number of days to move the date forward + * + * Increments a date some number of days. + * To move forward by weeks, add weeks*7 days. + * The date must be valid. + */ +void +g_date_add_days (GDate *d, + guint ndays) +{ + g_return_if_fail (g_date_valid (d)); + + if (!d->julian) + g_date_update_julian (d); + + g_return_if_fail (d->julian); + + d->julian_days += ndays; + d->dmy = FALSE; +} + +/** + * g_date_subtract_days: + * @date: a #GDate to decrement + * @n_days: number of days to move + * + * Moves a date some number of days into the past. + * To move by weeks, just move by weeks*7 days. + * The date must be valid. + */ +void +g_date_subtract_days (GDate *d, + guint ndays) +{ + g_return_if_fail (g_date_valid (d)); + + if (!d->julian) + g_date_update_julian (d); + + g_return_if_fail (d->julian); + g_return_if_fail (d->julian_days > ndays); + + d->julian_days -= ndays; + d->dmy = FALSE; +} + +/** + * g_date_add_months: + * @date: a #GDate to increment + * @n_months: number of months to move forward + * + * Increments a date by some number of months. + * If the day of the month is greater than 28, + * this routine may change the day of the month + * (because the destination month may not have + * the current day in it). The date must be valid. + */ +void +g_date_add_months (GDate *d, + guint nmonths) +{ + guint years, months; + gint idx; + + g_return_if_fail (g_date_valid (d)); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy); + + nmonths += d->month - 1; + + years = nmonths/12; + months = nmonths%12; + + d->month = months + 1; + d->year += years; + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + if (d->day > days_in_months[idx][d->month]) + d->day = days_in_months[idx][d->month]; + + d->julian = FALSE; + + g_return_if_fail (g_date_valid (d)); +} + +/** + * g_date_subtract_months: + * @date: a #GDate to decrement + * @n_months: number of months to move + * + * Moves a date some number of months into the past. + * If the current day of the month doesn't exist in + * the destination month, the day of the month + * may change. The date must be valid. + */ +void +g_date_subtract_months (GDate *d, + guint nmonths) +{ + guint years, months; + gint idx; + + g_return_if_fail (g_date_valid (d)); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy); + + years = nmonths/12; + months = nmonths%12; + + g_return_if_fail (d->year > years); + + d->year -= years; + + if (d->month > months) d->month -= months; + else + { + months -= d->month; + d->month = 12 - months; + d->year -= 1; + } + + idx = g_date_is_leap_year (d->year) ? 1 : 0; + + if (d->day > days_in_months[idx][d->month]) + d->day = days_in_months[idx][d->month]; + + d->julian = FALSE; + + g_return_if_fail (g_date_valid (d)); +} + +/** + * g_date_add_years: + * @date: a #GDate to increment + * @n_years: number of years to move forward + * + * Increments a date by some number of years. + * If the date is February 29, and the destination + * year is not a leap year, the date will be changed + * to February 28. The date must be valid. + */ +void +g_date_add_years (GDate *d, + guint nyears) +{ + g_return_if_fail (g_date_valid (d)); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy); + + d->year += nyears; + + if (d->month == 2 && d->day == 29) + { + if (!g_date_is_leap_year (d->year)) + d->day = 28; + } + + d->julian = FALSE; +} + +/** + * g_date_subtract_years: + * @date: a #GDate to decrement + * @n_years: number of years to move + * + * Moves a date some number of years into the past. + * If the current day doesn't exist in the destination + * year (i.e. it's February 29 and you move to a non-leap-year) + * then the day is changed to February 29. The date + * must be valid. + */ +void +g_date_subtract_years (GDate *d, + guint nyears) +{ + g_return_if_fail (g_date_valid (d)); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy); + g_return_if_fail (d->year > nyears); + + d->year -= nyears; + + if (d->month == 2 && d->day == 29) + { + if (!g_date_is_leap_year (d->year)) + d->day = 28; + } + + d->julian = FALSE; +} + +/** + * g_date_is_leap_year: + * @year: year to check + * + * Returns %TRUE if the year is a leap year. + * For the purposes of this function, + * leap year is every year divisible by 4 unless that year + * is divisible by 100. If it is divisible by 100 it would + * be a leap year only if that year is also divisible + * by 400. + * + * Returns: %TRUE if the year is a leap year + */ +gboolean +g_date_is_leap_year (GDateYear year) +{ + g_return_val_if_fail (g_date_valid_year (year), FALSE); + + return ( (((year % 4) == 0) && ((year % 100) != 0)) || + (year % 400) == 0 ); +} + +/** + * g_date_get_days_in_month: + * @month: month + * @year: year + * + * Returns the number of days in a month, taking leap + * years into account. + * + * Returns: number of days in @month during the @year + */ +guint8 +g_date_get_days_in_month (GDateMonth month, + GDateYear year) +{ + gint idx; + + g_return_val_if_fail (g_date_valid_year (year), 0); + g_return_val_if_fail (g_date_valid_month (month), 0); + + idx = g_date_is_leap_year (year) ? 1 : 0; + + return days_in_months[idx][month]; +} + +/** + * g_date_get_monday_weeks_in_year: + * @year: a year + * + * Returns the number of weeks in the year, where weeks + * are taken to start on Monday. Will be 52 or 53. The + * date must be valid. (Years always have 52 7-day periods, + * plus 1 or 2 extra days depending on whether it's a leap + * year. This function is basically telling you how many + * Mondays are in the year, i.e. there are 53 Mondays if + * one of the extra days happens to be a Monday.) + * + * Returns: number of Mondays in the year + */ +guint8 +g_date_get_monday_weeks_in_year (GDateYear year) +{ + GDate d; + + g_return_val_if_fail (g_date_valid_year (year), 0); + + g_date_clear (&d, 1); + g_date_set_dmy (&d, 1, 1, year); + if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53; + g_date_set_dmy (&d, 31, 12, year); + if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53; + if (g_date_is_leap_year (year)) + { + g_date_set_dmy (&d, 2, 1, year); + if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53; + g_date_set_dmy (&d, 30, 12, year); + if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53; + } + return 52; +} + +/** + * g_date_get_sunday_weeks_in_year: + * @year: year to count weeks in + * + * Returns the number of weeks in the year, where weeks + * are taken to start on Sunday. Will be 52 or 53. The + * date must be valid. (Years always have 52 7-day periods, + * plus 1 or 2 extra days depending on whether it's a leap + * year. This function is basically telling you how many + * Sundays are in the year, i.e. there are 53 Sundays if + * one of the extra days happens to be a Sunday.) + * + * Returns: the number of weeks in @year + */ +guint8 +g_date_get_sunday_weeks_in_year (GDateYear year) +{ + GDate d; + + g_return_val_if_fail (g_date_valid_year (year), 0); + + g_date_clear (&d, 1); + g_date_set_dmy (&d, 1, 1, year); + if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53; + g_date_set_dmy (&d, 31, 12, year); + if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53; + if (g_date_is_leap_year (year)) + { + g_date_set_dmy (&d, 2, 1, year); + if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53; + g_date_set_dmy (&d, 30, 12, year); + if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53; + } + return 52; +} + +/** + * g_date_compare: + * @lhs: first date to compare + * @rhs: second date to compare + * + * qsort()-style comparison function for dates. + * Both dates must be valid. + * + * Returns: 0 for equal, less than zero if @lhs is less than @rhs, + * greater than zero if @lhs is greater than @rhs + */ +gint +g_date_compare (const GDate *lhs, + const GDate *rhs) +{ + g_return_val_if_fail (lhs != NULL, 0); + g_return_val_if_fail (rhs != NULL, 0); + g_return_val_if_fail (g_date_valid (lhs), 0); + g_return_val_if_fail (g_date_valid (rhs), 0); + + /* Remember the self-comparison case! I think it works right now. */ + + while (TRUE) + { + if (lhs->julian && rhs->julian) + { + if (lhs->julian_days < rhs->julian_days) return -1; + else if (lhs->julian_days > rhs->julian_days) return 1; + else return 0; + } + else if (lhs->dmy && rhs->dmy) + { + if (lhs->year < rhs->year) return -1; + else if (lhs->year > rhs->year) return 1; + else + { + if (lhs->month < rhs->month) return -1; + else if (lhs->month > rhs->month) return 1; + else + { + if (lhs->day < rhs->day) return -1; + else if (lhs->day > rhs->day) return 1; + else return 0; + } + + } + + } + else + { + if (!lhs->julian) g_date_update_julian (lhs); + if (!rhs->julian) g_date_update_julian (rhs); + g_return_val_if_fail (lhs->julian, 0); + g_return_val_if_fail (rhs->julian, 0); + } + + } + return 0; /* warnings */ +} + +/** + * g_date_to_struct_tm: + * @date: a #GDate to set the struct tm from + * @tm: struct tm to fill + * + * Fills in the date-related bits of a struct tm + * using the @date value. Initializes the non-date parts with something + * sane but meaningless. + */ +void +g_date_to_struct_tm (const GDate *d, + struct tm *tm) +{ + GDateWeekday day; + + g_return_if_fail (g_date_valid (d)); + g_return_if_fail (tm != NULL); + + if (!d->dmy) + g_date_update_dmy (d); + + g_return_if_fail (d->dmy); + + /* zero all the irrelevant fields to be sure they're valid */ + + /* On Linux and maybe other systems, there are weird non-POSIX + * fields on the end of struct tm that choke strftime if they + * contain garbage. So we need to 0 the entire struct, not just the + * fields we know to exist. + */ + + memset (tm, 0x0, sizeof (struct tm)); + + tm->tm_mday = d->day; + tm->tm_mon = d->month - 1; /* 0-11 goes in tm */ + tm->tm_year = ((int)d->year) - 1900; /* X/Open says tm_year can be negative */ + + day = g_date_get_weekday (d); + if (day == 7) day = 0; /* struct tm wants days since Sunday, so Sunday is 0 */ + + tm->tm_wday = (int)day; + + tm->tm_yday = g_date_get_day_of_year (d) - 1; /* 0 to 365 */ + tm->tm_isdst = -1; /* -1 means "information not available" */ +} + +/** + * g_date_clamp: + * @date: a #GDate to clamp + * @min_date: minimum accepted value for @date + * @max_date: maximum accepted value for @date + * + * If @date is prior to @min_date, sets @date equal to @min_date. + * If @date falls after @max_date, sets @date equal to @max_date. + * Otherwise, @date is unchanged. + * Either of @min_date and @max_date may be %NULL. + * All non-%NULL dates must be valid. + */ +void +g_date_clamp (GDate *date, + const GDate *min_date, + const GDate *max_date) +{ + g_return_if_fail (g_date_valid (date)); + + if (min_date != NULL) + g_return_if_fail (g_date_valid (min_date)); + + if (max_date != NULL) + g_return_if_fail (g_date_valid (max_date)); + + if (min_date != NULL && max_date != NULL) + g_return_if_fail (g_date_compare (min_date, max_date) <= 0); + + if (min_date && g_date_compare (date, min_date) < 0) + *date = *min_date; + + if (max_date && g_date_compare (max_date, date) < 0) + *date = *max_date; +} + +/** + * g_date_order: + * @date1: the first date + * @date2: the second date + * + * Checks if @date1 is less than or equal to @date2, + * and swap the values if this is not the case. + */ +void +g_date_order (GDate *date1, + GDate *date2) +{ + g_return_if_fail (g_date_valid (date1)); + g_return_if_fail (g_date_valid (date2)); + + if (g_date_compare (date1, date2) > 0) + { + GDate tmp = *date1; + *date1 = *date2; + *date2 = tmp; + } +} + +#ifdef G_OS_WIN32 +static gsize +win32_strftime_helper (const GDate *d, + const gchar *format, + const struct tm *tm, + gchar *s, + gsize slen) +{ + SYSTEMTIME systemtime; + TIME_ZONE_INFORMATION tzinfo; + LCID lcid; + int n, k; + GArray *result; + const gchar *p; + gunichar c; + const wchar_t digits[] = L"0123456789"; + gchar *convbuf; + glong convlen = 0; + gsize retval; + + systemtime.wYear = tm->tm_year + 1900; + systemtime.wMonth = tm->tm_mon + 1; + systemtime.wDayOfWeek = tm->tm_wday; + systemtime.wDay = tm->tm_mday; + systemtime.wHour = tm->tm_hour; + systemtime.wMinute = tm->tm_min; + systemtime.wSecond = tm->tm_sec; + systemtime.wMilliseconds = 0; + + lcid = GetThreadLocale (); + result = g_array_sized_new (FALSE, FALSE, sizeof (wchar_t), MAX (128, strlen (format) * 2)); + + p = format; + while (*p) + { + c = g_utf8_get_char (p); + if (c == '%') + { + p = g_utf8_next_char (p); + if (!*p) + { + s[0] = '\0'; + g_array_free (result, TRUE); + + return 0; + } + + c = g_utf8_get_char (p); + if (c == 'E' || c == 'O') + { + /* Ignore modified conversion specifiers for now. */ + p = g_utf8_next_char (p); + if (!*p) + { + s[0] = '\0'; + g_array_free (result, TRUE); + + return 0; + } + + c = g_utf8_get_char (p); + } + + switch (c) + { + case 'a': + if (systemtime.wDayOfWeek == 0) + k = 6; + else + k = systemtime.wDayOfWeek - 1; + n = GetLocaleInfoW (lcid, LOCALE_SABBREVDAYNAME1+k, NULL, 0); + g_array_set_size (result, result->len + n); + GetLocaleInfoW (lcid, LOCALE_SABBREVDAYNAME1+k, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + break; + case 'A': + if (systemtime.wDayOfWeek == 0) + k = 6; + else + k = systemtime.wDayOfWeek - 1; + n = GetLocaleInfoW (lcid, LOCALE_SDAYNAME1+k, NULL, 0); + g_array_set_size (result, result->len + n); + GetLocaleInfoW (lcid, LOCALE_SDAYNAME1+k, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + break; + case 'b': + case 'h': + n = GetLocaleInfoW (lcid, LOCALE_SABBREVMONTHNAME1+systemtime.wMonth-1, NULL, 0); + g_array_set_size (result, result->len + n); + GetLocaleInfoW (lcid, LOCALE_SABBREVMONTHNAME1+systemtime.wMonth-1, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + break; + case 'B': + n = GetLocaleInfoW (lcid, LOCALE_SMONTHNAME1+systemtime.wMonth-1, NULL, 0); + g_array_set_size (result, result->len + n); + GetLocaleInfoW (lcid, LOCALE_SMONTHNAME1+systemtime.wMonth-1, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + break; + case 'c': + n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetDateFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + g_array_append_vals (result, L" ", 1); + n = GetTimeFormatW (lcid, 0, &systemtime, NULL, NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetTimeFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'C': + g_array_append_vals (result, digits + systemtime.wYear/1000, 1); + g_array_append_vals (result, digits + (systemtime.wYear/1000)%10, 1); + break; + case 'd': + g_array_append_vals (result, digits + systemtime.wDay/10, 1); + g_array_append_vals (result, digits + systemtime.wDay%10, 1); + break; + case 'D': + g_array_append_vals (result, digits + systemtime.wMonth/10, 1); + g_array_append_vals (result, digits + systemtime.wMonth%10, 1); + g_array_append_vals (result, L"/", 1); + g_array_append_vals (result, digits + systemtime.wDay/10, 1); + g_array_append_vals (result, digits + systemtime.wDay%10, 1); + g_array_append_vals (result, L"/", 1); + g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1); + g_array_append_vals (result, digits + systemtime.wYear%10, 1); + break; + case 'e': + if (systemtime.wDay >= 10) + g_array_append_vals (result, digits + systemtime.wDay/10, 1); + else + g_array_append_vals (result, L" ", 1); + g_array_append_vals (result, digits + systemtime.wDay%10, 1); + break; + + /* A GDate has no time fields, so for now we can + * hardcode all time conversions into zeros (or 12 for + * %I). The alternative code snippets in the #else + * branches are here ready to be taken into use when + * needed by a g_strftime() or g_date_and_time_format() + * or whatever. + */ + case 'H': +#if 1 + g_array_append_vals (result, L"00", 2); +#else + g_array_append_vals (result, digits + systemtime.wHour/10, 1); + g_array_append_vals (result, digits + systemtime.wHour%10, 1); +#endif + break; + case 'I': +#if 1 + g_array_append_vals (result, L"12", 2); +#else + if (systemtime.wHour == 0) + g_array_append_vals (result, L"12", 2); + else + { + g_array_append_vals (result, digits + (systemtime.wHour%12)/10, 1); + g_array_append_vals (result, digits + (systemtime.wHour%12)%10, 1); + } +#endif + break; + case 'j': + g_array_append_vals (result, digits + (tm->tm_yday+1)/100, 1); + g_array_append_vals (result, digits + ((tm->tm_yday+1)/10)%10, 1); + g_array_append_vals (result, digits + (tm->tm_yday+1)%10, 1); + break; + case 'm': + g_array_append_vals (result, digits + systemtime.wMonth/10, 1); + g_array_append_vals (result, digits + systemtime.wMonth%10, 1); + break; + case 'M': +#if 1 + g_array_append_vals (result, L"00", 2); +#else + g_array_append_vals (result, digits + systemtime.wMinute/10, 1); + g_array_append_vals (result, digits + systemtime.wMinute%10, 1); +#endif + break; + case 'n': + g_array_append_vals (result, L"\n", 1); + break; + case 'p': + n = GetTimeFormatW (lcid, 0, &systemtime, L"tt", NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetTimeFormatW (lcid, 0, &systemtime, L"tt", ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'r': + /* This is a rather odd format. Hard to say what to do. + * Let's always use the POSIX %I:%M:%S %p + */ +#if 1 + g_array_append_vals (result, L"12:00:00", 8); +#else + if (systemtime.wHour == 0) + g_array_append_vals (result, L"12", 2); + else + { + g_array_append_vals (result, digits + (systemtime.wHour%12)/10, 1); + g_array_append_vals (result, digits + (systemtime.wHour%12)%10, 1); + } + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wMinute/10, 1); + g_array_append_vals (result, digits + systemtime.wMinute%10, 1); + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wSecond/10, 1); + g_array_append_vals (result, digits + systemtime.wSecond%10, 1); + g_array_append_vals (result, L" ", 1); +#endif + n = GetTimeFormatW (lcid, 0, &systemtime, L"tt", NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetTimeFormatW (lcid, 0, &systemtime, L"tt", ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'R': +#if 1 + g_array_append_vals (result, L"00:00", 5); +#else + g_array_append_vals (result, digits + systemtime.wHour/10, 1); + g_array_append_vals (result, digits + systemtime.wHour%10, 1); + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wMinute/10, 1); + g_array_append_vals (result, digits + systemtime.wMinute%10, 1); +#endif + break; + case 'S': +#if 1 + g_array_append_vals (result, L"00", 2); +#else + g_array_append_vals (result, digits + systemtime.wSecond/10, 1); + g_array_append_vals (result, digits + systemtime.wSecond%10, 1); +#endif + break; + case 't': + g_array_append_vals (result, L"\t", 1); + break; + case 'T': +#if 1 + g_array_append_vals (result, L"00:00:00", 8); +#else + g_array_append_vals (result, digits + systemtime.wHour/10, 1); + g_array_append_vals (result, digits + systemtime.wHour%10, 1); + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wMinute/10, 1); + g_array_append_vals (result, digits + systemtime.wMinute%10, 1); + g_array_append_vals (result, L":", 1); + g_array_append_vals (result, digits + systemtime.wSecond/10, 1); + g_array_append_vals (result, digits + systemtime.wSecond%10, 1); +#endif + break; + case 'u': + if (systemtime.wDayOfWeek == 0) + g_array_append_vals (result, L"7", 1); + else + g_array_append_vals (result, digits + systemtime.wDayOfWeek, 1); + break; + case 'U': + n = g_date_get_sunday_week_of_year (d); + g_array_append_vals (result, digits + n/10, 1); + g_array_append_vals (result, digits + n%10, 1); + break; + case 'V': + n = g_date_get_iso8601_week_of_year (d); + g_array_append_vals (result, digits + n/10, 1); + g_array_append_vals (result, digits + n%10, 1); + break; + case 'w': + g_array_append_vals (result, digits + systemtime.wDayOfWeek, 1); + break; + case 'W': + n = g_date_get_monday_week_of_year (d); + g_array_append_vals (result, digits + n/10, 1); + g_array_append_vals (result, digits + n%10, 1); + break; + case 'x': + n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetDateFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'X': + n = GetTimeFormatW (lcid, 0, &systemtime, NULL, NULL, 0); + if (n > 0) + { + g_array_set_size (result, result->len + n); + GetTimeFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n); + g_array_set_size (result, result->len - 1); + } + break; + case 'y': + g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1); + g_array_append_vals (result, digits + systemtime.wYear%10, 1); + break; + case 'Y': + g_array_append_vals (result, digits + systemtime.wYear/1000, 1); + g_array_append_vals (result, digits + (systemtime.wYear/100)%10, 1); + g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1); + g_array_append_vals (result, digits + systemtime.wYear%10, 1); + break; + case 'Z': + n = GetTimeZoneInformation (&tzinfo); + if (n == TIME_ZONE_ID_UNKNOWN) + ; + else if (n == TIME_ZONE_ID_STANDARD) + g_array_append_vals (result, tzinfo.StandardName, wcslen (tzinfo.StandardName)); + else if (n == TIME_ZONE_ID_DAYLIGHT) + g_array_append_vals (result, tzinfo.DaylightName, wcslen (tzinfo.DaylightName)); + break; + case '%': + g_array_append_vals (result, L"%", 1); + break; + } + } + else if (c <= 0xFFFF) + { + wchar_t wc = c; + g_array_append_vals (result, &wc, 1); + } + else + { + glong nwc; + wchar_t *ws; + + ws = g_ucs4_to_utf16 (&c, 1, NULL, &nwc, NULL); + g_array_append_vals (result, ws, nwc); + g_free (ws); + } + p = g_utf8_next_char (p); + } + + convbuf = g_utf16_to_utf8 ((wchar_t *) result->data, result->len, NULL, &convlen, NULL); + g_array_free (result, TRUE); + + if (!convbuf) + { + s[0] = '\0'; + return 0; + } + + if (slen <= convlen) + { + /* Ensure only whole characters are copied into the buffer. */ + gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen); + g_assert (end != NULL); + convlen = end - convbuf; + + /* Return 0 because the buffer isn't large enough. */ + retval = 0; + } + else + retval = convlen; + + memcpy (s, convbuf, convlen); + s[convlen] = '\0'; + g_free (convbuf); + + return retval; +} + +#endif + +/** + * g_date_strftime: + * @s: destination buffer + * @slen: buffer size + * @format: format string + * @date: valid #GDate + * + * Generates a printed representation of the date, in a + * locale-specific way. + * Works just like the platform's C library strftime() function, + * but only accepts date-related formats; time-related formats + * give undefined results. Date must be valid. Unlike strftime() + * (which uses the locale encoding), works on a UTF-8 format + * string and stores a UTF-8 result. + * + * This function does not provide any conversion specifiers in + * addition to those implemented by the platform's C library. + * For example, don't expect that using g_date_strftime() would + * make the \%F provided by the C99 strftime() work on Windows + * where the C library only complies to C89. + * + * Returns: number of characters written to the buffer, or 0 the buffer was too small + */ +gsize +g_date_strftime (gchar *s, + gsize slen, + const gchar *format, + const GDate *d) +{ + struct tm tm; +#ifndef G_OS_WIN32 + gsize locale_format_len = 0; + gchar *locale_format; + gsize tmplen; + gchar *tmpbuf; + gsize tmpbufsize; + gsize convlen = 0; + gchar *convbuf; + GError *error = NULL; + gsize retval; +#endif + + g_return_val_if_fail (g_date_valid (d), 0); + g_return_val_if_fail (slen > 0, 0); + g_return_val_if_fail (format != NULL, 0); + g_return_val_if_fail (s != NULL, 0); + + g_date_to_struct_tm (d, &tm); + +#ifdef G_OS_WIN32 + if (!g_utf8_validate (format, -1, NULL)) + { + s[0] = '\0'; + return 0; + } + return win32_strftime_helper (d, format, &tm, s, slen); +#else + + locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error); + + if (error) + { + g_warning (G_STRLOC "Error converting format to locale encoding: %s\n", error->message); + g_error_free (error); + + s[0] = '\0'; + return 0; + } + + tmpbufsize = MAX (128, locale_format_len * 2); + while (TRUE) + { + tmpbuf = g_malloc (tmpbufsize); + + /* Set the first byte to something other than '\0', to be able to + * recognize whether strftime actually failed or just returned "". + */ + tmpbuf[0] = '\1'; + tmplen = strftime (tmpbuf, tmpbufsize, locale_format, &tm); + + if (tmplen == 0 && tmpbuf[0] != '\0') + { + g_free (tmpbuf); + tmpbufsize *= 2; + + if (tmpbufsize > 65536) + { + g_warning (G_STRLOC "Maximum buffer size for g_date_strftime exceeded: giving up\n"); + g_free (locale_format); + + s[0] = '\0'; + return 0; + } + } + else + break; + } + g_free (locale_format); + + convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error); + g_free (tmpbuf); + + if (error) + { + g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s\n", error->message); + g_error_free (error); + + s[0] = '\0'; + return 0; + } + + if (slen <= convlen) + { + /* Ensure only whole characters are copied into the buffer. + */ + gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen); + g_assert (end != NULL); + convlen = end - convbuf; + + /* Return 0 because the buffer isn't large enough. + */ + retval = 0; + } + else + retval = convlen; + + memcpy (s, convbuf, convlen); + s[convlen] = '\0'; + g_free (convbuf); + + return retval; +#endif +} diff --git a/glib/glib/gdate.h b/glib/glib/gdate.h new file mode 100644 index 0000000..5ef1850 --- /dev/null +++ b/glib/glib/gdate.h @@ -0,0 +1,264 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_DATE_H__ +#define __G_DATE_H__ + +#include + +#include +#include + +G_BEGIN_DECLS + +/* GDate + * + * Date calculations (not time for now, to be resolved). These are a + * mutant combination of Steffen Beyer's DateCalc routines + * (http://www.perl.com/CPAN/authors/id/STBEY/) and Jon Trowbridge's + * date routines (written for in-house software). Written by Havoc + * Pennington + */ + +typedef gint32 GTime; +typedef guint16 GDateYear; +typedef guint8 GDateDay; /* day of the month */ +typedef struct _GDate GDate; + +/* enum used to specify order of appearance in parsed date strings */ +typedef enum +{ + G_DATE_DAY = 0, + G_DATE_MONTH = 1, + G_DATE_YEAR = 2 +} GDateDMY; + +/* actual week and month values */ +typedef enum +{ + G_DATE_BAD_WEEKDAY = 0, + G_DATE_MONDAY = 1, + G_DATE_TUESDAY = 2, + G_DATE_WEDNESDAY = 3, + G_DATE_THURSDAY = 4, + G_DATE_FRIDAY = 5, + G_DATE_SATURDAY = 6, + G_DATE_SUNDAY = 7 +} GDateWeekday; +typedef enum +{ + G_DATE_BAD_MONTH = 0, + G_DATE_JANUARY = 1, + G_DATE_FEBRUARY = 2, + G_DATE_MARCH = 3, + G_DATE_APRIL = 4, + G_DATE_MAY = 5, + G_DATE_JUNE = 6, + G_DATE_JULY = 7, + G_DATE_AUGUST = 8, + G_DATE_SEPTEMBER = 9, + G_DATE_OCTOBER = 10, + G_DATE_NOVEMBER = 11, + G_DATE_DECEMBER = 12 +} GDateMonth; + +#define G_DATE_BAD_JULIAN 0U +#define G_DATE_BAD_DAY 0U +#define G_DATE_BAD_YEAR 0U + +/* Note: directly manipulating structs is generally a bad idea, but + * in this case it's an *incredibly* bad idea, because all or part + * of this struct can be invalid at any given time. Use the functions, + * or you will get hosed, I promise. + */ +struct _GDate +{ + guint julian_days : 32; /* julian days representation - we use a + * bitfield hoping that 64 bit platforms + * will pack this whole struct in one big + * int + */ + + guint julian : 1; /* julian is valid */ + guint dmy : 1; /* dmy is valid */ + + /* DMY representation */ + guint day : 6; + guint month : 4; + guint year : 16; +}; + +/* g_date_new() returns an invalid date, you then have to _set() stuff + * to get a usable object. You can also allocate a GDate statically, + * then call g_date_clear() to initialize. + */ +GDate* g_date_new (void); +GDate* g_date_new_dmy (GDateDay day, + GDateMonth month, + GDateYear year); +GDate* g_date_new_julian (guint32 julian_day); +void g_date_free (GDate *date); + +/* check g_date_valid() after doing an operation that might fail, like + * _parse. Almost all g_date operations are undefined on invalid + * dates (the exceptions are the mutators, since you need those to + * return to validity). + */ +gboolean g_date_valid (const GDate *date); +gboolean g_date_valid_day (GDateDay day) G_GNUC_CONST; +gboolean g_date_valid_month (GDateMonth month) G_GNUC_CONST; +gboolean g_date_valid_year (GDateYear year) G_GNUC_CONST; +gboolean g_date_valid_weekday (GDateWeekday weekday) G_GNUC_CONST; +gboolean g_date_valid_julian (guint32 julian_date) G_GNUC_CONST; +gboolean g_date_valid_dmy (GDateDay day, + GDateMonth month, + GDateYear year) G_GNUC_CONST; + +GDateWeekday g_date_get_weekday (const GDate *date); +GDateMonth g_date_get_month (const GDate *date); +GDateYear g_date_get_year (const GDate *date); +GDateDay g_date_get_day (const GDate *date); +guint32 g_date_get_julian (const GDate *date); +guint g_date_get_day_of_year (const GDate *date); +/* First monday/sunday is the start of week 1; if we haven't reached + * that day, return 0. These are not ISO weeks of the year; that + * routine needs to be added. + * these functions return the number of weeks, starting on the + * corrsponding day + */ +guint g_date_get_monday_week_of_year (const GDate *date); +guint g_date_get_sunday_week_of_year (const GDate *date); +guint g_date_get_iso8601_week_of_year (const GDate *date); + +/* If you create a static date struct you need to clear it to get it + * in a sane state before use. You can clear a whole array at + * once with the ndates argument. + */ +void g_date_clear (GDate *date, + guint n_dates); + +/* The parse routine is meant for dates typed in by a user, so it + * permits many formats but tries to catch common typos. If your data + * needs to be strictly validated, it is not an appropriate function. + */ +void g_date_set_parse (GDate *date, + const gchar *str); +void g_date_set_time_t (GDate *date, + time_t timet); +void g_date_set_time_val (GDate *date, + GTimeVal *timeval); +#ifndef G_DISABLE_DEPRECATED +GLIB_DEPRECATED_FOR(g_date_set_time_t) +void g_date_set_time (GDate *date, + GTime time_); +#endif +void g_date_set_month (GDate *date, + GDateMonth month); +void g_date_set_day (GDate *date, + GDateDay day); +void g_date_set_year (GDate *date, + GDateYear year); +void g_date_set_dmy (GDate *date, + GDateDay day, + GDateMonth month, + GDateYear y); +void g_date_set_julian (GDate *date, + guint32 julian_date); +gboolean g_date_is_first_of_month (const GDate *date); +gboolean g_date_is_last_of_month (const GDate *date); + +/* To go forward by some number of weeks just go forward weeks*7 days */ +void g_date_add_days (GDate *date, + guint n_days); +void g_date_subtract_days (GDate *date, + guint n_days); + +/* If you add/sub months while day > 28, the day might change */ +void g_date_add_months (GDate *date, + guint n_months); +void g_date_subtract_months (GDate *date, + guint n_months); + +/* If it's feb 29, changing years can move you to the 28th */ +void g_date_add_years (GDate *date, + guint n_years); +void g_date_subtract_years (GDate *date, + guint n_years); +gboolean g_date_is_leap_year (GDateYear year) G_GNUC_CONST; +guint8 g_date_get_days_in_month (GDateMonth month, + GDateYear year) G_GNUC_CONST; +guint8 g_date_get_monday_weeks_in_year (GDateYear year) G_GNUC_CONST; +guint8 g_date_get_sunday_weeks_in_year (GDateYear year) G_GNUC_CONST; + +/* Returns the number of days between the two dates. If date2 comes + before date1, a negative value is return. */ +gint g_date_days_between (const GDate *date1, + const GDate *date2); + +/* qsort-friendly (with a cast...) */ +gint g_date_compare (const GDate *lhs, + const GDate *rhs); +void g_date_to_struct_tm (const GDate *date, + struct tm *tm); + +void g_date_clamp (GDate *date, + const GDate *min_date, + const GDate *max_date); + +/* Swap date1 and date2's values if date1 > date2. */ +void g_date_order (GDate *date1, GDate *date2); + +/* Just like strftime() except you can only use date-related formats. + * Using a time format is undefined. + */ +gsize g_date_strftime (gchar *s, + gsize slen, + const gchar *format, + const GDate *date); + +#ifndef G_DISABLE_DEPRECATED + +#define g_date_weekday g_date_get_weekday +#define g_date_month g_date_get_month +#define g_date_year g_date_get_year +#define g_date_day g_date_get_day +#define g_date_julian g_date_get_julian +#define g_date_day_of_year g_date_get_day_of_year +#define g_date_monday_week_of_year g_date_get_monday_week_of_year +#define g_date_sunday_week_of_year g_date_get_sunday_week_of_year +#define g_date_days_in_month g_date_get_days_in_month +#define g_date_monday_weeks_in_year g_date_get_monday_weeks_in_year +#define g_date_sunday_weeks_in_year g_date_get_sunday_weeks_in_year + +#endif /* G_DISABLE_DEPRECATED */ + +G_END_DECLS + +#endif /* __G_DATE_H__ */ diff --git a/glib/glib/gdatetime.c b/glib/glib/gdatetime.c new file mode 100644 index 0000000..69e806e --- /dev/null +++ b/glib/glib/gdatetime.c @@ -0,0 +1,2754 @@ +/* gdatetime.c + * + * Copyright (C) 2009-2010 Christian Hergert + * Copyright (C) 2010 Thiago Santos + * Copyright (C) 2010 Emmanuele Bassi + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * licence, or (at your option) any later version. + * + * This 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA. + * + * Authors: Christian Hergert + * Thiago Santos + * Emmanuele Bassi + * Ryan Lortie + */ + +/* Algorithms within this file are based on the Calendar FAQ by + * Claus Tondering. It can be found at + * http://www.tondering.dk/claus/cal/calendar29.txt + * + * Copyright and disclaimer + * ------------------------ + * This document is Copyright (C) 2008 by Claus Tondering. + * E-mail: claus@tondering.dk. (Please include the word + * "calendar" in the subject line.) + * The document may be freely distributed, provided this + * copyright notice is included and no money is charged for + * the document. + * + * This document is provided "as is". No warranties are made as + * to its correctness. + */ + +/* Prologue {{{1 */ + +#include "config.h" + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef HAVE_LANGINFO_TIME +#include +#endif + +#include "gdatetime.h" + +#include "gslice.h" +#include "gatomic.h" +#include "gcharset.h" +#include "gconvert.h" +#include "gfileutils.h" +#include "ghash.h" +#include "gmain.h" +#include "gmappedfile.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gthread.h" +#include "gtimezone.h" + +#include "glibintl.h" + +#ifndef G_OS_WIN32 +#include +#include +#endif /* !G_OS_WIN32 */ + +/** + * SECTION:date-time + * @title: GDateTime + * @short_description: a structure representing Date and Time + * @see_also: #GTimeZone + * + * #GDateTime is a structure that combines a Gregorian date and time + * into a single structure. It provides many conversion and methods to + * manipulate dates and times. Time precision is provided down to + * microseconds and the time can range (proleptically) from 0001-01-01 + * 00:00:00 to 9999-12-31 23:59:59.999999. #GDateTime follows POSIX + * time in the sense that it is oblivious to leap seconds. + * + * #GDateTime is an immutable object; once it has been created it cannot + * be modified further. All modifiers will create a new #GDateTime. + * Nearly all such functions can fail due to the date or time going out + * of range, in which case %NULL will be returned. + * + * #GDateTime is reference counted: the reference count is increased by calling + * g_date_time_ref() and decreased by calling g_date_time_unref(). When the + * reference count drops to 0, the resources allocated by the #GDateTime + * structure are released. + * + * Many parts of the API may produce non-obvious results. As an + * example, adding two months to January 31st will yield March 31st + * whereas adding one month and then one month again will yield either + * March 28th or March 29th. Also note that adding 24 hours is not + * always the same as adding one day (since days containing daylight + * savings time transitions are either 23 or 25 hours in length). + * + * #GDateTime is available since GLib 2.26. + */ + +struct _GDateTime +{ + /* 1 is 0001-01-01 in Proleptic Gregorian */ + gint32 days; + + /* Microsecond timekeeping within Day */ + guint64 usec; + + /* TimeZone information */ + GTimeZone *tz; + gint interval; + + volatile gint ref_count; +}; + +/* Time conversion {{{1 */ + +#define UNIX_EPOCH_START 719163 +#define INSTANT_TO_UNIX(instant) \ + ((instant)/USEC_PER_SECOND - UNIX_EPOCH_START * SEC_PER_DAY) +#define UNIX_TO_INSTANT(unix) \ + (((unix) + UNIX_EPOCH_START * SEC_PER_DAY) * USEC_PER_SECOND) + +#define DAYS_IN_4YEARS 1461 /* days in 4 years */ +#define DAYS_IN_100YEARS 36524 /* days in 100 years */ +#define DAYS_IN_400YEARS 146097 /* days in 400 years */ + +#define USEC_PER_SECOND (G_GINT64_CONSTANT (1000000)) +#define USEC_PER_MINUTE (G_GINT64_CONSTANT (60000000)) +#define USEC_PER_HOUR (G_GINT64_CONSTANT (3600000000)) +#define USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000)) +#define USEC_PER_DAY (G_GINT64_CONSTANT (86400000000)) +#define SEC_PER_DAY (G_GINT64_CONSTANT (86400)) + +#define SECS_PER_MINUTE (60) +#define SECS_PER_HOUR (60 * SECS_PER_MINUTE) +#define SECS_PER_DAY (24 * SECS_PER_HOUR) +#define SECS_PER_YEAR (365 * SECS_PER_DAY) +#define SECS_PER_JULIAN (DAYS_PER_PERIOD * SECS_PER_DAY) + +#define GREGORIAN_LEAP(y) ((((y) % 4) == 0) && (!((((y) % 100) == 0) && (((y) % 400) != 0)))) +#define JULIAN_YEAR(d) ((d)->julian / 365.25) +#define DAYS_PER_PERIOD (G_GINT64_CONSTANT (2914695)) + +static const guint16 days_in_months[2][13] = +{ + { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } +}; + +static const guint16 days_in_year[2][13] = +{ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +#ifdef HAVE_LANGINFO_TIME + +#define GET_AMPM(d) ((g_date_time_get_hour (d) < 12) ? \ + nl_langinfo (AM_STR) : \ + nl_langinfo (PM_STR)) + +#define PREFERRED_DATE_TIME_FMT nl_langinfo (D_T_FMT) +#define PREFERRED_DATE_FMT nl_langinfo (D_FMT) +#define PREFERRED_TIME_FMT nl_langinfo (T_FMT) +#define PREFERRED_TIME_FMT nl_langinfo (T_FMT) +#define PREFERRED_12HR_TIME_FMT nl_langinfo (T_FMT_AMPM) + +static const gint weekday_item[2][7] = +{ + { ABDAY_2, ABDAY_3, ABDAY_4, ABDAY_5, ABDAY_6, ABDAY_7, ABDAY_1 }, + { DAY_2, DAY_3, DAY_4, DAY_5, DAY_6, DAY_7, DAY_1 } +}; + +static const gint month_item[2][12] = +{ + { ABMON_1, ABMON_2, ABMON_3, ABMON_4, ABMON_5, ABMON_6, ABMON_7, ABMON_8, ABMON_9, ABMON_10, ABMON_11, ABMON_12 }, + { MON_1, MON_2, MON_3, MON_4, MON_5, MON_6, MON_7, MON_8, MON_9, MON_10, MON_11, MON_12 }, +}; + +#define WEEKDAY_ABBR(d) nl_langinfo (weekday_item[0][g_date_time_get_day_of_week (d) - 1]) +#define WEEKDAY_FULL(d) nl_langinfo (weekday_item[1][g_date_time_get_day_of_week (d) - 1]) +#define MONTH_ABBR(d) nl_langinfo (month_item[0][g_date_time_get_month (d) - 1]) +#define MONTH_FULL(d) nl_langinfo (month_item[1][g_date_time_get_month (d) - 1]) + +#else + +#define GET_AMPM(d) ((g_date_time_get_hour (d) < 12) \ + /* Translators: 'before midday' indicator */ \ + ? C_("GDateTime", "AM") \ + /* Translators: 'after midday' indicator */ \ + : C_("GDateTime", "PM")) + +/* Translators: this is the preferred format for expressing the date and the time */ +#define PREFERRED_DATE_TIME_FMT C_("GDateTime", "%a %b %e %H:%M:%S %Y") + +/* Translators: this is the preferred format for expressing the date */ +#define PREFERRED_DATE_FMT C_("GDateTime", "%m/%d/%y") + +/* Translators: this is the preferred format for expressing the time */ +#define PREFERRED_TIME_FMT C_("GDateTime", "%H:%M:%S") + +/* Translators: this is the preferred format for expressing 12 hour time */ +#define PREFERRED_12HR_TIME_FMT C_("GDateTime", "%I:%M:%S %p") + +#define WEEKDAY_ABBR(d) (get_weekday_name_abbr (g_date_time_get_day_of_week (d))) +#define WEEKDAY_FULL(d) (get_weekday_name (g_date_time_get_day_of_week (d))) +#define MONTH_ABBR(d) (get_month_name_abbr (g_date_time_get_month (d))) +#define MONTH_FULL(d) (get_month_name (g_date_time_get_month (d))) + +static const gchar * +get_month_name (gint month) +{ + switch (month) + { + case 1: + return C_("full month name", "January"); + case 2: + return C_("full month name", "February"); + case 3: + return C_("full month name", "March"); + case 4: + return C_("full month name", "April"); + case 5: + return C_("full month name", "May"); + case 6: + return C_("full month name", "June"); + case 7: + return C_("full month name", "July"); + case 8: + return C_("full month name", "August"); + case 9: + return C_("full month name", "September"); + case 10: + return C_("full month name", "October"); + case 11: + return C_("full month name", "November"); + case 12: + return C_("full month name", "December"); + + default: + g_warning ("Invalid month number %d", month); + } + + return NULL; +} + +static const gchar * +get_month_name_abbr (gint month) +{ + switch (month) + { + case 1: + return C_("abbreviated month name", "Jan"); + case 2: + return C_("abbreviated month name", "Feb"); + case 3: + return C_("abbreviated month name", "Mar"); + case 4: + return C_("abbreviated month name", "Apr"); + case 5: + return C_("abbreviated month name", "May"); + case 6: + return C_("abbreviated month name", "Jun"); + case 7: + return C_("abbreviated month name", "Jul"); + case 8: + return C_("abbreviated month name", "Aug"); + case 9: + return C_("abbreviated month name", "Sep"); + case 10: + return C_("abbreviated month name", "Oct"); + case 11: + return C_("abbreviated month name", "Nov"); + case 12: + return C_("abbreviated month name", "Dec"); + + default: + g_warning ("Invalid month number %d", month); + } + + return NULL; +} + +static const gchar * +get_weekday_name (gint day) +{ + switch (day) + { + case 1: + return C_("full weekday name", "Monday"); + case 2: + return C_("full weekday name", "Tuesday"); + case 3: + return C_("full weekday name", "Wednesday"); + case 4: + return C_("full weekday name", "Thursday"); + case 5: + return C_("full weekday name", "Friday"); + case 6: + return C_("full weekday name", "Saturday"); + case 7: + return C_("full weekday name", "Sunday"); + + default: + g_warning ("Invalid week day number %d", day); + } + + return NULL; +} + +static const gchar * +get_weekday_name_abbr (gint day) +{ + switch (day) + { + case 1: + return C_("abbreviated weekday name", "Mon"); + case 2: + return C_("abbreviated weekday name", "Tue"); + case 3: + return C_("abbreviated weekday name", "Wed"); + case 4: + return C_("abbreviated weekday name", "Thu"); + case 5: + return C_("abbreviated weekday name", "Fri"); + case 6: + return C_("abbreviated weekday name", "Sat"); + case 7: + return C_("abbreviated weekday name", "Sun"); + + default: + g_warning ("Invalid week day number %d", day); + } + + return NULL; +} + +#endif /* HAVE_LANGINFO_TIME */ + +static inline gint +ymd_to_days (gint year, + gint month, + gint day) +{ + gint64 days; + + days = (year - 1) * 365 + ((year - 1) / 4) - ((year - 1) / 100) + + ((year - 1) / 400); + + days += days_in_year[0][month - 1]; + if (GREGORIAN_LEAP (year) && month > 2) + day++; + + days += day; + + return days; +} + +static void +g_date_time_get_week_number (GDateTime *datetime, + gint *week_number, + gint *day_of_week, + gint *day_of_year) +{ + gint a, b, c, d, e, f, g, n, s, month, day, year; + + g_date_time_get_ymd (datetime, &year, &month, &day); + + if (month <= 2) + { + a = g_date_time_get_year (datetime) - 1; + b = (a / 4) - (a / 100) + (a / 400); + c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400); + s = b - c; + e = 0; + f = day - 1 + (31 * (month - 1)); + } + else + { + a = year; + b = (a / 4) - (a / 100) + (a / 400); + c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400); + s = b - c; + e = s + 1; + f = day + (((153 * (month - 3)) + 2) / 5) + 58 + s; + } + + g = (a + b) % 7; + d = (f + g - e) % 7; + n = f + 3 - d; + + if (week_number) + { + if (n < 0) + *week_number = 53 - ((g - s) / 5); + else if (n > 364 + s) + *week_number = 1; + else + *week_number = (n / 7) + 1; + } + + if (day_of_week) + *day_of_week = d + 1; + + if (day_of_year) + *day_of_year = f + 1; +} + +/* Lifecycle {{{1 */ + +static GDateTime * +g_date_time_alloc (GTimeZone *tz) +{ + GDateTime *datetime; + + datetime = g_slice_new0 (GDateTime); + datetime->tz = g_time_zone_ref (tz); + datetime->ref_count = 1; + + return datetime; +} + +/** + * g_date_time_ref: + * @datetime: a #GDateTime + * + * Atomically increments the reference count of @datetime by one. + * + * Return value: the #GDateTime with the reference count increased + * + * Since: 2.26 + */ +GDateTime * +g_date_time_ref (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, NULL); + g_return_val_if_fail (datetime->ref_count > 0, NULL); + + g_atomic_int_inc (&datetime->ref_count); + + return datetime; +} + +/** + * g_date_time_unref: + * @datetime: a #GDateTime + * + * Atomically decrements the reference count of @datetime by one. + * + * When the reference count reaches zero, the resources allocated by + * @datetime are freed + * + * Since: 2.26 + */ +void +g_date_time_unref (GDateTime *datetime) +{ + g_return_if_fail (datetime != NULL); + g_return_if_fail (datetime->ref_count > 0); + + if (g_atomic_int_dec_and_test (&datetime->ref_count)) + { + g_time_zone_unref (datetime->tz); + g_slice_free (GDateTime, datetime); + } +} + +/* Internal state transformers {{{1 */ +/*< internal > + * g_date_time_to_instant: + * @datetime: a #GDateTime + * + * Convert a @datetime into an instant. + * + * An instant is a number that uniquely describes a particular + * microsecond in time, taking time zone considerations into account. + * (ie: "03:00 -0400" is the same instant as "02:00 -0500"). + * + * An instant is always positive but we use a signed return value to + * avoid troubles with C. + */ +static gint64 +g_date_time_to_instant (GDateTime *datetime) +{ + gint64 offset; + + offset = g_time_zone_get_offset (datetime->tz, datetime->interval); + offset *= USEC_PER_SECOND; + + return datetime->days * USEC_PER_DAY + datetime->usec - offset; +} + +/*< internal > + * g_date_time_from_instant: + * @tz: a #GTimeZone + * @instant: a instant in time + * + * Creates a #GDateTime from a time zone and an instant. + * + * This might fail if the time ends up being out of range. + */ +static GDateTime * +g_date_time_from_instant (GTimeZone *tz, + gint64 instant) +{ + GDateTime *datetime; + gint64 offset; + + if (instant < 0 || instant > G_GINT64_CONSTANT (1000000000000000000)) + return NULL; + + datetime = g_date_time_alloc (tz); + datetime->interval = g_time_zone_find_interval (tz, + G_TIME_TYPE_UNIVERSAL, + INSTANT_TO_UNIX (instant)); + offset = g_time_zone_get_offset (datetime->tz, datetime->interval); + offset *= USEC_PER_SECOND; + + instant += offset; + + datetime->days = instant / USEC_PER_DAY; + datetime->usec = instant % USEC_PER_DAY; + + if (datetime->days < 1 || 3652059 < datetime->days) + { + g_date_time_unref (datetime); + datetime = NULL; + } + + return datetime; +} + + +/*< internal > + * g_date_time_deal_with_date_change: + * @datetime: a #GDateTime + * + * This function should be called whenever the date changes by adding + * days, months or years. It does three things. + * + * First, we ensure that the date falls between 0001-01-01 and + * 9999-12-31 and return %FALSE if it does not. + * + * Next we update the ->interval field. + * + * Finally, we ensure that the resulting date and time pair exists (by + * ensuring that our time zone has an interval containing it) and + * adjusting as required. For example, if we have the time 02:30:00 on + * March 13 2010 in Toronto and we add 1 day to it, we would end up with + * 2:30am on March 14th, which doesn't exist. In that case, we bump the + * time up to 3:00am. + */ +static gboolean +g_date_time_deal_with_date_change (GDateTime *datetime) +{ + GTimeType was_dst; + gint64 full_time; + gint64 usec; + + if (datetime->days < 1 || datetime->days > 3652059) + return FALSE; + + was_dst = g_time_zone_is_dst (datetime->tz, datetime->interval); + + full_time = datetime->days * USEC_PER_DAY + datetime->usec; + + + usec = full_time % USEC_PER_SECOND; + full_time /= USEC_PER_SECOND; + full_time -= UNIX_EPOCH_START * SEC_PER_DAY; + + datetime->interval = g_time_zone_adjust_time (datetime->tz, + was_dst, + &full_time); + full_time += UNIX_EPOCH_START * SEC_PER_DAY; + full_time *= USEC_PER_SECOND; + full_time += usec; + + datetime->days = full_time / USEC_PER_DAY; + datetime->usec = full_time % USEC_PER_DAY; + + /* maybe daylight time caused us to shift to a different day, + * but it definitely didn't push us into a different year */ + return TRUE; +} + +static GDateTime * +g_date_time_replace_days (GDateTime *datetime, + gint days) +{ + GDateTime *new; + + new = g_date_time_alloc (datetime->tz); + new->interval = datetime->interval; + new->usec = datetime->usec; + new->days = days; + + if (!g_date_time_deal_with_date_change (new)) + { + g_date_time_unref (new); + new = NULL; + } + + return new; +} + +/* now/unix/timeval Constructors {{{1 */ + +/*< internal > + * g_date_time_new_from_timeval: + * @tz: a #GTimeZone + * @tv: a #GTimeVal + * + * Creates a #GDateTime corresponding to the given #GTimeVal @tv in the + * given time zone @tz. + * + * The time contained in a #GTimeVal is always stored in the form of + * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the + * given time zone. + * + * This call can fail (returning %NULL) if @tv represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +static GDateTime * +g_date_time_new_from_timeval (GTimeZone *tz, + const GTimeVal *tv) +{ + return g_date_time_from_instant (tz, tv->tv_usec + + UNIX_TO_INSTANT (tv->tv_sec)); +} + +/*< internal > + * g_date_time_new_from_unix: + * @tz: a #GTimeZone + * @t: the Unix time + * + * Creates a #GDateTime corresponding to the given Unix time @t in the + * given time zone @tz. + * + * Unix time is the number of seconds that have elapsed since 1970-01-01 + * 00:00:00 UTC, regardless of the time zone given. + * + * This call can fail (returning %NULL) if @t represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +static GDateTime * +g_date_time_new_from_unix (GTimeZone *tz, + gint64 secs) +{ + return g_date_time_from_instant (tz, UNIX_TO_INSTANT (secs)); +} + +/** + * g_date_time_new_now: + * @tz: a #GTimeZone + * + * Creates a #GDateTime corresponding to this exact instant in the given + * time zone @tz. The time is as accurate as the system allows, to a + * maximum accuracy of 1 microsecond. + * + * This function will always succeed unless the system clock is set to + * truly insane values (or unless GLib is still being used after the + * year 9999). + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_now (GTimeZone *tz) +{ + GTimeVal tv; + + g_get_current_time (&tv); + + return g_date_time_new_from_timeval (tz, &tv); +} + +/** + * g_date_time_new_now_local: + * + * Creates a #GDateTime corresponding to this exact instant in the local + * time zone. + * + * This is equivalent to calling g_date_time_new_now() with the time + * zone returned by g_time_zone_new_local(). + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_now_local (void) +{ + GDateTime *datetime; + GTimeZone *local; + + local = g_time_zone_new_local (); + datetime = g_date_time_new_now (local); + g_time_zone_unref (local); + + return datetime; +} + +/** + * g_date_time_new_now_utc: + * + * Creates a #GDateTime corresponding to this exact instant in UTC. + * + * This is equivalent to calling g_date_time_new_now() with the time + * zone returned by g_time_zone_new_utc(). + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_now_utc (void) +{ + GDateTime *datetime; + GTimeZone *utc; + + utc = g_time_zone_new_utc (); + datetime = g_date_time_new_now (utc); + g_time_zone_unref (utc); + + return datetime; +} + +/** + * g_date_time_new_from_unix_local: + * @t: the Unix time + * + * Creates a #GDateTime corresponding to the given Unix time @t in the + * local time zone. + * + * Unix time is the number of seconds that have elapsed since 1970-01-01 + * 00:00:00 UTC, regardless of the local time offset. + * + * This call can fail (returning %NULL) if @t represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_from_unix_local (gint64 t) +{ + GDateTime *datetime; + GTimeZone *local; + + local = g_time_zone_new_local (); + datetime = g_date_time_new_from_unix (local, t); + g_time_zone_unref (local); + + return datetime; +} + +/** + * g_date_time_new_from_unix_utc: + * @t: the Unix time + * + * Creates a #GDateTime corresponding to the given Unix time @t in UTC. + * + * Unix time is the number of seconds that have elapsed since 1970-01-01 + * 00:00:00 UTC. + * + * This call can fail (returning %NULL) if @t represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_from_unix_utc (gint64 t) +{ + GDateTime *datetime; + GTimeZone *utc; + + utc = g_time_zone_new_utc (); + datetime = g_date_time_new_from_unix (utc, t); + g_time_zone_unref (utc); + + return datetime; +} + +/** + * g_date_time_new_from_timeval_local: + * @tv: a #GTimeVal + * + * Creates a #GDateTime corresponding to the given #GTimeVal @tv in the + * local time zone. + * + * The time contained in a #GTimeVal is always stored in the form of + * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the + * local time offset. + * + * This call can fail (returning %NULL) if @tv represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_from_timeval_local (const GTimeVal *tv) +{ + GDateTime *datetime; + GTimeZone *local; + + local = g_time_zone_new_local (); + datetime = g_date_time_new_from_timeval (local, tv); + g_time_zone_unref (local); + + return datetime; +} + +/** + * g_date_time_new_from_timeval_utc: + * @tv: a #GTimeVal + * + * Creates a #GDateTime corresponding to the given #GTimeVal @tv in UTC. + * + * The time contained in a #GTimeVal is always stored in the form of + * seconds elapsed since 1970-01-01 00:00:00 UTC. + * + * This call can fail (returning %NULL) if @tv represents a time outside + * of the supported range of #GDateTime. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new_from_timeval_utc (const GTimeVal *tv) +{ + GDateTime *datetime; + GTimeZone *utc; + + utc = g_time_zone_new_utc (); + datetime = g_date_time_new_from_timeval (utc, tv); + g_time_zone_unref (utc); + + return datetime; +} + +/* full new functions {{{1 */ + +/** + * g_date_time_new: + * @tz: a #GTimeZone + * @year: the year component of the date + * @month: the month component of the date + * @day: the day component of the date + * @hour: the hour component of the date + * @minute: the minute component of the date + * @seconds: the number of seconds past the minute + * + * Creates a new #GDateTime corresponding to the given date and time in + * the time zone @tz. + * + * The @year must be between 1 and 9999, @month between 1 and 12 and @day + * between 1 and 28, 29, 30 or 31 depending on the month and the year. + * + * @hour must be between 0 and 23 and @minute must be between 0 and 59. + * + * @seconds must be at least 0.0 and must be strictly less than 60.0. + * It will be rounded down to the nearest microsecond. + * + * If the given time is not representable in the given time zone (for + * example, 02:30 on March 14th 2010 in Toronto, due to daylight savings + * time) then the time will be rounded up to the nearest existing time + * (in this case, 03:00). If this matters to you then you should verify + * the return value for containing the same as the numbers you gave. + * + * In the case that the given time is ambiguous in the given time zone + * (for example, 01:30 on November 7th 2010 in Toronto, due to daylight + * savings time) then the time falling within standard (ie: + * non-daylight) time is taken. + * + * It not considered a programmer error for the values to this function + * to be out of range, but in the case that they are, the function will + * return %NULL. + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_new (GTimeZone *tz, + gint year, + gint month, + gint day, + gint hour, + gint minute, + gdouble seconds) +{ + GDateTime *datetime; + gint64 full_time; + + datetime = g_date_time_alloc (tz); + datetime->days = ymd_to_days (year, month, day); + datetime->usec = (hour * USEC_PER_HOUR) + + (minute * USEC_PER_MINUTE) + + (gint64) (seconds * USEC_PER_SECOND); + + full_time = SEC_PER_DAY * + (ymd_to_days (year, month, day) - UNIX_EPOCH_START) + + SECS_PER_HOUR * hour + + SECS_PER_MINUTE * minute + + (int) seconds; + + datetime->interval = g_time_zone_adjust_time (datetime->tz, + G_TIME_TYPE_STANDARD, + &full_time); + + full_time += UNIX_EPOCH_START * SEC_PER_DAY; + datetime->days = full_time / SEC_PER_DAY; + datetime->usec = (full_time % SEC_PER_DAY) * USEC_PER_SECOND; + datetime->usec += ((int) (seconds * USEC_PER_SECOND)) % USEC_PER_SECOND; + + return datetime; +} + +/** + * g_date_time_new_local: + * @year: the year component of the date + * @month: the month component of the date + * @day: the day component of the date + * @hour: the hour component of the date + * @minute: the minute component of the date + * @seconds: the number of seconds past the minute + * + * Creates a new #GDateTime corresponding to the given date and time in + * the local time zone. + * + * This call is equivalent to calling g_date_time_new() with the time + * zone returned by g_time_zone_new_local(). + * + * Returns: a #GDateTime, or %NULL + * + * Since: 2.26. + **/ +GDateTime * +g_date_time_new_local (gint year, + gint month, + gint day, + gint hour, + gint minute, + gdouble seconds) +{ + GDateTime *datetime; + GTimeZone *local; + + local = g_time_zone_new_local (); + datetime = g_date_time_new (local, year, month, day, hour, minute, seconds); + g_time_zone_unref (local); + + return datetime; +} + +/** + * g_date_time_new_utc: + * @year: the year component of the date + * @month: the month component of the date + * @day: the day component of the date + * @hour: the hour component of the date + * @minute: the minute component of the date + * @seconds: the number of seconds past the minute + * + * Creates a new #GDateTime corresponding to the given date and time in + * UTC. + * + * This call is equivalent to calling g_date_time_new() with the time + * zone returned by g_time_zone_new_utc(). + * + * Returns: a #GDateTime, or %NULL + * + * Since: 2.26. + **/ +GDateTime * +g_date_time_new_utc (gint year, + gint month, + gint day, + gint hour, + gint minute, + gdouble seconds) +{ + GDateTime *datetime; + GTimeZone *utc; + + utc = g_time_zone_new_utc (); + datetime = g_date_time_new (utc, year, month, day, hour, minute, seconds); + g_time_zone_unref (utc); + + return datetime; +} + +/* Adders {{{1 */ + +/** + * g_date_time_add: + * @datetime: a #GDateTime + * @timespan: a #GTimeSpan + * + * Creates a copy of @datetime and adds the specified timespan to the copy. + * + * Return value: the newly created #GDateTime which should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime* +g_date_time_add (GDateTime *datetime, + GTimeSpan timespan) +{ + return g_date_time_from_instant (datetime->tz, timespan + + g_date_time_to_instant (datetime)); +} + +/** + * g_date_time_add_years: + * @datetime: a #GDateTime + * @years: the number of years + * + * Creates a copy of @datetime and adds the specified number of years to the + * copy. + * + * Return value: the newly created #GDateTime which should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime * +g_date_time_add_years (GDateTime *datetime, + gint years) +{ + gint year, month, day; + + g_return_val_if_fail (datetime != NULL, NULL); + + if (years < -10000 || years > 10000) + return NULL; + + g_date_time_get_ymd (datetime, &year, &month, &day); + year += years; + + /* only possible issue is if we've entered a year with no February 29 + */ + if (month == 2 && day == 29 && !GREGORIAN_LEAP (year)) + day = 28; + + return g_date_time_replace_days (datetime, ymd_to_days (year, month, day)); +} + +/** + * g_date_time_add_months: + * @datetime: a #GDateTime + * @months: the number of months + * + * Creates a copy of @datetime and adds the specified number of months to the + * copy. + * + * Return value: the newly created #GDateTime which should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime* +g_date_time_add_months (GDateTime *datetime, + gint months) +{ + gint year, month, day; + + g_return_val_if_fail (datetime != NULL, NULL); + g_date_time_get_ymd (datetime, &year, &month, &day); + + if (months < -120000 || months > 120000) + return NULL; + + year += months / 12; + month += months % 12; + if (month < 1) + { + month += 12; + year--; + } + else if (month > 12) + { + month -= 12; + year++; + } + + day = MIN (day, days_in_months[GREGORIAN_LEAP (year)][month]); + + return g_date_time_replace_days (datetime, ymd_to_days (year, month, day)); +} + +/** + * g_date_time_add_weeks: + * @datetime: a #GDateTime + * @weeks: the number of weeks + * + * Creates a copy of @datetime and adds the specified number of weeks to the + * copy. + * + * Return value: the newly created #GDateTime which should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime* +g_date_time_add_weeks (GDateTime *datetime, + gint weeks) +{ + g_return_val_if_fail (datetime != NULL, NULL); + + return g_date_time_add_days (datetime, weeks * 7); +} + +/** + * g_date_time_add_days: + * @datetime: a #GDateTime + * @days: the number of days + * + * Creates a copy of @datetime and adds the specified number of days to the + * copy. + * + * Return value: the newly created #GDateTime which should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime* +g_date_time_add_days (GDateTime *datetime, + gint days) +{ + g_return_val_if_fail (datetime != NULL, NULL); + + if (days < -3660000 || days > 3660000) + return NULL; + + return g_date_time_replace_days (datetime, datetime->days + days); +} + +/** + * g_date_time_add_hours: + * @datetime: a #GDateTime + * @hours: the number of hours to add + * + * Creates a copy of @datetime and adds the specified number of hours + * + * Return value: the newly created #GDateTime which should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime* +g_date_time_add_hours (GDateTime *datetime, + gint hours) +{ + return g_date_time_add (datetime, hours * USEC_PER_HOUR); +} + +/** + * g_date_time_add_minutes: + * @datetime: a #GDateTime + * @minutes: the number of minutes to add + * + * Creates a copy of @datetime adding the specified number of minutes. + * + * Return value: the newly created #GDateTime which should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime* +g_date_time_add_minutes (GDateTime *datetime, + gint minutes) +{ + return g_date_time_add (datetime, minutes * USEC_PER_MINUTE); +} + + +/** + * g_date_time_add_seconds: + * @datetime: a #GDateTime + * @seconds: the number of seconds to add + * + * Creates a copy of @datetime and adds the specified number of seconds. + * + * Return value: the newly created #GDateTime which should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime* +g_date_time_add_seconds (GDateTime *datetime, + gdouble seconds) +{ + return g_date_time_add (datetime, seconds * USEC_PER_SECOND); +} + +/** + * g_date_time_add_full: + * @datetime: a #GDateTime + * @years: the number of years to add + * @months: the number of months to add + * @days: the number of days to add + * @hours: the number of hours to add + * @minutes: the number of minutes to add + * @seconds: the number of seconds to add + * + * Creates a new #GDateTime adding the specified values to the current date and + * time in @datetime. + * + * Return value: the newly created #GDateTime that should be freed with + * g_date_time_unref(). + * + * Since: 2.26 + */ +GDateTime * +g_date_time_add_full (GDateTime *datetime, + gint years, + gint months, + gint days, + gint hours, + gint minutes, + gdouble seconds) +{ + gint year, month, day; + gint64 full_time; + GDateTime *new; + gint interval; + + g_return_val_if_fail (datetime != NULL, NULL); + g_date_time_get_ymd (datetime, &year, &month, &day); + + months += years * 12; + + if (months < -120000 || months > 120000) + return NULL; + + if (days < -3660000 || days > 3660000) + return NULL; + + year += months / 12; + month += months % 12; + if (month < 1) + { + month += 12; + year--; + } + else if (month > 12) + { + month -= 12; + year++; + } + + day = MIN (day, days_in_months[GREGORIAN_LEAP (year)][month]); + + /* full_time is now in unix (local) time */ + full_time = datetime->usec / USEC_PER_SECOND + SEC_PER_DAY * + (ymd_to_days (year, month, day) + days - UNIX_EPOCH_START); + + interval = g_time_zone_adjust_time (datetime->tz, + g_time_zone_is_dst (datetime->tz, + datetime->interval), + &full_time); + + /* move to UTC unix time */ + full_time -= g_time_zone_get_offset (datetime->tz, interval); + + /* convert back to an instant, add back fractional seconds */ + full_time += UNIX_EPOCH_START * SEC_PER_DAY; + full_time = full_time * USEC_PER_SECOND + + datetime->usec % USEC_PER_SECOND; + + /* do the actual addition now */ + full_time += (hours * USEC_PER_HOUR) + + (minutes * USEC_PER_MINUTE) + + (gint64) (seconds * USEC_PER_SECOND); + + /* find the new interval */ + interval = g_time_zone_find_interval (datetime->tz, + G_TIME_TYPE_UNIVERSAL, + INSTANT_TO_UNIX (full_time)); + + /* convert back into local time */ + full_time += USEC_PER_SECOND * + g_time_zone_get_offset (datetime->tz, interval); + + /* split into days and usec of a new datetime */ + new = g_date_time_alloc (datetime->tz); + new->interval = interval; + new->days = full_time / USEC_PER_DAY; + new->usec = full_time % USEC_PER_DAY; + + /* XXX validate */ + + return new; +} + +/* Compare, difference, hash, equal {{{1 */ +/** + * g_date_time_compare: + * @dt1: first #GDateTime to compare + * @dt2: second #GDateTime to compare + * + * A comparison function for #GDateTimes that is suitable + * as a #GCompareFunc. Both #GDateTimes must be non-%NULL. + * + * Return value: -1, 0 or 1 if @dt1 is less than, equal to or greater + * than @dt2. + * + * Since: 2.26 + */ +gint +g_date_time_compare (gconstpointer dt1, + gconstpointer dt2) +{ + gint64 difference; + + difference = g_date_time_difference ((GDateTime *) dt1, (GDateTime *) dt2); + + if (difference < 0) + return -1; + + else if (difference > 0) + return 1; + + else + return 0; +} + +/** + * g_date_time_difference: + * @end: a #GDateTime + * @begin: a #GDateTime + * + * Calculates the difference in time between @end and @begin. The + * #GTimeSpan that is returned is effectively @end - @begin (ie: + * positive if the first simparameter is larger). + * + * Return value: the difference between the two #GDateTime, as a time + * span expressed in microseconds. + * + * Since: 2.26 + */ +GTimeSpan +g_date_time_difference (GDateTime *end, + GDateTime *begin) +{ + g_return_val_if_fail (begin != NULL, 0); + g_return_val_if_fail (end != NULL, 0); + + return g_date_time_to_instant (end) - + g_date_time_to_instant (begin); +} + +/** + * g_date_time_hash: + * @datetime: a #GDateTime + * + * Hashes @datetime into a #guint, suitable for use within #GHashTable. + * + * Return value: a #guint containing the hash + * + * Since: 2.26 + */ +guint +g_date_time_hash (gconstpointer datetime) +{ + return g_date_time_to_instant ((GDateTime *) datetime); +} + +/** + * g_date_time_equal: + * @dt1: a #GDateTime + * @dt2: a #GDateTime + * + * Checks to see if @dt1 and @dt2 are equal. + * + * Equal here means that they represent the same moment after converting + * them to the same time zone. + * + * Return value: %TRUE if @dt1 and @dt2 are equal + * + * Since: 2.26 + */ +gboolean +g_date_time_equal (gconstpointer dt1, + gconstpointer dt2) +{ + return g_date_time_difference ((GDateTime *) dt1, (GDateTime *) dt2) == 0; +} + +/* Year, Month, Day Getters {{{1 */ +/** + * g_date_time_get_ymd: + * @datetime: a #GDateTime. + * @year: (out): the return location for the gregorian year, or %NULL. + * @month: (out): the return location for the month of the year, or %NULL. + * @day: (out): the return location for the day of the month, or %NULL. + * + * Retrieves the Gregorian day, month, and year of a given #GDateTime. + * + * Since: 2.26 + **/ +void +g_date_time_get_ymd (GDateTime *datetime, + gint *year, + gint *month, + gint *day) +{ + gint the_year; + gint the_month; + gint the_day; + gint remaining_days; + gint y100_cycles; + gint y4_cycles; + gint y1_cycles; + gint preceding; + gboolean leap; + + g_return_if_fail (datetime != NULL); + + remaining_days = datetime->days; + + /* + * We need to convert an offset in days to its year/month/day representation. + * Leap years makes this a little trickier than it should be, so we use + * 400, 100 and 4 years cycles here to get to the correct year. + */ + + /* Our days offset starts sets 0001-01-01 as day 1, if it was day 0 our + * math would be simpler, so let's do it */ + remaining_days--; + + the_year = (remaining_days / DAYS_IN_400YEARS) * 400 + 1; + remaining_days = remaining_days % DAYS_IN_400YEARS; + + y100_cycles = remaining_days / DAYS_IN_100YEARS; + remaining_days = remaining_days % DAYS_IN_100YEARS; + the_year += y100_cycles * 100; + + y4_cycles = remaining_days / DAYS_IN_4YEARS; + remaining_days = remaining_days % DAYS_IN_4YEARS; + the_year += y4_cycles * 4; + + y1_cycles = remaining_days / 365; + the_year += y1_cycles; + remaining_days = remaining_days % 365; + + if (y1_cycles == 4 || y100_cycles == 4) { + g_assert (remaining_days == 0); + + /* special case that indicates that the date is actually one year before, + * in the 31th of December */ + the_year--; + the_month = 12; + the_day = 31; + goto end; + } + + /* now get the month and the day */ + leap = y1_cycles == 3 && (y4_cycles != 24 || y100_cycles == 3); + + g_assert (leap == GREGORIAN_LEAP(the_year)); + + the_month = (remaining_days + 50) >> 5; + preceding = (days_in_year[0][the_month - 1] + (the_month > 2 && leap)); + if (preceding > remaining_days) + { + /* estimate is too large */ + the_month -= 1; + preceding -= leap ? days_in_months[1][the_month] + : days_in_months[0][the_month]; + } + + remaining_days -= preceding; + g_assert(0 <= remaining_days); + + the_day = remaining_days + 1; + +end: + if (year) + *year = the_year; + if (month) + *month = the_month; + if (day) + *day = the_day; +} + +/** + * g_date_time_get_year: + * @datetime: A #GDateTime + * + * Retrieves the year represented by @datetime in the Gregorian calendar. + * + * Return value: the year represented by @datetime + * + * Since: 2.26 + */ +gint +g_date_time_get_year (GDateTime *datetime) +{ + gint year; + + g_return_val_if_fail (datetime != NULL, 0); + + g_date_time_get_ymd (datetime, &year, NULL, NULL); + + return year; +} + +/** + * g_date_time_get_month: + * @datetime: a #GDateTime + * + * Retrieves the month of the year represented by @datetime in the Gregorian + * calendar. + * + * Return value: the month represented by @datetime + * + * Since: 2.26 + */ +gint +g_date_time_get_month (GDateTime *datetime) +{ + gint month; + + g_return_val_if_fail (datetime != NULL, 0); + + g_date_time_get_ymd (datetime, NULL, &month, NULL); + + return month; +} + +/** + * g_date_time_get_day_of_month: + * @datetime: a #GDateTime + * + * Retrieves the day of the month represented by @datetime in the gregorian + * calendar. + * + * Return value: the day of the month + * + * Since: 2.26 + */ +gint +g_date_time_get_day_of_month (GDateTime *datetime) +{ + gint day_of_year, + i; + const guint16 *days; + guint16 last = 0; + + g_return_val_if_fail (datetime != NULL, 0); + + days = days_in_year[GREGORIAN_LEAP (g_date_time_get_year (datetime)) ? 1 : 0]; + g_date_time_get_week_number (datetime, NULL, NULL, &day_of_year); + + for (i = 1; i <= 12; i++) + { + if (days [i] >= day_of_year) + return day_of_year - last; + last = days [i]; + } + + g_warn_if_reached (); + return 0; +} + +/* Week of year / day of week getters {{{1 */ +/** + * g_date_time_get_week_numbering_year: + * @datetime: a #GDateTime + * + * Returns the ISO 8601 week-numbering year in which the week containing + * @datetime falls. + * + * This function, taken together with g_date_time_get_week_of_year() and + * g_date_time_get_day_of_week() can be used to determine the full ISO + * week date on which @datetime falls. + * + * This is usually equal to the normal Gregorian year (as returned by + * g_date_time_get_year()), except as detailed below: + * + * For Thursday, the week-numbering year is always equal to the usual + * calendar year. For other days, the number is such that every day + * within a complete week (Monday to Sunday) is contained within the + * same week-numbering year. + * + * For Monday, Tuesday and Wednesday occurring near the end of the year, + * this may mean that the week-numbering year is one greater than the + * calendar year (so that these days have the same week-numbering year + * as the Thursday occurring early in the next year). + * + * For Friday, Saturaday and Sunday occurring near the start of the year, + * this may mean that the week-numbering year is one less than the + * calendar year (so that these days have the same week-numbering year + * as the Thursday occurring late in the previous year). + * + * An equivalent description is that the week-numbering year is equal to + * the calendar year containing the majority of the days in the current + * week (Monday to Sunday). + * + * Note that January 1 0001 in the proleptic Gregorian calendar is a + * Monday, so this function never returns 0. + * + * Returns: the ISO 8601 week-numbering year for @datetime + * + * Since: 2.26 + **/ +gint +g_date_time_get_week_numbering_year (GDateTime *datetime) +{ + gint year, month, day, weekday; + + g_date_time_get_ymd (datetime, &year, &month, &day); + weekday = g_date_time_get_day_of_week (datetime); + + /* January 1, 2, 3 might be in the previous year if they occur after + * Thursday. + * + * Jan 1: Friday, Saturday, Sunday => day 1: weekday 5, 6, 7 + * Jan 2: Saturday, Sunday => day 2: weekday 6, 7 + * Jan 3: Sunday => day 3: weekday 7 + * + * So we have a special case if (day - weekday) <= -4 + */ + if (month == 1 && (day - weekday) <= -4) + return year - 1; + + /* December 29, 30, 31 might be in the next year if they occur before + * Thursday. + * + * Dec 31: Monday, Tuesday, Wednesday => day 31: weekday 1, 2, 3 + * Dec 30: Monday, Tuesday => day 30: weekday 1, 2 + * Dec 29: Monday => day 29: weekday 1 + * + * So we have a special case if (day - weekday) >= 28 + */ + else if (month == 12 && (day - weekday) >= 28) + return year + 1; + + else + return year; +} + +/** + * g_date_time_get_week_of_year: + * @datetime: a #GDateTime + * + * Returns the ISO 8601 week number for the week containing @datetime. + * The ISO 8601 week number is the same for every day of the week (from + * Moday through Sunday). That can produce some unusual results + * (described below). + * + * The first week of the year is week 1. This is the week that contains + * the first Thursday of the year. Equivalently, this is the first week + * that has more than 4 of its days falling within the calendar year. + * + * The value 0 is never returned by this function. Days contained + * within a year but occurring before the first ISO 8601 week of that + * year are considered as being contained in the last week of the + * previous year. Similarly, the final days of a calendar year may be + * considered as being part of the first ISO 8601 week of the next year + * if 4 or more days of that week are contained within the new year. + * + * Returns: the ISO 8601 week number for @datetime. + * + * Since: 2.26 + */ +gint +g_date_time_get_week_of_year (GDateTime *datetime) +{ + gint weeknum; + + g_return_val_if_fail (datetime != NULL, 0); + + g_date_time_get_week_number (datetime, &weeknum, NULL, NULL); + + return weeknum; +} + +/** + * g_date_time_get_day_of_week: + * @datetime: a #GDateTime + * + * Retrieves the ISO 8601 day of the week on which @datetime falls (1 is + * Monday, 2 is Tuesday... 7 is Sunday). + * + * Return value: the day of the week + * + * Since: 2.26 + */ +gint +g_date_time_get_day_of_week (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, 0); + + return (datetime->days - 1) % 7 + 1; +} + +/* Day of year getter {{{1 */ +/** + * g_date_time_get_day_of_year: + * @datetime: a #GDateTime + * + * Retrieves the day of the year represented by @datetime in the Gregorian + * calendar. + * + * Return value: the day of the year + * + * Since: 2.26 + */ +gint +g_date_time_get_day_of_year (GDateTime *datetime) +{ + gint doy = 0; + + g_return_val_if_fail (datetime != NULL, 0); + + g_date_time_get_week_number (datetime, NULL, NULL, &doy); + return doy; +} + +/* Time component getters {{{1 */ + +/** + * g_date_time_get_hour: + * @datetime: a #GDateTime + * + * Retrieves the hour of the day represented by @datetime + * + * Return value: the hour of the day + * + * Since: 2.26 + */ +gint +g_date_time_get_hour (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, 0); + + return (datetime->usec / USEC_PER_HOUR); +} + +/** + * g_date_time_get_minute: + * @datetime: a #GDateTime + * + * Retrieves the minute of the hour represented by @datetime + * + * Return value: the minute of the hour + * + * Since: 2.26 + */ +gint +g_date_time_get_minute (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, 0); + + return (datetime->usec % USEC_PER_HOUR) / USEC_PER_MINUTE; +} + +/** + * g_date_time_get_second: + * @datetime: a #GDateTime + * + * Retrieves the second of the minute represented by @datetime + * + * Return value: the second represented by @datetime + * + * Since: 2.26 + */ +gint +g_date_time_get_second (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, 0); + + return (datetime->usec % USEC_PER_MINUTE) / USEC_PER_SECOND; +} + +/** + * g_date_time_get_microsecond: + * @datetime: a #GDateTime + * + * Retrieves the microsecond of the date represented by @datetime + * + * Return value: the microsecond of the second + * + * Since: 2.26 + */ +gint +g_date_time_get_microsecond (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, 0); + + return (datetime->usec % USEC_PER_SECOND); +} + +/** + * g_date_time_get_seconds: + * @datetime: a #GDateTime + * + * Retrieves the number of seconds since the start of the last minute, + * including the fractional part. + * + * Returns: the number of seconds + * + * Since: 2.26 + **/ +gdouble +g_date_time_get_seconds (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, 0); + + return (datetime->usec % USEC_PER_MINUTE) / 1000000.0; +} + +/* Exporters {{{1 */ +/** + * g_date_time_to_unix: + * @datetime: a #GDateTime + * + * Gives the Unix time corresponding to @datetime, rounding down to the + * nearest second. + * + * Unix time is the number of seconds that have elapsed since 1970-01-01 + * 00:00:00 UTC, regardless of the time zone associated with @datetime. + * + * Returns: the Unix time corresponding to @datetime + * + * Since: 2.26 + **/ +gint64 +g_date_time_to_unix (GDateTime *datetime) +{ + return INSTANT_TO_UNIX (g_date_time_to_instant (datetime)); +} + +/** + * g_date_time_to_timeval: + * @datetime: a #GDateTime + * @tv: a #GTimeVal to modify + * + * Stores the instant in time that @datetime represents into @tv. + * + * The time contained in a #GTimeVal is always stored in the form of + * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the time + * zone associated with @datetime. + * + * On systems where 'long' is 32bit (ie: all 32bit systems and all + * Windows systems), a #GTimeVal is incapable of storing the entire + * range of values that #GDateTime is capable of expressing. On those + * systems, this function returns %FALSE to indicate that the time is + * out of range. + * + * On systems where 'long' is 64bit, this function never fails. + * + * Returns: %TRUE if successful, else %FALSE + * + * Since: 2.26 + **/ +gboolean +g_date_time_to_timeval (GDateTime *datetime, + GTimeVal *tv) +{ + tv->tv_sec = INSTANT_TO_UNIX (g_date_time_to_instant (datetime)); + tv->tv_usec = datetime->usec % USEC_PER_SECOND; + + return TRUE; +} + +/* Timezone queries {{{1 */ +/** + * g_date_time_get_utc_offset: + * @datetime: a #GDateTime + * + * Determines the offset to UTC in effect at the time and in the time + * zone of @datetime. + * + * The offset is the number of microseconds that you add to UTC time to + * arrive at local time for the time zone (ie: negative numbers for time + * zones west of GMT, positive numbers for east). + * + * If @datetime represents UTC time, then the offset is always zero. + * + * Returns: the number of microseconds that should be added to UTC to + * get the local time + * + * Since: 2.26 + **/ +GTimeSpan +g_date_time_get_utc_offset (GDateTime *datetime) +{ + gint offset; + + g_return_val_if_fail (datetime != NULL, 0); + + offset = g_time_zone_get_offset (datetime->tz, datetime->interval); + + return (gint64) offset * USEC_PER_SECOND; +} + +/** + * g_date_time_get_timezone_abbreviation: + * @datetime: a #GDateTime + * + * Determines the time zone abbreviation to be used at the time and in + * the time zone of @datetime. + * + * For example, in Toronto this is currently "EST" during the winter + * months and "EDT" during the summer months when daylight savings + * time is in effect. + * + * Returns: (transfer none): the time zone abbreviation. The returned + * string is owned by the #GDateTime and it should not be + * modified or freed + * + * Since: 2.26 + **/ +const gchar * +g_date_time_get_timezone_abbreviation (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, NULL); + + return g_time_zone_get_abbreviation (datetime->tz, datetime->interval); +} + +/** + * g_date_time_is_daylight_savings: + * @datetime: a #GDateTime + * + * Determines if daylight savings time is in effect at the time and in + * the time zone of @datetime. + * + * Returns: %TRUE if daylight savings time is in effect + * + * Since: 2.26 + **/ +gboolean +g_date_time_is_daylight_savings (GDateTime *datetime) +{ + g_return_val_if_fail (datetime != NULL, FALSE); + + return g_time_zone_is_dst (datetime->tz, datetime->interval); +} + +/* Timezone convert {{{1 */ +/** + * g_date_time_to_timezone: + * @datetime: a #GDateTime + * @tz: the new #GTimeZone + * + * Create a new #GDateTime corresponding to the same instant in time as + * @datetime, but in the time zone @tz. + * + * This call can fail in the case that the time goes out of bounds. For + * example, converting 0001-01-01 00:00:00 UTC to a time zone west of + * Greenwich will fail (due to the year 0 being out of range). + * + * You should release the return value by calling g_date_time_unref() + * when you are done with it. + * + * Returns: a new #GDateTime, or %NULL + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_to_timezone (GDateTime *datetime, + GTimeZone *tz) +{ + return g_date_time_from_instant (tz, g_date_time_to_instant (datetime)); +} + +/** + * g_date_time_to_local: + * @datetime: a #GDateTime + * + * Creates a new #GDateTime corresponding to the same instant in time as + * @datetime, but in the local time zone. + * + * This call is equivalent to calling g_date_time_to_timezone() with the + * time zone returned by g_time_zone_new_local(). + * + * Returns: the newly created #GDateTime + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_to_local (GDateTime *datetime) +{ + GDateTime *new; + GTimeZone *local; + + local = g_time_zone_new_local (); + new = g_date_time_to_timezone (datetime, local); + g_time_zone_unref (local); + + return new; +} + +/** + * g_date_time_to_utc: + * @datetime: a #GDateTime + * + * Creates a new #GDateTime corresponding to the same instant in time as + * @datetime, but in UTC. + * + * This call is equivalent to calling g_date_time_to_timezone() with the + * time zone returned by g_time_zone_new_utc(). + * + * Returns: the newly created #GDateTime + * + * Since: 2.26 + **/ +GDateTime * +g_date_time_to_utc (GDateTime *datetime) +{ + GDateTime *new; + GTimeZone *utc; + + utc = g_time_zone_new_utc (); + new = g_date_time_to_timezone (datetime, utc); + g_time_zone_unref (utc); + + return new; +} + +/* Format {{{1 */ + +static void +format_number (GString *str, + gboolean use_alt_digits, + gchar *pad, + gint width, + guint32 number) +{ + const gchar *ascii_digits[10] = { + "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" + }; + const gchar **digits = ascii_digits; + const gchar *tmp[10]; + gint i = 0; + + g_return_if_fail (width <= 10); + +#ifdef HAVE_LANGINFO_OUTDIGIT + if (use_alt_digits) + { + static const gchar *alt_digits[10]; + static gsize initialised; + /* 2^32 has 10 digits */ + + if G_UNLIKELY (g_once_init_enter (&initialised)) + { +#define DO_DIGIT(n) \ + alt_digits[n] = nl_langinfo (_NL_CTYPE_OUTDIGIT## n ##_MB) + DO_DIGIT(0); DO_DIGIT(1); DO_DIGIT(2); DO_DIGIT(3); DO_DIGIT(4); + DO_DIGIT(5); DO_DIGIT(6); DO_DIGIT(7); DO_DIGIT(8); DO_DIGIT(9); +#undef DO_DIGIT + g_once_init_leave (&initialised, TRUE); + } + + digits = alt_digits; + } +#endif /* HAVE_LANGINFO_OUTDIGIT */ + + do + { + tmp[i++] = digits[number % 10]; + number /= 10; + } + while (number); + + while (pad && i < width) + tmp[i++] = *pad == '0' ? digits[0] : pad; + + /* should really be impossible */ + g_assert (i <= 10); + + while (i) + g_string_append (str, tmp[--i]); +} + +static gboolean g_date_time_format_locale (GDateTime *datetime, + const gchar *format, + GString *outstr, + gboolean locale_is_utf8); + +/* g_date_time_format() subroutine that takes a locale-encoded format + * string and produces a locale-encoded date/time string. + */ +static gboolean +g_date_time_locale_format_locale (GDateTime *datetime, + const gchar *format, + GString *outstr, + gboolean locale_is_utf8) +{ + gchar *utf8_format; + gboolean success; + + if (locale_is_utf8) + return g_date_time_format_locale (datetime, format, outstr, + locale_is_utf8); + + utf8_format = g_locale_to_utf8 (format, -1, NULL, NULL, NULL); + if (!utf8_format) + return FALSE; + + success = g_date_time_format_locale (datetime, utf8_format, outstr, + locale_is_utf8); + g_free (utf8_format); + return success; +} + +/* g_date_time_format() subroutine that takes a UTF-8 format + * string and produces a locale-encoded date/time string. + */ +static gboolean +g_date_time_format_locale (GDateTime *datetime, + const gchar *format, + GString *outstr, + gboolean locale_is_utf8) +{ + guint len; + gchar *tmp; + gunichar c; + gboolean alt_digits = FALSE; + gboolean pad_set = FALSE; + gchar *pad = ""; + gchar *ampm; + const gchar *tz; + + while (*format) + { + len = strcspn (format, "%"); + if (len) + { + if (locale_is_utf8) + g_string_append_len (outstr, format, len); + else + { + tmp = g_locale_from_utf8 (format, len, NULL, NULL, NULL); + if (!tmp) + return FALSE; + g_string_append (outstr, tmp); + g_free (tmp); + } + } + + format += len; + if (!*format) + break; + + g_assert (*format == '%'); + format++; + if (!*format) + break; + + alt_digits = FALSE; + pad_set = FALSE; + + next_mod: + c = g_utf8_get_char (format); + format = g_utf8_next_char (format); + switch (c) + { + case 'a': + g_string_append (outstr, WEEKDAY_ABBR (datetime)); + break; + case 'A': + g_string_append (outstr, WEEKDAY_FULL (datetime)); + break; + case 'b': + g_string_append (outstr, MONTH_ABBR (datetime)); + break; + case 'B': + g_string_append (outstr, MONTH_FULL (datetime)); + break; + case 'c': + { + if (!g_date_time_locale_format_locale (datetime, PREFERRED_DATE_TIME_FMT, + outstr, locale_is_utf8)) + return FALSE; + } + break; + case 'C': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_year (datetime) / 100); + break; + case 'd': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_day_of_month (datetime)); + break; + case 'e': + format_number (outstr, alt_digits, pad_set ? pad : " ", 2, + g_date_time_get_day_of_month (datetime)); + break; + case 'F': + g_string_append_printf (outstr, "%d-%02d-%02d", + g_date_time_get_year (datetime), + g_date_time_get_month (datetime), + g_date_time_get_day_of_month (datetime)); + break; + case 'g': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_week_numbering_year (datetime) % 100); + break; + case 'G': + format_number (outstr, alt_digits, pad_set ? pad : 0, 0, + g_date_time_get_week_numbering_year (datetime)); + break; + case 'h': + g_string_append (outstr, MONTH_ABBR (datetime)); + break; + case 'H': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_hour (datetime)); + break; + case 'I': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + (g_date_time_get_hour (datetime) + 11) % 12 + 1); + break; + case 'j': + format_number (outstr, alt_digits, pad_set ? pad : "0", 3, + g_date_time_get_day_of_year (datetime)); + break; + case 'k': + format_number (outstr, alt_digits, pad_set ? pad : " ", 2, + g_date_time_get_hour (datetime)); + break; + case 'l': + format_number (outstr, alt_digits, pad_set ? pad : " ", 2, + (g_date_time_get_hour (datetime) + 11) % 12 + 1); + break; + case 'n': + g_string_append_c (outstr, '\n'); + break; + case 'm': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_month (datetime)); + break; + case 'M': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_minute (datetime)); + break; + case 'O': + alt_digits = TRUE; + goto next_mod; + case 'p': + ampm = GET_AMPM (datetime); + if (!locale_is_utf8) + { + ampm = tmp = g_locale_to_utf8 (ampm, -1, NULL, NULL, NULL); + if (!tmp) + return FALSE; + } + ampm = g_utf8_strup (ampm, -1); + if (!locale_is_utf8) + { + g_free (tmp); + tmp = g_locale_from_utf8 (ampm, -1, NULL, NULL, NULL); + g_free (ampm); + if (!tmp) + return FALSE; + ampm = tmp; + } + g_string_append (outstr, ampm); + g_free (ampm); + break; + case 'P': + ampm = GET_AMPM (datetime); + if (!locale_is_utf8) + { + ampm = tmp = g_locale_to_utf8 (ampm, -1, NULL, NULL, NULL); + if (!tmp) + return FALSE; + } + ampm = g_utf8_strdown (ampm, -1); + if (!locale_is_utf8) + { + g_free (tmp); + tmp = g_locale_from_utf8 (ampm, -1, NULL, NULL, NULL); + g_free (ampm); + if (!tmp) + return FALSE; + ampm = tmp; + } + g_string_append (outstr, ampm); + g_free (ampm); + break; + case 'r': + { + if (!g_date_time_locale_format_locale (datetime, PREFERRED_12HR_TIME_FMT, + outstr, locale_is_utf8)) + return FALSE; + } + break; + case 'R': + g_string_append_printf (outstr, "%02d:%02d", + g_date_time_get_hour (datetime), + g_date_time_get_minute (datetime)); + break; + case 's': + g_string_append_printf (outstr, "%" G_GINT64_FORMAT, g_date_time_to_unix (datetime)); + break; + case 'S': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_second (datetime)); + break; + case 't': + g_string_append_c (outstr, '\t'); + break; + case 'T': + g_string_append_printf (outstr, "%02d:%02d:%02d", + g_date_time_get_hour (datetime), + g_date_time_get_minute (datetime), + g_date_time_get_second (datetime)); + break; + case 'u': + format_number (outstr, alt_digits, 0, 0, + g_date_time_get_day_of_week (datetime)); + break; + case 'V': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_week_of_year (datetime)); + break; + case 'w': + format_number (outstr, alt_digits, 0, 0, + g_date_time_get_day_of_week (datetime) % 7); + break; + case 'x': + { + if (!g_date_time_locale_format_locale (datetime, PREFERRED_DATE_FMT, + outstr, locale_is_utf8)) + return FALSE; + } + break; + case 'X': + { + if (!g_date_time_locale_format_locale (datetime, PREFERRED_TIME_FMT, + outstr, locale_is_utf8)) + return FALSE; + } + break; + case 'y': + format_number (outstr, alt_digits, pad_set ? pad : "0", 2, + g_date_time_get_year (datetime) % 100); + break; + case 'Y': + format_number (outstr, alt_digits, 0, 0, + g_date_time_get_year (datetime)); + break; + case 'z': + if (datetime->tz != NULL) + { + gint64 offset = g_date_time_get_utc_offset (datetime) + / USEC_PER_SECOND; + + g_string_append_printf (outstr, "%+03d%02d", + (int) offset / 3600, + (int) abs(offset) / 60 % 60); + } + else + g_string_append (outstr, "+0000"); + break; + case 'Z': + tz = g_date_time_get_timezone_abbreviation (datetime); + if (!locale_is_utf8) + { + tz = tmp = g_locale_from_utf8 (tz, -1, NULL, NULL, NULL); + if (!tmp) + return FALSE; + } + g_string_append (outstr, tz); + if (!locale_is_utf8) + g_free (tmp); + break; + case '%': + g_string_append_c (outstr, '%'); + break; + case '-': + pad_set = TRUE; + pad = ""; + goto next_mod; + case '_': + pad_set = TRUE; + pad = " "; + goto next_mod; + case '0': + pad_set = TRUE; + pad = "0"; + goto next_mod; + default: + return FALSE; + } + } + + return TRUE; +} + +/** + * g_date_time_format: + * @datetime: A #GDateTime + * @format: a valid UTF-8 string, containing the format for the + * #GDateTime + * + * Creates a newly allocated string representing the requested @format. + * + * The format strings understood by this function are a subset of the + * strftime() format language as specified by C99. The \%D, \%U and \%W + * conversions are not supported, nor is the 'E' modifier. The GNU + * extensions \%k, \%l, \%s and \%P are supported, however, as are the + * '0', '_' and '-' modifiers. + * + * In contrast to strftime(), this function always produces a UTF-8 + * string, regardless of the current locale. Note that the rendering of + * many formats is locale-dependent and may not match the strftime() + * output exactly. + * + * The following format specifiers are supported: + * + * + * + * \%a: + * + * the abbreviated weekday name according to the current locale + * + * + * \%A: + * + * the full weekday name according to the current locale + * + * + * \%b: + * + * the abbreviated month name according to the current locale + * + * + * \%B: + * + * the full month name according to the current locale + * + * + * \%c: + * + * the preferred date and time representation for the current locale + * + * + * \%C: + * + * The century number (year/100) as a 2-digit integer (00-99) + * + * + * \%d: + * + * the day of the month as a decimal number (range 01 to 31) + * + * + * \%e: + * + * the day of the month as a decimal number (range 1 to 31) + * + * + * \%F: + * + * equivalent to \%Y-\%m-\%d (the ISO 8601 date + * format) + * + * + * \%g: + * + * the last two digits of the ISO 8601 week-based year as a decimal + * number (00-99). This works well with \%V and \%u. + * + * + * \%G: + * + * the ISO 8601 week-based year as a decimal number. This works well + * with \%V and \%u. + * + * + * \%h: + * + * equivalent to \%b + * + * + * \%H: + * + * the hour as a decimal number using a 24-hour clock (range 00 to + * 23) + * + * + * \%I: + * + * the hour as a decimal number using a 12-hour clock (range 01 to + * 12) + * + * + * \%j: + * + * the day of the year as a decimal number (range 001 to 366) + * + * + * \%k: + * + * the hour (24-hour clock) as a decimal number (range 0 to 23); + * single digits are preceded by a blank + * + * + * \%l: + * + * the hour (12-hour clock) as a decimal number (range 1 to 12); + * single digits are preceded by a blank + * + * + * \%m: + * + * the month as a decimal number (range 01 to 12) + * + * + * \%M: + * + * the minute as a decimal number (range 00 to 59) + * + * + * \%p: + * + * either "AM" or "PM" according to the given time value, or the + * corresponding strings for the current locale. Noon is treated as + * "PM" and midnight as "AM". + * + * + * \%P: + * + * like \%p but lowercase: "am" or "pm" or a corresponding string for + * the current locale + * + * + * \%r: + * + * the time in a.m. or p.m. notation + * + * + * \%R: + * + * the time in 24-hour notation (\%H:\%M) + * + * + * \%s: + * + * the number of seconds since the Epoch, that is, since 1970-01-01 + * 00:00:00 UTC + * + * + * \%S: + * + * the second as a decimal number (range 00 to 60) + * + * + * \%t: + * + * a tab character + * + * + * \%T: + * + * the time in 24-hour notation with seconds (\%H:\%M:\%S) + * + * + * \%u: + * + * the ISO 8601 standard day of the week as a decimal, range 1 to 7, + * Monday being 1. This works well with \%G and \%V. + * + * + * \%V: + * + * the ISO 8601 standard week number of the current year as a decimal + * number, range 01 to 53, where week 1 is the first week that has at + * least 4 days in the new year. See g_date_time_get_week_of_year(). + * This works well with \%G and \%u. + * + * + * \%w: + * + * the day of the week as a decimal, range 0 to 6, Sunday being 0. + * This is not the ISO 8601 standard format -- use \%u instead. + * + * + * \%x: + * + * the preferred date representation for the current locale without + * the time + * + * + * \%X: + * + * the preferred time representation for the current locale without + * the date + * + * + * \%y: + * + * the year as a decimal number without the century + * + * + * \%Y: + * + * the year as a decimal number including the century + * + * + * \%z: + * + * the time-zone as hour offset from UTC + * + * + * \%Z: + * + * the time zone or name or abbreviation + * + * + * \%\%: + * + * a literal \% character + * + * + * + * Some conversion specifications can be modified by preceding the + * conversion specifier by one or more modifier characters. The + * following modifiers are supported for many of the numeric + * conversions: + * + * + * O + * + * Use alternative numeric symbols, if the current locale + * supports those. + * + * + * + * _ + * + * Pad a numeric result with spaces. + * This overrides the default padding for the specifier. + * + * + * + * - + * + * Do not pad a numeric result. + * This overrides the default padding for the specifier. + * + * + * + * 0 + * + * Pad a numeric result with zeros. + * This overrides the default padding for the specifier. + * + * + * + * + * Returns: a newly allocated string formatted to the requested format + * or %NULL in the case that there was an error. The string + * should be freed with g_free(). + * + * Since: 2.26 + */ +gchar * +g_date_time_format (GDateTime *datetime, + const gchar *format) +{ + GString *outstr; + gchar *utf8; + gboolean locale_is_utf8 = g_get_charset (NULL); + + g_return_val_if_fail (datetime != NULL, NULL); + g_return_val_if_fail (format != NULL, NULL); + g_return_val_if_fail (g_utf8_validate (format, -1, NULL), NULL); + + outstr = g_string_sized_new (strlen (format) * 2); + + if (!g_date_time_format_locale (datetime, format, outstr, locale_is_utf8)) + { + g_string_free (outstr, TRUE); + return NULL; + } + + if (locale_is_utf8) + return g_string_free (outstr, FALSE); + + utf8 = g_locale_to_utf8 (outstr->str, outstr->len, NULL, NULL, NULL); + g_string_free (outstr, TRUE); + return utf8; +} + + +/* Epilogue {{{1 */ +/* vim:set foldmethod=marker: */ diff --git a/glib/glib/gdatetime.h b/glib/glib/gdatetime.h new file mode 100644 index 0000000..6643e3f --- /dev/null +++ b/glib/glib/gdatetime.h @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2009-2010 Christian Hergert + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of the + * licence, or (at your option) any later version. + * + * This 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 Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 + * USA. + * + * Authors: Christian Hergert + * Thiago Santos + * Emmanuele Bassi + * Ryan Lortie + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_DATE_TIME_H__ +#define __G_DATE_TIME_H__ + +#include + +G_BEGIN_DECLS + +/** + * G_TIME_SPAN_DAY: + * + * Evaluates to a time span of one day. + * + * Since: 2.26 + */ +#define G_TIME_SPAN_DAY (G_GINT64_CONSTANT (86400000000)) + +/** + * G_TIME_SPAN_HOUR: + * + * Evaluates to a time span of one hour. + * + * Since: 2.26 + */ +#define G_TIME_SPAN_HOUR (G_GINT64_CONSTANT (3600000000)) + +/** + * G_TIME_SPAN_MINUTE: + * + * Evaluates to a time span of one minute. + * + * Since: 2.26 + */ +#define G_TIME_SPAN_MINUTE (G_GINT64_CONSTANT (60000000)) + +/** + * G_TIME_SPAN_SECOND: + * + * Evaluates to a time span of one second. + * + * Since: 2.26 + */ +#define G_TIME_SPAN_SECOND (G_GINT64_CONSTANT (1000000)) + +/** + * G_TIME_SPAN_MILLISECOND: + * + * Evaluates to a time span of one millisecond. + * + * Since: 2.26 + */ +#define G_TIME_SPAN_MILLISECOND (G_GINT64_CONSTANT (1000)) + +/** + * GTimeSpan: + * + * A value representing an interval of time, in microseconds. + * + * Since: 2.26 + */ +typedef gint64 GTimeSpan; + +/** + * GDateTime: + * + * GDateTime is an opaque structure whose members + * cannot be accessed directly. + * + * Since: 2.26 + */ +typedef struct _GDateTime GDateTime; + +void g_date_time_unref (GDateTime *datetime); +GDateTime * g_date_time_ref (GDateTime *datetime); + +GDateTime * g_date_time_new_now (GTimeZone *tz); +GDateTime * g_date_time_new_now_local (void); +GDateTime * g_date_time_new_now_utc (void); + +GDateTime * g_date_time_new_from_unix_local (gint64 t); +GDateTime * g_date_time_new_from_unix_utc (gint64 t); + +GDateTime * g_date_time_new_from_timeval_local (const GTimeVal *tv); +GDateTime * g_date_time_new_from_timeval_utc (const GTimeVal *tv); + +GDateTime * g_date_time_new (GTimeZone *tz, + gint year, + gint month, + gint day, + gint hour, + gint minute, + gdouble seconds); +GDateTime * g_date_time_new_local (gint year, + gint month, + gint day, + gint hour, + gint minute, + gdouble seconds); +GDateTime * g_date_time_new_utc (gint year, + gint month, + gint day, + gint hour, + gint minute, + gdouble seconds); + +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add (GDateTime *datetime, + GTimeSpan timespan); + +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add_years (GDateTime *datetime, + gint years); +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add_months (GDateTime *datetime, + gint months); +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add_weeks (GDateTime *datetime, + gint weeks); +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add_days (GDateTime *datetime, + gint days); + +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add_hours (GDateTime *datetime, + gint hours); +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add_minutes (GDateTime *datetime, + gint minutes); +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add_seconds (GDateTime *datetime, + gdouble seconds); + +G_GNUC_WARN_UNUSED_RESULT +GDateTime * g_date_time_add_full (GDateTime *datetime, + gint years, + gint months, + gint days, + gint hours, + gint minutes, + gdouble seconds); + +gint g_date_time_compare (gconstpointer dt1, + gconstpointer dt2); +GTimeSpan g_date_time_difference (GDateTime *end, + GDateTime *begin); +guint g_date_time_hash (gconstpointer datetime); +gboolean g_date_time_equal (gconstpointer dt1, + gconstpointer dt2); + +void g_date_time_get_ymd (GDateTime *datetime, + gint *year, + gint *month, + gint *day); + +gint g_date_time_get_year (GDateTime *datetime); +gint g_date_time_get_month (GDateTime *datetime); +gint g_date_time_get_day_of_month (GDateTime *datetime); + +gint g_date_time_get_week_numbering_year (GDateTime *datetime); +gint g_date_time_get_week_of_year (GDateTime *datetime); +gint g_date_time_get_day_of_week (GDateTime *datetime); + +gint g_date_time_get_day_of_year (GDateTime *datetime); + +gint g_date_time_get_hour (GDateTime *datetime); +gint g_date_time_get_minute (GDateTime *datetime); +gint g_date_time_get_second (GDateTime *datetime); +gint g_date_time_get_microsecond (GDateTime *datetime); +gdouble g_date_time_get_seconds (GDateTime *datetime); + +gint64 g_date_time_to_unix (GDateTime *datetime); +gboolean g_date_time_to_timeval (GDateTime *datetime, + GTimeVal *tv); + +GTimeSpan g_date_time_get_utc_offset (GDateTime *datetime); +const gchar * g_date_time_get_timezone_abbreviation (GDateTime *datetime); +gboolean g_date_time_is_daylight_savings (GDateTime *datetime); + +GDateTime * g_date_time_to_timezone (GDateTime *datetime, + GTimeZone *tz); +GDateTime * g_date_time_to_local (GDateTime *datetime); +GDateTime * g_date_time_to_utc (GDateTime *datetime); + +gchar * g_date_time_format (GDateTime *datetime, + const gchar *format) G_GNUC_MALLOC; + +G_END_DECLS + +#endif /* __G_DATE_TIME_H__ */ diff --git a/glib/glib/gdir.c b/glib/glib/gdir.c new file mode 100644 index 0000000..3173ae7 --- /dev/null +++ b/glib/glib/gdir.c @@ -0,0 +1,320 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gdir.c: Simplified wrapper around the DIRENT functions. + * + * Copyright 2001 Hans Breuer + * Copyright 2004 Tor Lillqvist + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include + +#ifdef HAVE_DIRENT_H +#include +#include +#endif + +#include "gdir.h" + +#include "gconvert.h" +#include "gfileutils.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "glibintl.h" + + +#if defined (_MSC_VER) && !defined (HAVE_DIRENT_H) +#include "../build/win32/dirent/dirent.h" +#include "../build/win32/dirent/wdirent.c" +#endif + +/** + * GDir: + * + * An opaque structure representing an opened directory. + */ + +struct _GDir +{ +#ifdef G_OS_WIN32 + _WDIR *wdirp; +#else + DIR *dirp; +#endif +#ifdef G_OS_WIN32 + gchar utf8_buf[FILENAME_MAX*4]; +#endif +}; + +/** + * g_dir_open: + * @path: the path to the directory you are interested in. On Unix + * in the on-disk encoding. On Windows in UTF-8 + * @flags: Currently must be set to 0. Reserved for future use. + * @error: return location for a #GError, or %NULL. + * If non-%NULL, an error will be set if and only if + * g_dir_open() fails. + * + * Opens a directory for reading. The names of the files in the + * directory can then be retrieved using g_dir_read_name(). Note + * that the ordering is not defined. + * + * Return value: a newly allocated #GDir on success, %NULL on failure. + * If non-%NULL, you must free the result with g_dir_close() + * when you are finished with it. + **/ +GDir * +g_dir_open (const gchar *path, + guint flags, + GError **error) +{ + GDir *dir; + int errsv; +#ifdef G_OS_WIN32 + wchar_t *wpath; +#else + gchar *utf8_path; +#endif + + g_return_val_if_fail (path != NULL, NULL); + +#ifdef G_OS_WIN32 + wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, error); + + if (wpath == NULL) + return NULL; + + dir = g_new (GDir, 1); + + dir->wdirp = _wopendir (wpath); + g_free (wpath); + + if (dir->wdirp) + return dir; + + /* error case */ + errsv = errno; + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + _("Error opening directory '%s': %s"), + path, g_strerror (errsv)); + + g_free (dir); + + return NULL; +#else + dir = g_new (GDir, 1); + + dir->dirp = opendir (path); + + if (dir->dirp) + return dir; + + /* error case */ + errsv = errno; + + utf8_path = g_filename_to_utf8 (path, -1, + NULL, NULL, NULL); + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (errsv), + _("Error opening directory '%s': %s"), + utf8_path, g_strerror (errsv)); + + g_free (utf8_path); + g_free (dir); + + return NULL; +#endif +} + +#if defined (G_OS_WIN32) && !defined (_WIN64) + +/* The above function actually is called g_dir_open_utf8, and it's + * that what applications compiled with this GLib version will + * use. + */ + +#undef g_dir_open + +/* Binary compatibility version. Not for newly compiled code. */ + +GDir * +g_dir_open (const gchar *path, + guint flags, + GError **error) +{ + gchar *utf8_path = g_locale_to_utf8 (path, -1, NULL, NULL, error); + GDir *retval; + + if (utf8_path == NULL) + return NULL; + + retval = g_dir_open_utf8 (utf8_path, flags, error); + + g_free (utf8_path); + + return retval; +} +#endif + +/** + * g_dir_read_name: + * @dir: a #GDir* created by g_dir_open() + * + * Retrieves the name of another entry in the directory, or %NULL. + * The order of entries returned from this function is not defined, + * and may vary by file system or other operating-system dependent + * factors. + * + * On Unix, the '.' and '..' entries are omitted, and the returned + * name is in the on-disk encoding. + * + * On Windows, as is true of all GLib functions which operate on + * filenames, the returned name is in UTF-8. + * + * Return value: The entry's name or %NULL if there are no + * more entries. The return value is owned by GLib and + * must not be modified or freed. + **/ +const gchar * +g_dir_read_name (GDir *dir) +{ +#ifdef G_OS_WIN32 + gchar *utf8_name; + struct _wdirent *wentry; +#else + struct dirent *entry; +#endif + + g_return_val_if_fail (dir != NULL, NULL); + +#ifdef G_OS_WIN32 + while (1) + { + wentry = _wreaddir (dir->wdirp); + while (wentry + && (0 == wcscmp (wentry->d_name, L".") || + 0 == wcscmp (wentry->d_name, L".."))) + wentry = _wreaddir (dir->wdirp); + + if (wentry == NULL) + return NULL; + + utf8_name = g_utf16_to_utf8 (wentry->d_name, -1, NULL, NULL, NULL); + + if (utf8_name == NULL) + continue; /* Huh, impossible? Skip it anyway */ + + strcpy (dir->utf8_buf, utf8_name); + g_free (utf8_name); + + return dir->utf8_buf; + } +#else + entry = readdir (dir->dirp); + while (entry + && (0 == strcmp (entry->d_name, ".") || + 0 == strcmp (entry->d_name, ".."))) + entry = readdir (dir->dirp); + + if (entry) + return entry->d_name; + else + return NULL; +#endif +} + +#if defined (G_OS_WIN32) && !defined (_WIN64) + +/* Ditto for g_dir_read_name */ + +#undef g_dir_read_name + +/* Binary compatibility version. Not for newly compiled code. */ + +const gchar * +g_dir_read_name (GDir *dir) +{ + while (1) + { + const gchar *utf8_name = g_dir_read_name_utf8 (dir); + gchar *retval; + + if (utf8_name == NULL) + return NULL; + + retval = g_locale_from_utf8 (utf8_name, -1, NULL, NULL, NULL); + + if (retval != NULL) + { + strcpy (dir->utf8_buf, retval); + g_free (retval); + + return dir->utf8_buf; + } + } +} + +#endif + +/** + * g_dir_rewind: + * @dir: a #GDir* created by g_dir_open() + * + * Resets the given directory. The next call to g_dir_read_name() + * will return the first entry again. + **/ +void +g_dir_rewind (GDir *dir) +{ + g_return_if_fail (dir != NULL); + +#ifdef G_OS_WIN32 + _wrewinddir (dir->wdirp); +#else + rewinddir (dir->dirp); +#endif +} + +/** + * g_dir_close: + * @dir: a #GDir* created by g_dir_open() + * + * Closes the directory and deallocates all related resources. + **/ +void +g_dir_close (GDir *dir) +{ + g_return_if_fail (dir != NULL); + +#ifdef G_OS_WIN32 + _wclosedir (dir->wdirp); +#else + closedir (dir->dirp); +#endif + g_free (dir); +} diff --git a/glib/glib/gdir.h b/glib/glib/gdir.h new file mode 100644 index 0000000..79b3038 --- /dev/null +++ b/glib/glib/gdir.h @@ -0,0 +1,54 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gdir.c: Simplified wrapper around the DIRENT functions. + * + * Copyright 2001 Hans Breuer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_DIR_H__ +#define __G_DIR_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GDir GDir; + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +/* For DLL ABI stability, keep old names for old (non-UTF-8) functionality. */ +#define g_dir_open g_dir_open_utf8 +#define g_dir_read_name g_dir_read_name_utf8 +#endif +#endif + +GDir * g_dir_open (const gchar *path, + guint flags, + GError **error); +const gchar * g_dir_read_name (GDir *dir); +void g_dir_rewind (GDir *dir); +void g_dir_close (GDir *dir); + +G_END_DECLS + +#endif /* __G_DIR_H__ */ diff --git a/glib/glib/gen-iswide-table.py b/glib/glib/gen-iswide-table.py new file mode 100755 index 0000000..292addc --- /dev/null +++ b/glib/glib/gen-iswide-table.py @@ -0,0 +1,58 @@ +#!/usr/bin/python + +import sys + +W = {} +W['A'] = [] +W['W'] = [] +W['F'] = W['W'] + +for line in sys.stdin: + i = line.find ('#') + if i >= 0: + line = line[:i] + line = line.strip () + if not len (line): + continue + + fields = [x.strip () for x in line.split (';')] + chars = fields[0] + width = fields[1] + + if width not in ['A', 'W', 'F']: + continue + + if chars.find ('..') > 0: + (start,end) = chars.split ('..') + else: + start = chars + end = chars + start, end = int(start,16), int(end,16) + + for i in range (start, end+1): + W[width].append (i) + + +def write_intervals (S): + S.sort () + start = S[0]; + end = start - 1 + for c in S: + if c == end+1: + end += 1 + continue + else: + print "{0x%04X, 0x%04X}, " % (start, end) + start = c + end = start + print "{0x%04X, 0x%04X} " % (start, end) + + + +print "table for g_unichar_iswide():" +print +write_intervals (W['W']) +print +print "table for g_unichar_iswide_cjk():" +print +write_intervals (W['A']) diff --git a/glib/glib/gen-script-table.pl b/glib/glib/gen-script-table.pl new file mode 100755 index 0000000..27268ab --- /dev/null +++ b/glib/glib/gen-script-table.pl @@ -0,0 +1,119 @@ +#!/usr/bin/perl -w +# +# Script to convert http://www.unicode.org/Public/UNIDATA/Scripts.txt +# into a machine-readable table. +# +###################################################################### + +if (@ARGV != 1) { + die "Usage: gen-script-table.pl Scripts.txt > gscripttable.h\n"; +} + +open IN, $ARGV[0] || die "Cannot open $ARGV[0]: $!\n"; + +my @ranges; +my $file; +my $easy_range; +my $i; +my $start; +my $end; +my $script; + + +while () { + if (/^\#\s+(Scripts-.*.txt)/) { + $file = $1; + } + + s/#.*//; + next if /^\s*$/; + if (!/^([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s*;\s*([A-Za-z_]+)\s*$/) { + die "Cannot parse line: '$_'\n"; + } + + if (defined $2) { + push @ranges, [ hex $1, hex $2, uc $3 ]; + } else { + push @ranges, [ hex $1, hex $1, uc $3 ]; + } +} + +@ranges = sort { $a->[0] <=> $b->[0] } @ranges; +$date = gmtime; + +print <<"EOT"; +/* gscripttable.h: Generated by gen-script-table.pl + * + * Date: $date + * Source: $file + * + * Do not edit. + */ + +EOT + +$easy_range = 0x2000; + +print <<"EOT"; +#define G_EASY_SCRIPTS_RANGE $easy_range + +static const guchar g_script_easy_table[$easy_range] = { +EOT + +$i = 0; +$end = -1; + +for (my $c = 0; $c < $easy_range; $c++) { + + if ($c % 3 == 0) { + printf "\n "; + } + + if ($c > $end) { + $start = $ranges[$i]->[0]; + $end = $ranges[$i]->[1]; + $script = $ranges[$i]->[2]; + $i++; + } + + if ($c < $start) { + printf " G_UNICODE_SCRIPT_UNKNOWN,"; + } else { + printf " G_UNICODE_SCRIPT_%s,", $script; + } +} + +if ($end >= $easy_range) { + $i--; + $ranges[$i]->[0] = $easy_range; +} + + +print <<"EOT"; + +}; + +static const struct { + gunichar start; + guint16 chars; + guint16 script; +} g_script_table[] = { +EOT + +for (; $i <= $#ranges; $i++) { + $start = $ranges[$i]->[0]; + $end = $ranges[$i]->[1]; + $script = $ranges[$i]->[2]; + + while ($i <= $#ranges - 1 && + $ranges[$i + 1]->[0] == $end + 1 && + $ranges[$i + 1]->[2] eq $script) { + $i++; + $end = $ranges[$i]->[1]; + } + + printf " { %#06x, %5d, G_UNICODE_SCRIPT_%s },\n", $start, $end - $start + 1, $script; +} + +printf "};\n"; + diff --git a/glib/glib/gen-unicode-tables.pl b/glib/glib/gen-unicode-tables.pl new file mode 100755 index 0000000..f2b9237 --- /dev/null +++ b/glib/glib/gen-unicode-tables.pl @@ -0,0 +1,1339 @@ +#! /usr/bin/perl -w + +# Copyright (C) 1998, 1999 Tom Tromey +# Copyright (C) 2001 Red Hat Software + +# This program 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 2, or (at your option) +# any later version. + +# This program 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 this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# Contributer(s): +# Andrew Taylor + +# gen-unicode-tables.pl - Generate tables for libunicode from Unicode data. +# See http://www.unicode.org/Public/UNIDATA/UnicodeCharacterDatabase.html +# I consider the output of this program to be unrestricted. Use it as +# you will. + +# FIXME: +# * For decomp table it might make sense to use a shift count other +# than 8. We could easily compute the perfect shift count. + +# we use some perl unicode features +require 5.006; + +use bytes; + +use vars qw($CODE $NAME $CATEGORY $COMBINING_CLASSES $BIDI_CATEGORY $DECOMPOSITION $DECIMAL_VALUE $DIGIT_VALUE $NUMERIC_VALUE $MIRRORED $OLD_NAME $COMMENT $UPPER $LOWER $TITLE $BREAK_CODE $BREAK_CATEGORY $BREAK_NAME $CASE_CODE $CASE_LOWER $CASE_TITLE $CASE_UPPER $CASE_CONDITION); + + +# Names of fields in Unicode data table. +$CODE = 0; +$NAME = 1; +$CATEGORY = 2; +$COMBINING_CLASSES = 3; +$BIDI_CATEGORY = 4; +$DECOMPOSITION = 5; +$DECIMAL_VALUE = 6; +$DIGIT_VALUE = 7; +$NUMERIC_VALUE = 8; +$MIRRORED = 9; +$OLD_NAME = 10; +$COMMENT = 11; +$UPPER = 12; +$LOWER = 13; +$TITLE = 14; + +# Names of fields in the line break table +$BREAK_CODE = 0; +$BREAK_PROPERTY = 1; + +# Names of fields in the SpecialCasing table +$CASE_CODE = 0; +$CASE_LOWER = 1; +$CASE_TITLE = 2; +$CASE_UPPER = 3; +$CASE_CONDITION = 4; + +# Names of fields in the CaseFolding table +$FOLDING_CODE = 0; +$FOLDING_STATUS = 1; +$FOLDING_MAPPING = 2; + +# Map general category code onto symbolic name. +%mappings = + ( + # Normative. + 'Lu' => "G_UNICODE_UPPERCASE_LETTER", + 'Ll' => "G_UNICODE_LOWERCASE_LETTER", + 'Lt' => "G_UNICODE_TITLECASE_LETTER", + 'Mn' => "G_UNICODE_NON_SPACING_MARK", + 'Mc' => "G_UNICODE_SPACING_MARK", + 'Me' => "G_UNICODE_ENCLOSING_MARK", + 'Nd' => "G_UNICODE_DECIMAL_NUMBER", + 'Nl' => "G_UNICODE_LETTER_NUMBER", + 'No' => "G_UNICODE_OTHER_NUMBER", + 'Zs' => "G_UNICODE_SPACE_SEPARATOR", + 'Zl' => "G_UNICODE_LINE_SEPARATOR", + 'Zp' => "G_UNICODE_PARAGRAPH_SEPARATOR", + 'Cc' => "G_UNICODE_CONTROL", + 'Cf' => "G_UNICODE_FORMAT", + 'Cs' => "G_UNICODE_SURROGATE", + 'Co' => "G_UNICODE_PRIVATE_USE", + 'Cn' => "G_UNICODE_UNASSIGNED", + + # Informative. + 'Lm' => "G_UNICODE_MODIFIER_LETTER", + 'Lo' => "G_UNICODE_OTHER_LETTER", + 'Pc' => "G_UNICODE_CONNECT_PUNCTUATION", + 'Pd' => "G_UNICODE_DASH_PUNCTUATION", + 'Ps' => "G_UNICODE_OPEN_PUNCTUATION", + 'Pe' => "G_UNICODE_CLOSE_PUNCTUATION", + 'Pi' => "G_UNICODE_INITIAL_PUNCTUATION", + 'Pf' => "G_UNICODE_FINAL_PUNCTUATION", + 'Po' => "G_UNICODE_OTHER_PUNCTUATION", + 'Sm' => "G_UNICODE_MATH_SYMBOL", + 'Sc' => "G_UNICODE_CURRENCY_SYMBOL", + 'Sk' => "G_UNICODE_MODIFIER_SYMBOL", + 'So' => "G_UNICODE_OTHER_SYMBOL" + ); + +%break_mappings = + ( + 'AI' => "G_UNICODE_BREAK_AMBIGUOUS", + 'AL' => "G_UNICODE_BREAK_ALPHABETIC", + 'B2' => "G_UNICODE_BREAK_BEFORE_AND_AFTER", + 'BA' => "G_UNICODE_BREAK_AFTER", + 'BB' => "G_UNICODE_BREAK_BEFORE", + 'BK' => "G_UNICODE_BREAK_MANDATORY", + 'CB' => "G_UNICODE_BREAK_CONTINGENT", + 'CJ' => "G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER", + 'CL' => "G_UNICODE_BREAK_CLOSE_PUNCTUATION", + 'CM' => "G_UNICODE_BREAK_COMBINING_MARK", + 'CP' => "G_UNICODE_BREAK_CLOSE_PARANTHESIS", + 'CR' => "G_UNICODE_BREAK_CARRIAGE_RETURN", + 'EX' => "G_UNICODE_BREAK_EXCLAMATION", + 'GL' => "G_UNICODE_BREAK_NON_BREAKING_GLUE", + 'H2' => "G_UNICODE_BREAK_HANGUL_LV_SYLLABLE", + 'H3' => "G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE", + 'HL' => "G_UNICODE_BREAK_HEBREW_LETTER", + 'HY' => "G_UNICODE_BREAK_HYPHEN", + 'ID' => "G_UNICODE_BREAK_IDEOGRAPHIC", + 'IN' => "G_UNICODE_BREAK_INSEPARABLE", + 'IS' => "G_UNICODE_BREAK_INFIX_SEPARATOR", + 'JL' => "G_UNICODE_BREAK_HANGUL_L_JAMO", + 'JT' => "G_UNICODE_BREAK_HANGUL_T_JAMO", + 'JV' => "G_UNICODE_BREAK_HANGUL_V_JAMO", + 'LF' => "G_UNICODE_BREAK_LINE_FEED", + 'NL' => "G_UNICODE_BREAK_NEXT_LINE", + 'NS' => "G_UNICODE_BREAK_NON_STARTER", + 'NU' => "G_UNICODE_BREAK_NUMERIC", + 'OP' => "G_UNICODE_BREAK_OPEN_PUNCTUATION", + 'PO' => "G_UNICODE_BREAK_POSTFIX", + 'PR' => "G_UNICODE_BREAK_PREFIX", + 'QU' => "G_UNICODE_BREAK_QUOTATION", + 'SA' => "G_UNICODE_BREAK_COMPLEX_CONTEXT", + 'SG' => "G_UNICODE_BREAK_SURROGATE", + 'SP' => "G_UNICODE_BREAK_SPACE", + 'SY' => "G_UNICODE_BREAK_SYMBOL", + 'WJ' => "G_UNICODE_BREAK_WORD_JOINER", + 'XX' => "G_UNICODE_BREAK_UNKNOWN", + 'ZW' => "G_UNICODE_BREAK_ZERO_WIDTH_SPACE" + ); + +# Title case mappings. +%title_to_lower = (); +%title_to_upper = (); + +# Maximum length of special-case strings + +my @special_cases; +my @special_case_offsets; +my $special_case_offset = 0; + +$do_decomp = 0; +$do_props = 1; +if (@ARGV && $ARGV[0] eq '-decomp') +{ + $do_decomp = 1; + $do_props = 0; + shift @ARGV; +} +elsif (@ARGV && $ARGV[0] eq '-both') +{ + $do_decomp = 1; + shift @ARGV; +} + +if (@ARGV != 2) { + $0 =~ s@.*/@@; + die "\nUsage: $0 [-decomp | -both] UNICODE-VERSION DIRECTORY\n\n DIRECTORY should contain the following Unicode data files:\n UnicodeData.txt, LineBreak.txt, SpecialCasing.txt, CaseFolding.txt,\n CompositionExclusions.txt\n\n"; +} + +my ($unicodedatatxt, $linebreaktxt, $specialcasingtxt, $casefoldingtxt, $compositionexclusionstxt); + +my $d = $ARGV[1]; +opendir (my $dir, $d) or die "Cannot open Unicode data dir $d: $!\n"; +for my $f (readdir ($dir)) +{ + $unicodedatatxt = "$d/$f" if ($f =~ /^UnicodeData.*\.txt/); + $linebreaktxt = "$d/$f" if ($f =~ /^LineBreak.*\.txt/); + $specialcasingtxt = "$d/$f" if ($f =~ /^SpecialCasing.*\.txt/); + $casefoldingtxt = "$d/$f" if ($f =~ /^CaseFolding.*\.txt/); + $compositionexclusionstxt = "$d/$f" if ($f =~ /^CompositionExclusions.*\.txt/); +} + +defined $unicodedatatxt or die "Did not find UnicodeData file"; +defined $linebreaktxt or die "Did not find LineBreak file"; +defined $specialcasingtxt or die "Did not find SpecialCasing file"; +defined $casefoldingtxt or die "Did not find CaseFolding file"; +defined $compositionexclusionstxt or die "Did not find CompositionExclusions file"; + +print "Creating decomp table\n" if ($do_decomp); +print "Creating property table\n" if ($do_props); + +print "Composition exlusions from $compositionexclusionstxt\n"; + +open (INPUT, "< $compositionexclusionstxt") || exit 1; + +while () { + + chop; + + next if /^#/; + next if /^\s*$/; + + s/\s*#.*//; + + s/^\s*//; + s/\s*$//; + + $composition_exclusions{hex($_)} = 1; +} + +close INPUT; + +print "Unicode data from $unicodedatatxt\n"; + +open (INPUT, "< $unicodedatatxt") || exit 1; + +# we save memory by skipping the huge empty area before U+E0000 +my $pages_before_e0000; + +$last_code = -1; +while () +{ + chop; + @fields = split (';', $_, 30); + if ($#fields != 14) + { + printf STDERR ("Entry for $fields[$CODE] has wrong number of fields (%d)\n", $#fields); + } + + $code = hex ($fields[$CODE]); + + if ($code >= 0xE0000 and $last_code < 0xE0000) + { + $pages_before_e0000 = ($last_code >> 8) + 1; + } + + if ($code > $last_code + 1) + { + # Found a gap. + if ($fields[$NAME] =~ /Last>/) + { + # Fill the gap with the last character read, + # since this was a range specified in the char database + @gfields = @fields; + } + else + { + # The gap represents undefined characters. Only the type + # matters. + @gfields = ('', '', 'Cn', '0', '', '', '', '', '', '', '', + '', '', '', ''); + } + for (++$last_code; $last_code < $code; ++$last_code) + { + $gfields{$CODE} = sprintf ("%04x", $last_code); + &process_one ($last_code, @gfields); + } + } + &process_one ($code, @fields); + $last_code = $code; +} + +close INPUT; + +@gfields = ('', '', 'Cn', '0', '', '', '', '', '', '', '', + '', '', '', ''); +for (++$last_code; $last_code <= 0x10FFFF; ++$last_code) +{ + $gfields{$CODE} = sprintf ("%04x", $last_code); + &process_one ($last_code, @gfields); +} +--$last_code; # Want last to be 0x10FFFF. + +print "Creating line break table\n"; + +print "Line break data from $linebreaktxt\n"; + +open (INPUT, "< $linebreaktxt") || exit 1; + +$last_code = -1; +while () +{ + my ($start_code, $end_code); + + chop; + + next if /^#/; + next if /^$/; + + s/\s*#.*//; + + @fields = split (';', $_, 30); + if ($#fields != 1) + { + printf STDERR ("Entry for $fields[$CODE] has wrong number of fields (%d)\n", $#fields); + next; + } + + if ($fields[$CODE] =~ /([A-F0-9]{4,6})\.\.([A-F0-9]{4,6})/) + { + $start_code = hex ($1); + $end_code = hex ($2); + } else { + $start_code = $end_code = hex ($fields[$CODE]); + + } + + if ($start_code > $last_code + 1) + { + # The gap represents undefined characters. If assigned, + # they are AL, if not assigned, XX + for (++$last_code; $last_code < $start_code; ++$last_code) + { + if ($type[$last_code] eq 'Cn') + { + $break_props[$last_code] = 'XX'; + } + else + { + $break_props[$last_code] = 'AL'; + } + } + } + + for ($last_code = $start_code; $last_code <= $end_code; $last_code++) + { + $break_props[$last_code] = $fields[$BREAK_PROPERTY]; + } + + $last_code = $end_code; +} + +close INPUT; + +for (++$last_code; $last_code <= 0x10FFFF; ++$last_code) +{ + if ($type[$last_code] eq 'Cn') + { + $break_props[$last_code] = 'XX'; + } + else + { + $break_props[$last_code] = 'AL'; + } +} +--$last_code; # Want last to be 0x10FFFF. + +print STDERR "Last code is not 0x10FFFF" if ($last_code != 0x10FFFF); + +print "Reading special-casing table for case conversion\n"; + +open (INPUT, "< $specialcasingtxt") || exit 1; + +while () +{ + my $code; + + chop; + + next if /^#/; + next if /^\s*$/; + + s/\s*#.*//; + + @fields = split ('\s*;\s*', $_, 30); + + $raw_code = $fields[$CASE_CODE]; + $code = hex ($raw_code); + + if ($#fields != 4 && $#fields != 5) + { + printf STDERR ("Entry for $raw_code has wrong number of fields (%d)\n", $#fields); + next; + } + + if (!defined $type[$code]) + { + printf STDERR "Special case for code point: $code, which has no defined type\n"; + next; + } + + if (defined $fields[5]) { + # Ignore conditional special cases - we'll handle them in code + next; + } + + if ($type[$code] eq 'Lu') + { + (hex $fields[$CASE_UPPER] == $code) || die "$raw_code is Lu and UCD_Upper($raw_code) != $raw_code"; + + &add_special_case ($code, $value[$code], $fields[$CASE_LOWER], $fields[$CASE_TITLE]); + + } elsif ($type[$code] eq 'Lt') + { + (hex $fields[$CASE_TITLE] == $code) || die "$raw_code is Lt and UCD_Title($raw_code) != $raw_code"; + + &add_special_case ($code, undef, $fields[$CASE_LOWER], $fields[$CASE_UPPER]); + } elsif ($type[$code] eq 'Ll') + { + (hex $fields[$CASE_LOWER] == $code) || die "$raw_code is Ll and UCD_Lower($raw_code) != $raw_code"; + + &add_special_case ($code, $value[$code], $fields[$CASE_UPPER], $fields[$CASE_TITLE]); + } else { + printf STDERR "Special case for non-alphabetic code point: $raw_code\n"; + next; + } +} + +close INPUT; + +open (INPUT, "< $casefoldingtxt") || exit 1; + +my $casefoldlen = 0; +my @casefold; + +while () +{ + my $code; + + chop; + + next if /^#/; + next if /^\s*$/; + + s/\s*#.*//; + + @fields = split ('\s*;\s*', $_, 30); + + $raw_code = $fields[$FOLDING_CODE]; + $code = hex ($raw_code); + + if ($#fields != 3) + { + printf STDERR ("Entry for $raw_code has wrong number of fields (%d)\n", $#fields); + next; + } + + # we don't use Simple or Turkic rules here + next if ($fields[$FOLDING_STATUS] =~ /^[ST]$/); + + @values = map { hex ($_) } split /\s+/, $fields[$FOLDING_MAPPING]; + + # Check simple case + + if (@values == 1 && + !(defined $value[$code] && $value[$code] >= 0x1000000) && + defined $type[$code]) { + + my $lower; + if ($type[$code] eq 'Ll') + { + $lower = $code; + } elsif ($type[$code] eq 'Lt') + { + $lower = $title_to_lower{$code}; + } elsif ($type[$code] eq 'Lu') + { + $lower = $value[$code]; + } else { + $lower = $code; + } + + if ($lower == $values[0]) { + next; + } + } + + my $string = pack ("U*", @values); + + if (1 + &length_in_bytes ($string) > $casefoldlen) { + $casefoldlen = 1 + &length_in_bytes ($string); + } + + push @casefold, [ $code, &escape ($string) ]; +} + +close INPUT; + +if ($do_props) { + &print_tables ($last_code) +} +if ($do_decomp) { + &print_decomp ($last_code); + &output_composition_table; +} + +&print_line_break ($last_code); + +exit 0; + + +# perl "length" returns the length in characters +sub length_in_bytes +{ + my ($string) = @_; + + return length $string; +} + +# Process a single character. +sub process_one +{ + my ($code, @fields) = @_; + + $type[$code] = $fields[$CATEGORY]; + if ($type[$code] eq 'Nd') + { + $value[$code] = int ($fields[$DECIMAL_VALUE]); + } + elsif ($type[$code] eq 'Ll') + { + $value[$code] = hex ($fields[$UPPER]); + } + elsif ($type[$code] eq 'Lu') + { + $value[$code] = hex ($fields[$LOWER]); + } + + if ($type[$code] eq 'Lt') + { + $title_to_lower{$code} = hex ($fields[$LOWER]); + $title_to_upper{$code} = hex ($fields[$UPPER]); + } + + $cclass[$code] = $fields[$COMBINING_CLASSES]; + + # Handle decompositions. + if ($fields[$DECOMPOSITION] ne '') + { + if ($fields[$DECOMPOSITION] =~ s/\<.*\>\s*//) { + $decompose_compat[$code] = 1; + } else { + $decompose_compat[$code] = 0; + + if (!exists $composition_exclusions{$code}) { + $compositions{$code} = $fields[$DECOMPOSITION]; + } + } + $decompositions[$code] = $fields[$DECOMPOSITION]; + } +} + +sub print_tables +{ + my ($last) = @_; + my ($outfile) = "gunichartables.h"; + + local ($bytes_out) = 0; + + print "Writing $outfile...\n"; + + open (OUT, "> $outfile"); + + print OUT "/* This file is automatically generated. DO NOT EDIT!\n"; + print OUT " Instead, edit gen-unicode-tables.pl and re-run. */\n\n"; + + print OUT "#ifndef CHARTABLES_H\n"; + print OUT "#define CHARTABLES_H\n\n"; + + print OUT "#define G_UNICODE_DATA_VERSION \"$ARGV[0]\"\n\n"; + + printf OUT "#define G_UNICODE_LAST_CHAR 0x%04x\n\n", $last; + + printf OUT "#define G_UNICODE_MAX_TABLE_INDEX 10000\n\n"; + + my $last_part1 = ($pages_before_e0000 * 256) - 1; + printf OUT "#define G_UNICODE_LAST_CHAR_PART1 0x%04X\n\n", $last_part1; + printf OUT "#define G_UNICODE_LAST_PAGE_PART1 %d\n\n", $pages_before_e0000 - 1; + + $table_index = 0; + printf OUT "static const char type_data[][256] = {\n"; + for ($count = 0; $count <= $last; $count += 256) + { + $row[$count / 256] = &print_row ($count, 1, \&fetch_type); + } + printf OUT "\n};\n\n"; + + printf OUT "/* U+0000 through U+%04X */\n", $last_part1; + print OUT "static const gint16 type_table_part1[$pages_before_e0000] = {\n"; + for ($count = 0; $count <= $last_part1; $count += 256) + { + print OUT ",\n" if $count > 0; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + printf OUT "/* U+E0000 through U+%04X */\n", $last; + print OUT "static const gint16 type_table_part2[768] = {\n"; + for ($count = 0xE0000; $count <= $last; $count += 256) + { + print OUT ",\n" if $count > 0xE0000; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + + # + # Now print attribute table. + # + + $table_index = 0; + printf OUT "static const gunichar attr_data[][256] = {\n"; + for ($count = 0; $count <= $last; $count += 256) + { + $row[$count / 256] = &print_row ($count, 4, \&fetch_attr); + } + printf OUT "\n};\n\n"; + + printf OUT "/* U+0000 through U+%04X */\n", $last_part1; + print OUT "static const gint16 attr_table_part1[$pages_before_e0000] = {\n"; + for ($count = 0; $count <= $last_part1; $count += 256) + { + print OUT ",\n" if $count > 0; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + printf OUT "/* U+E0000 through U+%04X */\n", $last; + print OUT "static const gint16 attr_table_part2[768] = {\n"; + for ($count = 0xE0000; $count <= $last; $count += 256) + { + print OUT ",\n" if $count > 0xE0000; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + # + # print title case table + # + + print OUT "static const gunichar title_table[][3] = {\n"; + my ($item); + my ($first) = 1; + foreach $item (sort keys %title_to_lower) + { + print OUT ",\n" + unless $first; + $first = 0; + printf OUT " { 0x%04x, 0x%04x, 0x%04x }", $item, $title_to_upper{$item}, $title_to_lower{$item}; + $bytes_out += 12; + } + print OUT "\n};\n\n"; + + # + # And special case conversion table -- conversions that change length + # + &output_special_case_table (\*OUT); + &output_casefold_table (\*OUT); + + print OUT "#endif /* CHARTABLES_H */\n"; + + close (OUT); + + printf STDERR "Generated %d bytes in tables\n", $bytes_out; +} + +# A fetch function for the type table. +sub fetch_type +{ + my ($index) = @_; + return $mappings{$type[$index]}; +} + +# A fetch function for the attribute table. +sub fetch_attr +{ + my ($index) = @_; + if (defined $value[$index]) + { + return sprintf ("0x%04x", $value[$index]); + } + else + { + return "0x0000"; + } +} + +sub print_row +{ + my ($start, $typsize, $fetcher) = @_; + + my ($i); + my (@values); + my ($flag) = 1; + my ($off); + + for ($off = 0; $off < 256; ++$off) + { + $values[$off] = $fetcher->($off + $start); + if ($values[$off] ne $values[0]) + { + $flag = 0; + } + } + if ($flag) + { + return $values[0] . " + G_UNICODE_MAX_TABLE_INDEX"; + } + + printf OUT ",\n" if ($table_index != 0); + printf OUT " { /* page %d, index %d */\n ", $start / 256, $table_index; + my ($column) = 4; + for ($i = $start; $i < $start + 256; ++$i) + { + print OUT ", " + if $i > $start; + my ($text) = $values[$i - $start]; + if (length ($text) + $column + 2 > 78) + { + print OUT "\n "; + $column = 4; + } + print OUT $text; + $column += length ($text) + 2; + } + print OUT "\n }"; + + $bytes_out += 256 * $typsize; + + return sprintf "%d /* page %d */", $table_index++, $start / 256; +} + +sub escape +{ + my ($string) = @_; + + my $escaped = unpack("H*", $string); + $escaped =~ s/(.{2})/\\x$1/g; + + return $escaped; +} + +# Returns the offset of $decomp in the offset string. Updates the +# referenced variables as appropriate. +sub handle_decomp ($$$$) +{ + my ($decomp, $decomp_offsets_ref, $decomp_string_ref, $decomp_string_offset_ref) = @_; + my $offset = "G_UNICODE_NOT_PRESENT_OFFSET"; + + if (defined $decomp) + { + if (defined $decomp_offsets_ref->{$decomp}) + { + $offset = $decomp_offsets_ref->{$decomp}; + } + else + { + $offset = ${$decomp_string_offset_ref}; + $decomp_offsets_ref->{$decomp} = $offset; + ${$decomp_string_ref} .= "\n \"" . &escape ($decomp) . "\\0\" /* offset ${$decomp_string_offset_ref} */"; + ${$decomp_string_offset_ref} += &length_in_bytes ($decomp) + 1; + } + } + + return $offset; +} + +# Generate the character decomposition header. +sub print_decomp +{ + my ($last) = @_; + my ($outfile) = "gunidecomp.h"; + + local ($bytes_out) = 0; + + print "Writing $outfile...\n"; + + open (OUT, "> $outfile") || exit 1; + + print OUT "/* This file is automatically generated. DO NOT EDIT! */\n\n"; + print OUT "#ifndef DECOMP_H\n"; + print OUT "#define DECOMP_H\n\n"; + + printf OUT "#define G_UNICODE_LAST_CHAR 0x%04x\n\n", $last; + + printf OUT "#define G_UNICODE_MAX_TABLE_INDEX (0x110000 / 256)\n\n"; + + my $last_part1 = ($pages_before_e0000 * 256) - 1; + printf OUT "#define G_UNICODE_LAST_CHAR_PART1 0x%04X\n\n", $last_part1; + printf OUT "#define G_UNICODE_LAST_PAGE_PART1 %d\n\n", $pages_before_e0000 - 1; + + $NOT_PRESENT_OFFSET = 65535; + print OUT "#define G_UNICODE_NOT_PRESENT_OFFSET $NOT_PRESENT_OFFSET\n\n"; + + my ($count, @row); + $table_index = 0; + printf OUT "static const guchar cclass_data[][256] = {\n"; + for ($count = 0; $count <= $last; $count += 256) + { + $row[$count / 256] = &print_row ($count, 1, \&fetch_cclass); + } + printf OUT "\n};\n\n"; + + print OUT "static const gint16 combining_class_table_part1[$pages_before_e0000] = {\n"; + for ($count = 0; $count <= $last_part1; $count += 256) + { + print OUT ",\n" if $count > 0; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + print OUT "static const gint16 combining_class_table_part2[768] = {\n"; + for ($count = 0xE0000; $count <= $last; $count += 256) + { + print OUT ",\n" if $count > 0xE0000; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + print OUT "typedef struct\n{\n"; + print OUT " gunichar ch;\n"; + print OUT " guint16 canon_offset;\n"; + print OUT " guint16 compat_offset;\n"; + print OUT "} decomposition;\n\n"; + + print OUT "static const decomposition decomp_table[] =\n{\n"; + my ($iter); + my ($first) = 1; + my ($decomp_string) = ""; + my ($decomp_string_offset) = 0; + for ($count = 0; $count <= $last; ++$count) + { + if (defined $decompositions[$count]) + { + print OUT ",\n" + if ! $first; + $first = 0; + + my $canon_decomp; + my $compat_decomp; + + if (!$decompose_compat[$count]) { + $canon_decomp = make_decomp ($count, 0); + } + $compat_decomp = make_decomp ($count, 1); + + if (defined $canon_decomp && $compat_decomp eq $canon_decomp) { + undef $compat_decomp; + } + + my $canon_offset = handle_decomp ($canon_decomp, \%decomp_offsets, \$decomp_string, \$decomp_string_offset); + my $compat_offset = handle_decomp ($compat_decomp, \%decomp_offsets, \$decomp_string, \$decomp_string_offset); + + die if $decomp_string_offset > $NOT_PRESENT_OFFSET; + + printf OUT qq( { 0x%04x, $canon_offset, $compat_offset }), $count; + $bytes_out += 8; + } + } + print OUT "\n};\n\n"; + $bytes_out += $decomp_string_offset + 1; + + printf OUT "static const gchar decomp_expansion_string[] = %s;\n\n", $decomp_string; + + print OUT "typedef struct\n{\n"; + print OUT " gunichar ch;\n"; + print OUT " gunichar a;\n"; + print OUT " gunichar b;\n"; + print OUT "} decomposition_step;\n\n"; + + # There's lots of room to optimize the following table... + print OUT "static const decomposition_step decomp_step_table[] =\n{\n"; + $first = 1; + my @steps = (); + for ($count = 0; $count <= $last; ++$count) + { + if ((defined $decompositions[$count]) && (!$decompose_compat[$count])) + { + print OUT ",\n" + if ! $first; + $first = 0; + my @list; + @list = (split(' ', $decompositions[$count]), "0"); + printf OUT qq( { 0x%05x, 0x%05x, 0x%05x }), $count, hex($list[0]), hex($list[1]); + # don't include 1:1 in the compose table + push @steps, [ ($count, hex($list[0]), hex($list[1])) ] + if hex($list[1]) + } + } + print OUT "\n};\n\n"; + + print OUT "#endif /* DECOMP_H */\n"; + + printf STDERR "Generated %d bytes in decomp tables\n", $bytes_out; +} + +sub print_line_break +{ + my ($last) = @_; + my ($outfile) = "gunibreak.h"; + + local ($bytes_out) = 0; + + print "Writing $outfile...\n"; + + open (OUT, "> $outfile"); + + print OUT "/* This file is automatically generated. DO NOT EDIT!\n"; + print OUT " Instead, edit gen-unicode-tables.pl and re-run. */\n\n"; + + print OUT "#ifndef BREAKTABLES_H\n"; + print OUT "#define BREAKTABLES_H\n\n"; + + print OUT "#include \n"; + print OUT "#include \n\n"; + + print OUT "#define G_UNICODE_DATA_VERSION \"$ARGV[0]\"\n\n"; + + printf OUT "#define G_UNICODE_LAST_CHAR 0x%04X\n\n", $last; + + printf OUT "#define G_UNICODE_MAX_TABLE_INDEX 10000\n\n"; + + my $last_part1 = ($pages_before_e0000 * 256) - 1; + printf OUT "/* the last code point that should be looked up in break_property_table_part1 */\n"; + printf OUT "#define G_UNICODE_LAST_CHAR_PART1 0x%04X\n\n", $last_part1; + + $table_index = 0; + printf OUT "static const gint8 break_property_data[][256] = {\n"; + for ($count = 0; $count <= $last; $count += 256) + { + $row[$count / 256] = &print_row ($count, 1, \&fetch_break_type); + } + printf OUT "\n};\n\n"; + + printf OUT "/* U+0000 through U+%04X */\n", $last_part1; + print OUT "static const gint16 break_property_table_part1[$pages_before_e0000] = {\n"; + for ($count = 0; $count <= $last_part1; $count += 256) + { + print OUT ",\n" if $count > 0; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + printf OUT "/* U+E0000 through U+%04X */\n", $last; + print OUT "static const gint16 break_property_table_part2[768] = {\n"; + for ($count = 0xE0000; $count <= $last; $count += 256) + { + print OUT ",\n" if $count > 0xE0000; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + + print OUT "#endif /* BREAKTABLES_H */\n"; + + close (OUT); + + printf STDERR "Generated %d bytes in break tables\n", $bytes_out; +} + + +# A fetch function for the break properties table. +sub fetch_break_type +{ + my ($index) = @_; + return $break_mappings{$break_props[$index]}; +} + +# Fetcher for combining class. +sub fetch_cclass +{ + my ($i) = @_; + return $cclass[$i]; +} + +# Expand a character decomposition recursively. +sub expand_decomp +{ + my ($code, $compat) = @_; + + my ($iter, $val); + my (@result) = (); + foreach $iter (split (' ', $decompositions[$code])) + { + $val = hex ($iter); + if (defined $decompositions[$val] && + ($compat || !$decompose_compat[$val])) + { + push (@result, &expand_decomp ($val, $compat)); + } + else + { + push (@result, $val); + } + } + + return @result; +} + +sub make_decomp +{ + my ($code, $compat) = @_; + + my $result = ""; + foreach $iter (&expand_decomp ($code, $compat)) + { + $result .= pack ("U", $iter); # to utf-8 + } + + $result; +} +# Generate special case data string from two fields +sub add_special_case +{ + my ($code, $single, $field1, $field2) = @_; + + @values = (defined $single ? $single : (), + (map { hex ($_) } split /\s+/, $field1), + 0, + (map { hex ($_) } split /\s+/, $field2)); + + $result = ""; + + for $value (@values) { + $result .= pack ("U", $value); # to utf-8 + } + + push @special_case_offsets, $special_case_offset; + + # We encode special cases up in the 0x1000000 space + $value[$code] = 0x1000000 + $special_case_offset; + + $special_case_offset += 1 + &length_in_bytes ($result); + + push @special_cases, &escape ($result); +} + +sub output_special_case_table +{ + my $out = shift; + + print $out < $b } keys %$array) { + if ($array->{$code} == 1) { + delete $array->{$code}; + next; + } + $array->{$code} = $n++; + } + + return $n; +} + +sub output_composition_table +{ + print STDERR "Generating composition table\n"; + + local ($bytes_out) = 0; + + my %first; + my %second; + + # First we need to go through and remove decompositions + # starting with a non-starter, and single-character + # decompositions. At the same time, record + # the first and second character of each decomposition + + for $code (keys %compositions) + { + @values = map { hex ($_) } split /\s+/, $compositions{$code}; + + # non-starters + if ($cclass[$code]) { + delete $compositions{$code}; + next; + } + if ($cclass[$values[0]]) { + delete $compositions{$code}; + next; + } + + # single-character decompositions + if (@values == 1) { + delete $compositions{$code}; + next; + } + + if (@values != 2) { + die "$code has more than two elements in its decomposition!\n"; + } + + if (exists $first{$values[0]}) { + $first{$values[0]}++; + } else { + $first{$values[0]} = 1; + } + } + + # Assign integer indices, removing singletons + my $n_first = enumerate_ordered (\%first); + + # Now record the second character of each (non-singleton) decomposition + for $code (keys %compositions) { + @values = map { hex ($_) } split /\s+/, $compositions{$code}; + + if (exists $first{$values[0]}) { + if (exists $second{$values[1]}) { + $second{$values[1]}++; + } else { + $second{$values[1]} = 1; + } + } + } + + # Assign integer indices, removing duplicate + my $n_second = enumerate_ordered (\%second); + + # Build reverse table + + my @first_singletons; + my @second_singletons; + my %reverse; + for $code (keys %compositions) { + @values = map { hex ($_) } split /\s+/, $compositions{$code}; + + my $first = $first{$values[0]}; + my $second = $second{$values[1]}; + + if (defined $first && defined $second) { + $reverse{"$first|$second"} = $code; + } elsif (!defined $first) { + push @first_singletons, [ $values[0], $values[1], $code ]; + } else { + push @second_singletons, [ $values[1], $values[0], $code ]; + } + } + + @first_singletons = sort { $a->[0] <=> $b->[0] } @first_singletons; + @second_singletons = sort { $a->[0] <=> $b->[0] } @second_singletons; + + my %vals; + + open OUT, ">gunicomp.h" or die "Cannot open gunicomp.h: $!\n"; + + # Assign values in lookup table for all code points involved + + my $total = 1; + my $last = 0; + printf OUT "#define COMPOSE_FIRST_START %d\n", $total; + for $code (keys %first) { + $vals{$code} = $first{$code} + $total; + $last = $code if $code > $last; + } + $total += $n_first; + $i = 0; + printf OUT "#define COMPOSE_FIRST_SINGLE_START %d\n", $total; + for $record (@first_singletons) { + my $code = $record->[0]; + $vals{$code} = $i++ + $total; + $last = $code if $code > $last; + } + $total += @first_singletons; + printf OUT "#define COMPOSE_SECOND_START %d\n", $total; + for $code (keys %second) { + $vals{$code} = $second{$code} + $total; + $last = $code if $code > $last; + } + $total += $n_second; + $i = 0; + printf OUT "#define COMPOSE_SECOND_SINGLE_START %d\n\n", $total; + for $record (@second_singletons) { + my $code = $record->[0]; + $vals{$code} = $i++ + $total; + $last = $code if $code > $last; + } + + printf OUT "#define COMPOSE_TABLE_LAST %d\n\n", $last / 256; + + # Output lookup table + + my @row; + $table_index = 0; + printf OUT "static const guint16 compose_data[][256] = {\n"; + for (my $count = 0; $count <= $last; $count += 256) + { + $row[$count / 256] = &print_row ($count, 2, sub { exists $vals{$_[0]} ? $vals{$_[0]} : 0; }); + } + printf OUT "\n};\n\n"; + + print OUT "static const gint16 compose_table[COMPOSE_TABLE_LAST + 1] = {\n"; + for (my $count = 0; $count <= $last; $count += 256) + { + print OUT ",\n" if $count > 0; + print OUT " ", $row[$count / 256]; + $bytes_out += 2; + } + print OUT "\n};\n\n"; + + # Output first singletons + + print OUT "static const gunichar compose_first_single[][2] = {\n"; + $i = 0; + for $record (@first_singletons) { + print OUT ",\n" if $i++ > 0; + printf OUT " { %#06x, %#06x }", $record->[1], $record->[2]; + } + print OUT "\n};\n"; + + $bytes_out += @first_singletons * 4; + + # Output second singletons + + print OUT "static const guint16 compose_second_single[][2] = {\n"; + $i = 0; + for $record (@second_singletons) { + if ($record->[1] > 0xFFFF or $record->[2] > 0xFFFF) { + die "time to switch compose_second_single to gunichar"; + } + print OUT ",\n" if $i++ > 0; + printf OUT " { %#06x, %#06x }", $record->[1], $record->[2]; + } + print OUT "\n};\n"; + + $bytes_out += @second_singletons * 4; + + # Output array of composition pairs + + print OUT < 0xFFFF) { + die "time to switch compose_array to gunichar" ; + } + printf OUT "0x%04x", $reverse{"$i|$j"}; + } else { + print OUT " 0"; + } + } + print OUT " }"; + } + print OUT "\n"; + + print OUT <[0] <=> $b->[0] } @casefold; + + for $case (@casefold) + { + $code = $case->[0]; + $string = $case->[1]; + + if ($code > 0xFFFF) { + die "time to switch casefold_table to gunichar" ; + } + + print $out sprintf(qq( { 0x%04x, "$string" },\n), $code); + + } + + print $out < +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_CRT_EXTERNS_H +#include /* for _NSGetEnviron */ +#endif +#ifdef G_OS_WIN32 +#include +#endif + +#include "gmem.h" +#include "gmessages.h" +#include "gstrfuncs.h" +#include "gunicode.h" +#include "gconvert.h" +#include "gquark.h" + +/* Environ array functions {{{1 */ +static gint +g_environ_find (gchar **envp, + const gchar *variable) +{ + gint len, i; + + len = strlen (variable); + + for (i = 0; envp[i]; i++) + { + if (strncmp (envp[i], variable, len) == 0 && + envp[i][len] == '=') + return i; + } + + return -1; +} + +/** + * g_environ_getenv: + * @envp: (array zero-terminated=1) (transfer none): an environment + * list (eg, as returned from g_get_environ()) + * @variable: the environment variable to get, in the GLib file name + * encoding + * + * Returns the value of the environment variable @variable in the + * provided list @envp. + * + * The name and value are in the GLib file name encoding. + * On UNIX, this means the actual bytes which might or might not + * be in some consistent character set and encoding. On Windows, + * it is in UTF-8. On Windows, in case the environment variable's + * value contains references to other environment variables, they + * are expanded. + * + * Return value: the value of the environment variable, or %NULL if + * the environment variable is not set in @envp. The returned + * string is owned by @envp, and will be freed if @variable is + * set or unset again. + * + * Since: 2.32 + */ +const gchar * +g_environ_getenv (gchar **envp, + const gchar *variable) +{ + gint index; + + g_return_val_if_fail (envp != NULL, NULL); + g_return_val_if_fail (variable != NULL, NULL); + + index = g_environ_find (envp, variable); + if (index != -1) + return envp[index] + strlen (variable) + 1; + else + return NULL; +} + +/** + * g_environ_setenv: + * @envp: (array zero-terminated=1) (transfer full): an environment + * list that can be freed using g_strfreev() (e.g., as returned from g_get_environ()) + * @variable: the environment variable to set, must not contain '=' + * @value: the value for to set the variable to + * @overwrite: whether to change the variable if it already exists + * + * Sets the environment variable @variable in the provided list + * @envp to @value. + * + * Both the variable's name and value should be in the GLib + * file name encoding. On UNIX, this means that they can be + * arbitrary byte strings. On Windows, they should be in UTF-8. + * + * Return value: (array zero-terminated=1) (transfer full): the + * updated environment list. Free it using g_strfreev(). + * + * Since: 2.32 + */ +gchar ** +g_environ_setenv (gchar **envp, + const gchar *variable, + const gchar *value, + gboolean overwrite) +{ + gint index; + + g_return_val_if_fail (envp != NULL, NULL); + g_return_val_if_fail (variable != NULL, NULL); + g_return_val_if_fail (strchr (variable, '=') == NULL, NULL); + + index = g_environ_find (envp, variable); + if (index != -1) + { + if (overwrite) + { + g_free (envp[index]); + envp[index] = g_strdup_printf ("%s=%s", variable, value); + } + } + else + { + gint length; + + length = g_strv_length (envp); + envp = g_renew (gchar *, envp, length + 2); + envp[length] = g_strdup_printf ("%s=%s", variable, value); + envp[length + 1] = NULL; + } + + return envp; +} + +static gchar ** +g_environ_unsetenv_internal (gchar **envp, + const gchar *variable, + gboolean free_value) +{ + gint len; + gchar **e, **f; + + len = strlen (variable); + + /* Note that we remove *all* environment entries for + * the variable name, not just the first. + */ + e = f = envp; + while (*e != NULL) + { + if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=') + { + *f = *e; + f++; + } + else + { + if (free_value) + g_free (*e); + } + + e++; + } + *f = NULL; + + return envp; +} + + +/** + * g_environ_unsetenv: + * @envp: (array zero-terminated=1) (transfer full): an environment + * list that can be freed using g_strfreev() (e.g., as returned from g_get_environ()) + * @variable: the environment variable to remove, must not contain '=' + * + * Removes the environment variable @variable from the provided + * environment @envp. + * + * Return value: (array zero-terminated=1) (transfer full): the + * updated environment list. Free it using g_strfreev(). + * + * Since: 2.32 + */ +gchar ** +g_environ_unsetenv (gchar **envp, + const gchar *variable) +{ + g_return_val_if_fail (envp != NULL, NULL); + g_return_val_if_fail (variable != NULL, NULL); + g_return_val_if_fail (strchr (variable, '=') == NULL, NULL); + + return g_environ_unsetenv_internal (envp, variable, TRUE); +} + +/* UNIX implemention {{{1 */ +#ifndef G_OS_WIN32 + +/** + * g_getenv: + * @variable: the environment variable to get, in the GLib file name + * encoding + * + * Returns the value of an environment variable. + * + * The name and value are in the GLib file name encoding. On UNIX, + * this means the actual bytes which might or might not be in some + * consistent character set and encoding. On Windows, it is in UTF-8. + * On Windows, in case the environment variable's value contains + * references to other environment variables, they are expanded. + * + * Return value: the value of the environment variable, or %NULL if + * the environment variable is not found. The returned string + * may be overwritten by the next call to g_getenv(), g_setenv() + * or g_unsetenv(). + */ +const gchar * +g_getenv (const gchar *variable) +{ + g_return_val_if_fail (variable != NULL, NULL); + + return getenv (variable); +} + +/** + * g_setenv: + * @variable: the environment variable to set, must not contain '='. + * @value: the value for to set the variable to. + * @overwrite: whether to change the variable if it already exists. + * + * Sets an environment variable. Both the variable's name and value + * should be in the GLib file name encoding. On UNIX, this means that + * they can be arbitrary byte strings. On Windows, they should be in + * UTF-8. + * + * Note that on some systems, when variables are overwritten, the memory + * used for the previous variables and its value isn't reclaimed. + * + * + * Environment variable handling in UNIX is not thread-safe, and your + * program may crash if one thread calls g_setenv() while another + * thread is calling getenv(). (And note that many functions, such as + * gettext(), call getenv() internally.) This function is only safe to + * use at the very start of your program, before creating any other + * threads (or creating objects that create worker threads of their + * own). + * + * If you need to set up the environment for a child process, you can + * use g_get_environ() to get an environment array, modify that with + * g_environ_setenv() and g_environ_unsetenv(), and then pass that + * array directly to execvpe(), g_spawn_async(), or the like. + * + * + * Returns: %FALSE if the environment variable couldn't be set. + * + * Since: 2.4 + */ +gboolean +g_setenv (const gchar *variable, + const gchar *value, + gboolean overwrite) +{ + gint result; +#ifndef HAVE_SETENV + gchar *string; +#endif + + g_return_val_if_fail (variable != NULL, FALSE); + g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE); + +#ifdef HAVE_SETENV + result = setenv (variable, value, overwrite); +#else + if (!overwrite && getenv (variable) != NULL) + return TRUE; + + /* This results in a leak when you overwrite existing + * settings. It would be fairly easy to fix this by keeping + * our own parallel array or hash table. + */ + string = g_strconcat (variable, "=", value, NULL); + result = putenv (string); +#endif + return result == 0; +} + +#ifdef HAVE__NSGETENVIRON +#define environ (*_NSGetEnviron()) +#else +/* According to the Single Unix Specification, environ is not + * in any system header, although unistd.h often declares it. + */ +extern char **environ; +#endif + +/** + * g_unsetenv: + * @variable: the environment variable to remove, must not contain '=' + * + * Removes an environment variable from the environment. + * + * Note that on some systems, when variables are overwritten, the + * memory used for the previous variables and its value isn't reclaimed. + * + * + * Environment variable handling in UNIX is not thread-safe, and your + * program may crash if one thread calls g_unsetenv() while another + * thread is calling getenv(). (And note that many functions, such as + * gettext(), call getenv() internally.) This function is only safe + * to use at the very start of your program, before creating any other + * threads (or creating objects that create worker threads of their + * own). + * + * If you need to set up the environment for a child process, you can + * use g_get_environ() to get an environment array, modify that with + * g_environ_setenv() and g_environ_unsetenv(), and then pass that + * array directly to execvpe(), g_spawn_async(), or the like. + * + * + * Since: 2.4 + */ +void +g_unsetenv (const gchar *variable) +{ +#ifdef HAVE_UNSETENV + g_return_if_fail (variable != NULL); + g_return_if_fail (strchr (variable, '=') == NULL); + + unsetenv (variable); +#else /* !HAVE_UNSETENV */ + g_return_if_fail (variable != NULL); + g_return_if_fail (strchr (variable, '=') == NULL); + + /* Mess directly with the environ array. + * This seems to be the only portable way to do this. + */ + g_environ_unsetenv_internal (environ, variable, FALSE); +#endif /* !HAVE_UNSETENV */ +} + +/** + * g_listenv: + * + * Gets the names of all variables set in the environment. + * + * Programs that want to be portable to Windows should typically use + * this function and g_getenv() instead of using the environ array + * from the C library directly. On Windows, the strings in the environ + * array are in system codepage encoding, while in most of the typical + * use cases for environment variables in GLib-using programs you want + * the UTF-8 encoding that this function and g_getenv() provide. + * + * Returns: (array zero-terminated=1) (transfer full): a %NULL-terminated + * list of strings which must be freed with g_strfreev(). + * + * Since: 2.8 + */ +gchar ** +g_listenv (void) +{ + gchar **result, *eq; + gint len, i, j; + + len = g_strv_length (environ); + result = g_new0 (gchar *, len + 1); + + j = 0; + for (i = 0; i < len; i++) + { + eq = strchr (environ[i], '='); + if (eq) + result[j++] = g_strndup (environ[i], eq - environ[i]); + } + + result[j] = NULL; + + return result; +} + +/** + * g_get_environ: + * + * Gets the list of environment variables for the current process. + * + * The list is %NULL terminated and each item in the list is of the + * form 'NAME=VALUE'. + * + * This is equivalent to direct access to the 'environ' global variable, + * except portable. + * + * The return value is freshly allocated and it should be freed with + * g_strfreev() when it is no longer needed. + * + * Returns: (array zero-terminated=1) (transfer full): the list of + * environment variables + * + * Since: 2.28 + */ +gchar ** +g_get_environ (void) +{ + return g_strdupv (environ); +} + +/* Win32 implementation {{{1 */ +#else /* G_OS_WIN32 */ + +const gchar * +g_getenv (const gchar *variable) +{ + GQuark quark; + gchar *value; + wchar_t dummy[2], *wname, *wvalue; + int len; + + g_return_val_if_fail (variable != NULL, NULL); + g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), NULL); + + /* On Windows NT, it is relatively typical that environment + * variables contain references to other environment variables. If + * so, use ExpandEnvironmentStrings(). (In an ideal world, such + * environment variables would be stored in the Registry as + * REG_EXPAND_SZ type values, and would then get automatically + * expanded before a program sees them. But there is broken software + * that stores environment variables as REG_SZ values even if they + * contain references to other environment variables.) + */ + + wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); + + len = GetEnvironmentVariableW (wname, dummy, 2); + + if (len == 0) + { + g_free (wname); + return NULL; + } + else if (len == 1) + len = 2; + + wvalue = g_new (wchar_t, len); + + if (GetEnvironmentVariableW (wname, wvalue, len) != len - 1) + { + g_free (wname); + g_free (wvalue); + return NULL; + } + + if (wcschr (wvalue, L'%') != NULL) + { + wchar_t *tem = wvalue; + + len = ExpandEnvironmentStringsW (wvalue, dummy, 2); + + if (len > 0) + { + wvalue = g_new (wchar_t, len); + + if (ExpandEnvironmentStringsW (tem, wvalue, len) != len) + { + g_free (wvalue); + wvalue = tem; + } + else + g_free (tem); + } + } + + value = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL); + + g_free (wname); + g_free (wvalue); + + quark = g_quark_from_string (value); + g_free (value); + + return g_quark_to_string (quark); +} + +gboolean +g_setenv (const gchar *variable, + const gchar *value, + gboolean overwrite) +{ + gboolean retval; + wchar_t *wname, *wvalue, *wassignment; + gchar *tem; + + g_return_val_if_fail (variable != NULL, FALSE); + g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE); + g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), FALSE); + g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE); + + if (!overwrite && g_getenv (variable) != NULL) + return TRUE; + + /* We want to (if possible) set both the environment variable copy + * kept by the C runtime and the one kept by the system. + * + * We can't use only the C runtime's putenv or _wputenv() as that + * won't work for arbitrary Unicode strings in a "non-Unicode" app + * (with main() and not wmain()). In a "main()" app the C runtime + * initializes the C runtime's environment table by converting the + * real (wide char) environment variables to system codepage, thus + * breaking those that aren't representable in the system codepage. + * + * As the C runtime's putenv() will also set the system copy, we do + * the putenv() first, then call SetEnvironmentValueW ourselves. + */ + + wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); + wvalue = g_utf8_to_utf16 (value, -1, NULL, NULL, NULL); + tem = g_strconcat (variable, "=", value, NULL); + wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL); + + g_free (tem); + _wputenv (wassignment); + g_free (wassignment); + + retval = (SetEnvironmentVariableW (wname, wvalue) != 0); + + g_free (wname); + g_free (wvalue); + + return retval; +} + +void +g_unsetenv (const gchar *variable) +{ + wchar_t *wname, *wassignment; + gchar *tem; + + g_return_if_fail (variable != NULL); + g_return_if_fail (strchr (variable, '=') == NULL); + g_return_if_fail (g_utf8_validate (variable, -1, NULL)); + + wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL); + tem = g_strconcat (variable, "=", NULL); + wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL); + + g_free (tem); + _wputenv (wassignment); + g_free (wassignment); + + SetEnvironmentVariableW (wname, NULL); + + g_free (wname); +} + +gchar ** +g_listenv (void) +{ + gchar **result, *eq; + gint len = 0, j; + wchar_t *p, *q; + + p = (wchar_t *) GetEnvironmentStringsW (); + if (p != NULL) + { + q = p; + while (*q) + { + q += wcslen (q) + 1; + len++; + } + } + result = g_new0 (gchar *, len + 1); + + j = 0; + q = p; + while (*q) + { + result[j] = g_utf16_to_utf8 (q, -1, NULL, NULL, NULL); + if (result[j] != NULL) + { + eq = strchr (result[j], '='); + if (eq && eq > result[j]) + { + *eq = '\0'; + j++; + } + else + g_free (result[j]); + } + q += wcslen (q) + 1; + } + result[j] = NULL; + FreeEnvironmentStringsW (p); + + return result; +} + +gchar ** +g_get_environ (void) +{ + gunichar2 *strings; + gchar **result; + gint i, n; + + strings = GetEnvironmentStringsW (); + for (n = 0; strings[n]; n += wcslen (strings + n) + 1); + result = g_new (char *, n + 1); + for (i = 0; strings[i]; i += wcslen (strings + i) + 1) + result[i] = g_utf16_to_utf8 (strings + i, -1, NULL, NULL, NULL); + FreeEnvironmentStringsW (strings); + result[i] = NULL; + + return result; +} + +/* Win32 binary compatibility versions {{{1 */ +#ifndef _WIN64 + +#undef g_getenv + +const gchar * +g_getenv (const gchar *variable) +{ + gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL); + const gchar *utf8_value = g_getenv_utf8 (utf8_variable); + gchar *value; + GQuark quark; + + g_free (utf8_variable); + if (!utf8_value) + return NULL; + value = g_locale_from_utf8 (utf8_value, -1, NULL, NULL, NULL); + quark = g_quark_from_string (value); + g_free (value); + + return g_quark_to_string (quark); +} + +#undef g_setenv + +gboolean +g_setenv (const gchar *variable, + const gchar *value, + gboolean overwrite) +{ + gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL); + gchar *utf8_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL); + gboolean retval = g_setenv_utf8 (utf8_variable, utf8_value, overwrite); + + g_free (utf8_variable); + g_free (utf8_value); + + return retval; +} + +#undef g_unsetenv + +void +g_unsetenv (const gchar *variable) +{ + gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL); + + g_unsetenv_utf8 (utf8_variable); + + g_free (utf8_variable); +} + +#endif /* _WIN64 */ + +#endif /* G_OS_WIN32 */ + +/* Epilogue {{{1 */ +/* vim: set foldmethod=marker: */ diff --git a/glib/glib/genviron.h b/glib/glib/genviron.h new file mode 100644 index 0000000..c75c548 --- /dev/null +++ b/glib/glib/genviron.h @@ -0,0 +1,65 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_ENVIRON_H__ +#define __G_ENVIRON_H__ + +#include + +G_BEGIN_DECLS + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +#define g_getenv g_getenv_utf8 +#define g_setenv g_setenv_utf8 +#define g_unsetenv g_unsetenv_utf8 +#endif +#endif + +const gchar * g_getenv (const gchar *variable); +gboolean g_setenv (const gchar *variable, + const gchar *value, + gboolean overwrite); +void g_unsetenv (const gchar *variable); +gchar ** g_listenv (void); + +gchar ** g_get_environ (void); +const gchar * g_environ_getenv (gchar **envp, + const gchar *variable); +gchar ** g_environ_setenv (gchar **envp, + const gchar *variable, + const gchar *value, + gboolean overwrite) G_GNUC_WARN_UNUSED_RESULT; +gchar ** g_environ_unsetenv (gchar **envp, + const gchar *variable) G_GNUC_WARN_UNUSED_RESULT; + +G_END_DECLS + +#endif /* __G_ENVIRON_H__ */ diff --git a/glib/glib/gerror.c b/glib/glib/gerror.c new file mode 100644 index 0000000..6cc3cfb --- /dev/null +++ b/glib/glib/gerror.c @@ -0,0 +1,727 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/** + * SECTION:error_reporting + * @Title: Error Reporting + * @Short_description: a system for reporting errors + * + * GLib provides a standard method of reporting errors from a called + * function to the calling code. (This is the same problem solved by + * exceptions in other languages.) It's important to understand that + * this method is both a data type (the #GError + * object) and a set of rules. If you use #GError + * incorrectly, then your code will not properly interoperate with other + * code that uses #GError, and users of your API will probably get confused. + * + * First and foremost: #GError should only be used to report + * recoverable runtime errors, never to report programming + * errors. If the programmer has screwed up, then you should + * use g_warning(), g_return_if_fail(), g_assert(), g_error(), or some + * similar facility. (Incidentally, remember that the g_error() function + * should only be used for programming errors, it + * should not be used to print any error reportable via #GError.) + * + * Examples of recoverable runtime errors are "file not found" or + * "failed to parse input." Examples of programming errors are "NULL + * passed to strcmp()" or "attempted to free the same pointer twice." + * These two kinds of errors are fundamentally different: runtime errors + * should be handled or reported to the user, programming errors should + * be eliminated by fixing the bug in the program. This is why most + * functions in GLib and GTK+ do not use the #GError facility. + * + * Functions that can fail take a return location for a #GError as their + * last argument. For example: + * |[ + * gboolean g_file_get_contents (const gchar *filename, + * gchar **contents, + * gsize *length, + * GError **error); + * ]| + * If you pass a non-%NULL value for the error + * argument, it should point to a location where an error can be placed. + * For example: + * |[ + * gchar *contents; + * GError *err = NULL; + * g_file_get_contents ("foo.txt", &contents, NULL, &err); + * g_assert ((contents == NULL && err != NULL) || (contents != NULL && err == NULL)); + * if (err != NULL) + * { + * /* Report error to user, and free error */ + * g_assert (contents == NULL); + * fprintf (stderr, "Unable to read file: %s\n", err->message); + * g_error_free (err); + * } + * else + * { + * /* Use file contents */ + * g_assert (contents != NULL); + * } + * ]| + * Note that err != NULL in this example is a + * reliable indicator of whether + * g_file_get_contents() failed. Additionally, g_file_get_contents() + * returns a boolean which indicates whether it was successful. + * + * Because g_file_get_contents() returns %FALSE on failure, if you + * are only interested in whether it failed and don't need to display + * an error message, you can pass %NULL for the error + * argument: + * |[ + * if (g_file_get_contents ("foo.txt", &contents, NULL, NULL)) /* ignore errors */ + * /* no error occurred */ ; + * else + * /* error */ ; + * ]| + * + * The #GError object contains three fields: domain + * indicates the module the error-reporting function is located in, + * code indicates the specific error that occurred, + * and message is a user-readable error message with + * as many details as possible. Several functions are provided to deal + * with an error received from a called function: g_error_matches() + * returns %TRUE if the error matches a given domain and code, + * g_propagate_error() copies an error into an error location (so the + * calling function will receive it), and g_clear_error() clears an + * error location by freeing the error and resetting the location to + * %NULL. To display an error to the user, simply display + * error->message, perhaps along with additional + * context known only to the calling function (the file being opened, + * or whatever -- though in the g_file_get_contents() case, + * error->message already contains a filename). + * + * When implementing a function that can report errors, the basic + * tool is g_set_error(). Typically, if a fatal error occurs you + * want to g_set_error(), then return immediately. g_set_error() + * does nothing if the error location passed to it is %NULL. + * Here's an example: + * |[ + * gint + * foo_open_file (GError **error) + * { + * gint fd; + * + * fd = open ("file.txt", O_RDONLY); + * + * if (fd < 0) + * { + * g_set_error (error, + * FOO_ERROR, /* error domain */ + * FOO_ERROR_BLAH, /* error code */ + * "Failed to open file: %s", /* error message format string */ + * g_strerror (errno)); + * return -1; + * } + * else + * return fd; + * } + * ]| + * + * Things are somewhat more complicated if you yourself call another + * function that can report a #GError. If the sub-function indicates + * fatal errors in some way other than reporting a #GError, such as + * by returning %TRUE on success, you can simply do the following: + * |[ + * gboolean + * my_function_that_can_fail (GError **err) + * { + * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); + * + * if (!sub_function_that_can_fail (err)) + * { + * /* assert that error was set by the sub-function */ + * g_assert (err == NULL || *err != NULL); + * return FALSE; + * } + * + * /* otherwise continue, no error occurred */ + * g_assert (err == NULL || *err == NULL); + * } + * ]| + * + * If the sub-function does not indicate errors other than by + * reporting a #GError, you need to create a temporary #GError + * since the passed-in one may be %NULL. g_propagate_error() is + * intended for use in this case. + * |[ + * gboolean + * my_function_that_can_fail (GError **err) + * { + * GError *tmp_error; + * + * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); + * + * tmp_error = NULL; + * sub_function_that_can_fail (&tmp_error); + * + * if (tmp_error != NULL) + * { + * /* store tmp_error in err, if err != NULL, + * * otherwise call g_error_free() on tmp_error + * */ + * g_propagate_error (err, tmp_error); + * return FALSE; + * } + * + * /* otherwise continue, no error occurred */ + * } + * ]| + * + * Error pileups are always a bug. For example, this code is incorrect: + * |[ + * gboolean + * my_function_that_can_fail (GError **err) + * { + * GError *tmp_error; + * + * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); + * + * tmp_error = NULL; + * sub_function_that_can_fail (&tmp_error); + * other_function_that_can_fail (&tmp_error); + * + * if (tmp_error != NULL) + * { + * g_propagate_error (err, tmp_error); + * return FALSE; + * } + * } + * ]| + * tmp_error should be checked immediately after + * sub_function_that_can_fail(), and either cleared or propagated + * upward. The rule is: after each error, you must either + * handle the error, or return it to the calling function. + * Note that passing %NULL for the error location is the equivalent + * of handling an error by always doing nothing about it. So the + * following code is fine, assuming errors in sub_function_that_can_fail() + * are not fatal to my_function_that_can_fail(): + * |[ + * gboolean + * my_function_that_can_fail (GError **err) + * { + * GError *tmp_error; + * + * g_return_val_if_fail (err == NULL || *err == NULL, FALSE); + * + * sub_function_that_can_fail (NULL); /* ignore errors */ + * + * tmp_error = NULL; + * other_function_that_can_fail (&tmp_error); + * + * if (tmp_error != NULL) + * { + * g_propagate_error (err, tmp_error); + * return FALSE; + * } + * } + * ]| + * + * Note that passing %NULL for the error location + * ignores errors; it's equivalent to + * try { sub_function_that_can_fail (); } catch (...) {} + * in C++. It does not mean to leave errors + * unhandled; it means to handle them by doing nothing. + * + * Error domains and codes are conventionally named as follows: + * + * + * The error domain is called + * <NAMESPACE>_<MODULE>_ERROR, + * for example %G_SPAWN_ERROR or %G_THREAD_ERROR: + * |[ + * #define G_SPAWN_ERROR g_spawn_error_quark () + * + * GQuark + * g_spawn_error_quark (void) + * { + * return g_quark_from_static_string ("g-spawn-error-quark"); + * } + * ]| + * + * + * The quark function for the error domain is called + * <namespace>_<module>_error_quark, + * for example g_spawn_error_quark() or g_thread_error_quark(). + * + * + * The error codes are in an enumeration called + * <Namespace><Module>Error; + * for example,#GThreadError or #GSpawnError. + * + * + * Members of the error code enumeration are called + * <NAMESPACE>_<MODULE>_ERROR_<CODE>, + * for example %G_SPAWN_ERROR_FORK or %G_THREAD_ERROR_AGAIN. + * + * + * If there's a "generic" or "unknown" error code for unrecoverable + * errors it doesn't make sense to distinguish with specific codes, + * it should be called <NAMESPACE>_<MODULE>_ERROR_FAILED, + * for example %G_SPAWN_ERROR_FAILED. + * + * + * + * Summary of rules for use of #GError: + * + * + * Do not report programming errors via #GError. + * + * + * The last argument of a function that returns an error should + * be a location where a #GError can be placed (i.e. "#GError** error"). + * If #GError is used with varargs, the #GError** should be the last + * argument before the "...". + * + * + * The caller may pass %NULL for the #GError** if they are not interested + * in details of the exact error that occurred. + * + * + * If %NULL is passed for the #GError** argument, then errors should + * not be returned to the caller, but your function should still + * abort and return if an error occurs. That is, control flow should + * not be affected by whether the caller wants to get a #GError. + * + * + * If a #GError is reported, then your function by definition + * had a fatal failure and did not complete whatever + * it was supposed to do. If the failure was not fatal, + * then you handled it and you should not report it. If it was fatal, + * then you must report it and discontinue whatever you were doing + * immediately. + * + * + * If a #GError is reported, out parameters are not guaranteed to + * be set to any defined value. + * + * + * A #GError* must be initialized to %NULL before passing its address + * to a function that can report errors. + * + * + * "Piling up" errors is always a bug. That is, if you assign a + * new #GError to a #GError* that is non-%NULL, thus overwriting + * the previous error, it indicates that you should have aborted + * the operation instead of continuing. If you were able to continue, + * you should have cleared the previous error with g_clear_error(). + * g_set_error() will complain if you pile up errors. + * + * + * By convention, if you return a boolean value indicating success + * then %TRUE means success and %FALSE means failure. If %FALSE is + * returned, the error must be set to a non-%NULL + * value. + * + * + * A %NULL return value is also frequently used to mean that an error + * occurred. You should make clear in your documentation whether %NULL + * is a valid return value in non-error cases; if %NULL is a valid value, + * then users must check whether an error was returned to see if the + * function succeeded. + * + * + * When implementing a function that can report errors, you may want + * to add a check at the top of your function that the error return + * location is either %NULL or contains a %NULL error (e.g. + * g_return_if_fail (error == NULL || *error == NULL);). + * + * + */ + +#include "config.h" + +#include "gerror.h" + +#include "gslice.h" +#include "gstrfuncs.h" +#include "gtestutils.h" + +/** + * g_error_new_valist: + * @domain: error domain + * @code: error code + * @format: printf()-style format for error message + * @args: #va_list of parameters for the message format + * + * Creates a new #GError with the given @domain and @code, + * and a message formatted with @format. + * + * Returns: a new #GError + * + * Since: 2.22 + */ +GError* +g_error_new_valist (GQuark domain, + gint code, + const gchar *format, + va_list args) +{ + GError *error; + + /* Historically, GError allowed this (although it was never meant to work), + * and it has significant use in the wild, which g_return_val_if_fail + * would break. It should maybe g_return_val_if_fail in GLib 4. + * (GNOME#660371, GNOME#560482) + */ + g_warn_if_fail (domain != 0); + g_warn_if_fail (format != NULL); + + error = g_slice_new (GError); + + error->domain = domain; + error->code = code; + error->message = g_strdup_vprintf (format, args); + + return error; +} + +/** + * g_error_new: + * @domain: error domain + * @code: error code + * @format: printf()-style format for error message + * @...: parameters for message format + * + * Creates a new #GError with the given @domain and @code, + * and a message formatted with @format. + * + * Return value: a new #GError + */ +GError* +g_error_new (GQuark domain, + gint code, + const gchar *format, + ...) +{ + GError* error; + va_list args; + + g_return_val_if_fail (format != NULL, NULL); + g_return_val_if_fail (domain != 0, NULL); + + va_start (args, format); + error = g_error_new_valist (domain, code, format, args); + va_end (args); + + return error; +} + +/** + * g_error_new_literal: + * @domain: error domain + * @code: error code + * @message: error message + * + * Creates a new #GError; unlike g_error_new(), @message is + * not a printf()-style format string. Use this function if + * @message contains text you don't have control over, + * that could include printf() escape sequences. + * + * Return value: a new #GError + **/ +GError* +g_error_new_literal (GQuark domain, + gint code, + const gchar *message) +{ + GError* err; + + g_return_val_if_fail (message != NULL, NULL); + g_return_val_if_fail (domain != 0, NULL); + + err = g_slice_new (GError); + + err->domain = domain; + err->code = code; + err->message = g_strdup (message); + + return err; +} + +/** + * g_error_free: + * @error: a #GError + * + * Frees a #GError and associated resources. + */ +void +g_error_free (GError *error) +{ + g_return_if_fail (error != NULL); + + g_free (error->message); + + g_slice_free (GError, error); +} + +/** + * g_error_copy: + * @error: a #GError + * + * Makes a copy of @error. + * + * Return value: a new #GError + */ +GError* +g_error_copy (const GError *error) +{ + GError *copy; + + g_return_val_if_fail (error != NULL, NULL); + /* See g_error_new_valist for why these don't return */ + g_warn_if_fail (error->domain != 0); + g_warn_if_fail (error->message != NULL); + + copy = g_slice_new (GError); + + *copy = *error; + + copy->message = g_strdup (error->message); + + return copy; +} + +/** + * g_error_matches: + * @error: a #GError or %NULL + * @domain: an error domain + * @code: an error code + * + * Returns %TRUE if @error matches @domain and @code, %FALSE + * otherwise. In particular, when @error is %NULL, %FALSE will + * be returned. + * + * Return value: whether @error has @domain and @code + */ +gboolean +g_error_matches (const GError *error, + GQuark domain, + gint code) +{ + return error && + error->domain == domain && + error->code == code; +} + +#define ERROR_OVERWRITTEN_WARNING "GError set over the top of a previous GError or uninitialized memory.\n" \ + "This indicates a bug in someone's code. You must ensure an error is NULL before it's set.\n" \ + "The overwriting error message was: %s" + +/** + * g_set_error: + * @err: a return location for a #GError, or %NULL + * @domain: error domain + * @code: error code + * @format: printf()-style format + * @...: args for @format + * + * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err + * must be %NULL. A new #GError is created and assigned to *@err. + */ +void +g_set_error (GError **err, + GQuark domain, + gint code, + const gchar *format, + ...) +{ + GError *new; + + va_list args; + + if (err == NULL) + return; + + va_start (args, format); + new = g_error_new_valist (domain, code, format, args); + va_end (args); + + if (*err == NULL) + *err = new; + else + g_warning (ERROR_OVERWRITTEN_WARNING, new->message); +} + +/** + * g_set_error_literal: + * @err: a return location for a #GError, or %NULL + * @domain: error domain + * @code: error code + * @message: error message + * + * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err + * must be %NULL. A new #GError is created and assigned to *@err. + * Unlike g_set_error(), @message is not a printf()-style format string. + * Use this function if @message contains text you don't have control over, + * that could include printf() escape sequences. + * + * Since: 2.18 + */ +void +g_set_error_literal (GError **err, + GQuark domain, + gint code, + const gchar *message) +{ + GError *new; + + if (err == NULL) + return; + + new = g_error_new_literal (domain, code, message); + if (*err == NULL) + *err = new; + else + g_warning (ERROR_OVERWRITTEN_WARNING, new->message); +} + +/** + * g_propagate_error: + * @dest: error return location + * @src: error to move into the return location + * + * If @dest is %NULL, free @src; otherwise, moves @src into *@dest. + * The error variable @dest points to must be %NULL. + */ +void +g_propagate_error (GError **dest, + GError *src) +{ + g_return_if_fail (src != NULL); + + if (dest == NULL) + { + if (src) + g_error_free (src); + return; + } + else + { + if (*dest != NULL) + g_warning (ERROR_OVERWRITTEN_WARNING, src->message); + else + *dest = src; + } +} + +/** + * g_clear_error: + * @err: a #GError return location + * + * If @err is %NULL, does nothing. If @err is non-%NULL, + * calls g_error_free() on *@err and sets *@err to %NULL. + */ +void +g_clear_error (GError **err) +{ + if (err && *err) + { + g_error_free (*err); + *err = NULL; + } +} + +static void +g_error_add_prefix (gchar **string, + const gchar *format, + va_list ap) +{ + gchar *oldstring; + gchar *prefix; + + prefix = g_strdup_vprintf (format, ap); + oldstring = *string; + *string = g_strconcat (prefix, oldstring, NULL); + g_free (oldstring); + g_free (prefix); +} + +/** + * g_prefix_error: + * @err: a return location for a #GError, or %NULL + * @format: printf()-style format string + * @...: arguments to @format + * + * Formats a string according to @format and + * prefix it to an existing error message. If + * @err is %NULL (ie: no error variable) then do + * nothing. + * + * If *@err is %NULL (ie: an error variable is + * present but there is no error condition) then + * also do nothing. Whether or not it makes + * sense to take advantage of this feature is up + * to you. + * + * Since: 2.16 + */ +void +g_prefix_error (GError **err, + const gchar *format, + ...) +{ + if (err && *err) + { + va_list ap; + + va_start (ap, format); + g_error_add_prefix (&(*err)->message, format, ap); + va_end (ap); + } +} + +/** + * g_propagate_prefixed_error: + * @dest: error return location + * @src: error to move into the return location + * @format: printf()-style format string + * @...: arguments to @format + * + * If @dest is %NULL, free @src; otherwise, + * moves @src into *@dest. *@dest must be %NULL. + * After the move, add a prefix as with + * g_prefix_error(). + * + * Since: 2.16 + **/ +void +g_propagate_prefixed_error (GError **dest, + GError *src, + const gchar *format, + ...) +{ + g_propagate_error (dest, src); + + if (dest && *dest) + { + va_list ap; + + va_start (ap, format); + g_error_add_prefix (&(*dest)->message, format, ap); + va_end (ap); + } +} diff --git a/glib/glib/gerror.h b/glib/glib/gerror.h new file mode 100644 index 0000000..6eb65fe --- /dev/null +++ b/glib/glib/gerror.h @@ -0,0 +1,107 @@ +/* gerror.h - Error reporting system + * + * Copyright 2000 Red Hat, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_ERROR_H__ +#define __G_ERROR_H__ + +#include + +#include + +G_BEGIN_DECLS + +/** + * GError: + * @domain: error domain, e.g. #G_FILE_ERROR + * @code: error code, e.g. %G_FILE_ERROR_NOENT + * @message: human-readable informative error message + * + * The GError structure contains + * information about an error that has occurred. + */ +typedef struct _GError GError; + +struct _GError +{ + GQuark domain; + gint code; + gchar *message; +}; + +GError* g_error_new (GQuark domain, + gint code, + const gchar *format, + ...) G_GNUC_PRINTF (3, 4); + +GError* g_error_new_literal (GQuark domain, + gint code, + const gchar *message); +GError* g_error_new_valist (GQuark domain, + gint code, + const gchar *format, + va_list args); + +void g_error_free (GError *error); +GError* g_error_copy (const GError *error); + +gboolean g_error_matches (const GError *error, + GQuark domain, + gint code); + +/* if (err) *err = g_error_new(domain, code, format, ...), also has + * some sanity checks. + */ +void g_set_error (GError **err, + GQuark domain, + gint code, + const gchar *format, + ...) G_GNUC_PRINTF (4, 5); + +void g_set_error_literal (GError **err, + GQuark domain, + gint code, + const gchar *message); + +/* if (dest) *dest = src; also has some sanity checks. + */ +void g_propagate_error (GError **dest, + GError *src); + +/* if (err && *err) { g_error_free(*err); *err = NULL; } */ +void g_clear_error (GError **err); + +/* if (err) prefix the formatted string to the ->message */ +void g_prefix_error (GError **err, + const gchar *format, + ...) G_GNUC_PRINTF (2, 3); + +/* g_propagate_error then g_error_prefix on dest */ +void g_propagate_prefixed_error (GError **dest, + GError *src, + const gchar *format, + ...) G_GNUC_PRINTF (3, 4); + +G_END_DECLS + +#endif /* __G_ERROR_H__ */ diff --git a/glib/glib/gfileutils.c b/glib/glib/gfileutils.c new file mode 100644 index 0000000..cb306ef --- /dev/null +++ b/glib/glib/gfileutils.c @@ -0,0 +1,2654 @@ +/* gfileutils.c - File utility functions + * + * Copyright 2000 Red Hat, Inc. + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include "glibconfig.h" + +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef G_OS_WIN32 +#include +#include +#endif /* G_OS_WIN32 */ + +#ifndef S_ISLNK +#define S_ISLNK(x) 0 +#endif + +#ifndef O_BINARY +#define O_BINARY 0 +#endif + +#include "gfileutils.h" + +#include "gstdio.h" +#include "glibintl.h" + +#ifdef HAVE_LINUX_MAGIC_H /* for btrfs check */ +#include +#include +#endif + + +/** + * SECTION:fileutils + * @title: File Utilities + * @short_description: various file-related functions + * + * There is a group of functions which wrap the common POSIX functions + * dealing with filenames (g_open(), g_rename(), g_mkdir(), g_stat(), + * g_unlink(), g_remove(), g_fopen(), g_freopen()). The point of these + * wrappers is to make it possible to handle file names with any Unicode + * characters in them on Windows without having to use ifdefs and the + * wide character API in the application code. + * + * The pathname argument should be in the GLib file name encoding. + * On POSIX this is the actual on-disk encoding which might correspond + * to the locale settings of the process (or the + * G_FILENAME_ENCODING environment variable), or not. + * + * On Windows the GLib file name encoding is UTF-8. Note that the + * Microsoft C library does not use UTF-8, but has separate APIs for + * current system code page and wide characters (UTF-16). The GLib + * wrappers call the wide character API if present (on modern Windows + * systems), otherwise convert to/from the system code page. + * + * Another group of functions allows to open and read directories + * in the GLib file name encoding. These are g_dir_open(), + * g_dir_read_name(), g_dir_rewind(), g_dir_close(). + */ + +/** + * GFileError: + * @G_FILE_ERROR_EXIST: Operation not permitted; only the owner of + * the file (or other resource) or processes with special privileges + * can perform the operation. + * @G_FILE_ERROR_ISDIR: File is a directory; you cannot open a directory + * for writing, or create or remove hard links to it. + * @G_FILE_ERROR_ACCES: Permission denied; the file permissions do not + * allow the attempted operation. + * @G_FILE_ERROR_NAMETOOLONG: Filename too long. + * @G_FILE_ERROR_NOENT: No such file or directory. This is a "file + * doesn't exist" error for ordinary files that are referenced in + * contexts where they are expected to already exist. + * @G_FILE_ERROR_NOTDIR: A file that isn't a directory was specified when + * a directory is required. + * @G_FILE_ERROR_NXIO: No such device or address. The system tried to + * use the device represented by a file you specified, and it + * couldn't find the device. This can mean that the device file was + * installed incorrectly, or that the physical device is missing or + * not correctly attached to the computer. + * @G_FILE_ERROR_NODEV: The underlying file system of the specified file + * does not support memory mapping. + * @G_FILE_ERROR_ROFS: The directory containing the new link can't be + * modified because it's on a read-only file system. + * @G_FILE_ERROR_TXTBSY: Text file busy. + * @G_FILE_ERROR_FAULT: You passed in a pointer to bad memory. + * (GLib won't reliably return this, don't pass in pointers to bad + * memory.) + * @G_FILE_ERROR_LOOP: Too many levels of symbolic links were encountered + * in looking up a file name. This often indicates a cycle of symbolic + * links. + * @G_FILE_ERROR_NOSPC: No space left on device; write operation on a + * file failed because the disk is full. + * @G_FILE_ERROR_NOMEM: No memory available. The system cannot allocate + * more virtual memory because its capacity is full. + * @G_FILE_ERROR_MFILE: The current process has too many files open and + * can't open any more. Duplicate descriptors do count toward this + * limit. + * @G_FILE_ERROR_NFILE: There are too many distinct file openings in the + * entire system. + * @G_FILE_ERROR_BADF: Bad file descriptor; for example, I/O on a + * descriptor that has been closed or reading from a descriptor open + * only for writing (or vice versa). + * @G_FILE_ERROR_INVAL: Invalid argument. This is used to indicate + * various kinds of problems with passing the wrong argument to a + * library function. + * @G_FILE_ERROR_PIPE: Broken pipe; there is no process reading from the + * other end of a pipe. Every library function that returns this + * error code also generates a `SIGPIPE' signal; this signal + * terminates the program if not handled or blocked. Thus, your + * program will never actually see this code unless it has handled + * or blocked `SIGPIPE'. + * @G_FILE_ERROR_AGAIN: Resource temporarily unavailable; the call might + * work if you try again later. + * @G_FILE_ERROR_INTR: Interrupted function call; an asynchronous signal + * occurred and prevented completion of the call. When this + * happens, you should try the call again. + * @G_FILE_ERROR_IO: Input/output error; usually used for physical read + * or write errors. i.e. the disk or other physical device hardware + * is returning errors. + * @G_FILE_ERROR_PERM: Operation not permitted; only the owner of the + * file (or other resource) or processes with special privileges can + * perform the operation. + * @G_FILE_ERROR_NOSYS: Function not implemented; this indicates that + * the system is missing some functionality. + * @G_FILE_ERROR_FAILED: Does not correspond to a UNIX error code; this + * is the standard "failed for unspecified reason" error code present + * in all #GError error code enumerations. Returned if no specific + * code applies. + * + * Values corresponding to @errno codes returned from file operations + * on UNIX. Unlike @errno codes, GFileError values are available on + * all systems, even Windows. The exact meaning of each code depends + * on what sort of file operation you were performing; the UNIX + * documentation gives more details. The following error code descriptions + * come from the GNU C Library manual, and are under the copyright + * of that manual. + * + * It's not very portable to make detailed assumptions about exactly + * which errors will be returned from a given operation. Some errors + * don't occur on some systems, etc., sometimes there are subtle + * differences in when a system will report a given error, etc. + */ + +/** + * G_FILE_ERROR: + * + * Error domain for file operations. Errors in this domain will + * be from the #GFileError enumeration. See #GError for information + * on error domains. + */ + +/** + * GFileTest: + * @G_FILE_TEST_IS_REGULAR: %TRUE if the file is a regular file + * (not a directory). Note that this test will also return %TRUE + * if the tested file is a symlink to a regular file. + * @G_FILE_TEST_IS_SYMLINK: %TRUE if the file is a symlink. + * @G_FILE_TEST_IS_DIR: %TRUE if the file is a directory. + * @G_FILE_TEST_IS_EXECUTABLE: %TRUE if the file is executable. + * @G_FILE_TEST_EXISTS: %TRUE if the file exists. It may or may not + * be a regular file. + * + * A test to perform on a file using g_file_test(). + */ + +/** + * g_mkdir_with_parents: + * @pathname: a pathname in the GLib file name encoding + * @mode: permissions to use for newly created directories + * + * Create a directory if it doesn't already exist. Create intermediate + * parent directories as needed, too. + * + * Returns: 0 if the directory already exists, or was successfully + * created. Returns -1 if an error occurred, with errno set. + * + * Since: 2.8 + */ +int +g_mkdir_with_parents (const gchar *pathname, + int mode) +{ + gchar *fn, *p; + + if (pathname == NULL || *pathname == '\0') + { + errno = EINVAL; + return -1; + } + + fn = g_strdup (pathname); + + if (g_path_is_absolute (fn)) + p = (gchar *) g_path_skip_root (fn); + else + p = fn; + + do + { + while (*p && !G_IS_DIR_SEPARATOR (*p)) + p++; + + if (!*p) + p = NULL; + else + *p = '\0'; + + if (!g_file_test (fn, G_FILE_TEST_EXISTS)) + { + if (g_mkdir (fn, mode) == -1 && errno != EEXIST) + { + int errno_save = errno; + g_free (fn); + errno = errno_save; + return -1; + } + } + else if (!g_file_test (fn, G_FILE_TEST_IS_DIR)) + { + g_free (fn); + errno = ENOTDIR; + return -1; + } + if (p) + { + *p++ = G_DIR_SEPARATOR; + while (*p && G_IS_DIR_SEPARATOR (*p)) + p++; + } + } + while (p); + + g_free (fn); + + return 0; +} + +/** + * g_file_test: + * @filename: a filename to test in the GLib file name encoding + * @test: bitfield of #GFileTest flags + * + * Returns %TRUE if any of the tests in the bitfield @test are + * %TRUE. For example, (G_FILE_TEST_EXISTS | + * G_FILE_TEST_IS_DIR) will return %TRUE if the file exists; + * the check whether it's a directory doesn't matter since the existence + * test is %TRUE. With the current set of available tests, there's no point + * passing in more than one test at a time. + * + * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links, + * so for a symbolic link to a regular file g_file_test() will return + * %TRUE for both %G_FILE_TEST_IS_SYMLINK and %G_FILE_TEST_IS_REGULAR. + * + * Note, that for a dangling symbolic link g_file_test() will return + * %TRUE for %G_FILE_TEST_IS_SYMLINK and %FALSE for all other flags. + * + * You should never use g_file_test() to test whether it is safe + * to perform an operation, because there is always the possibility + * of the condition changing before you actually perform the operation. + * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK + * to know whether it is safe to write to a file without being + * tricked into writing into a different location. It doesn't work! + * |[ + * /* DON'T DO THIS */ + * if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) + * { + * fd = g_open (filename, O_WRONLY); + * /* write to fd */ + * } + * ]| + * + * Another thing to note is that %G_FILE_TEST_EXISTS and + * %G_FILE_TEST_IS_EXECUTABLE are implemented using the access() + * system call. This usually doesn't matter, but if your program + * is setuid or setgid it means that these tests will give you + * the answer for the real user ID and group ID, rather than the + * effective user ID and group ID. + * + * On Windows, there are no symlinks, so testing for + * %G_FILE_TEST_IS_SYMLINK will always return %FALSE. Testing for + * %G_FILE_TEST_IS_EXECUTABLE will just check that the file exists and + * its name indicates that it is executable, checking for well-known + * extensions and those listed in the PATHEXT environment variable. + * + * Return value: whether a test was %TRUE + **/ +gboolean +g_file_test (const gchar *filename, + GFileTest test) +{ +#ifdef G_OS_WIN32 +/* stuff missing in std vc6 api */ +# ifndef INVALID_FILE_ATTRIBUTES +# define INVALID_FILE_ATTRIBUTES -1 +# endif +# ifndef FILE_ATTRIBUTE_DEVICE +# define FILE_ATTRIBUTE_DEVICE 64 +# endif + int attributes; + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + + if (wfilename == NULL) + return FALSE; + + attributes = GetFileAttributesW (wfilename); + + g_free (wfilename); + + if (attributes == INVALID_FILE_ATTRIBUTES) + return FALSE; + + if (test & G_FILE_TEST_EXISTS) + return TRUE; + + if (test & G_FILE_TEST_IS_REGULAR) + { + if ((attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0) + return TRUE; + } + + if (test & G_FILE_TEST_IS_DIR) + { + if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + return TRUE; + } + + /* "while" so that we can exit this "loop" with a simple "break" */ + while (test & G_FILE_TEST_IS_EXECUTABLE) + { + const gchar *lastdot = strrchr (filename, '.'); + const gchar *pathext = NULL, *p; + int extlen; + + if (lastdot == NULL) + break; + + if (_stricmp (lastdot, ".exe") == 0 || + _stricmp (lastdot, ".cmd") == 0 || + _stricmp (lastdot, ".bat") == 0 || + _stricmp (lastdot, ".com") == 0) + return TRUE; + + /* Check if it is one of the types listed in %PATHEXT% */ + + pathext = g_getenv ("PATHEXT"); + if (pathext == NULL) + break; + + pathext = g_utf8_casefold (pathext, -1); + + lastdot = g_utf8_casefold (lastdot, -1); + extlen = strlen (lastdot); + + p = pathext; + while (TRUE) + { + const gchar *q = strchr (p, ';'); + if (q == NULL) + q = p + strlen (p); + if (extlen == q - p && + memcmp (lastdot, p, extlen) == 0) + { + g_free ((gchar *) pathext); + g_free ((gchar *) lastdot); + return TRUE; + } + if (*q) + p = q + 1; + else + break; + } + + g_free ((gchar *) pathext); + g_free ((gchar *) lastdot); + break; + } + + return FALSE; +#else + if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0)) + return TRUE; + + if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0)) + { + if (getuid () != 0) + return TRUE; + + /* For root, on some POSIX systems, access (filename, X_OK) + * will succeed even if no executable bits are set on the + * file. We fall through to a stat test to avoid that. + */ + } + else + test &= ~G_FILE_TEST_IS_EXECUTABLE; + + if (test & G_FILE_TEST_IS_SYMLINK) + { + struct stat s; + + if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode)) + return TRUE; + } + + if (test & (G_FILE_TEST_IS_REGULAR | + G_FILE_TEST_IS_DIR | + G_FILE_TEST_IS_EXECUTABLE)) + { + struct stat s; + + if (stat (filename, &s) == 0) + { + if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode)) + return TRUE; + + if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode)) + return TRUE; + + /* The extra test for root when access (file, X_OK) succeeds. + */ + if ((test & G_FILE_TEST_IS_EXECUTABLE) && + ((s.st_mode & S_IXOTH) || + (s.st_mode & S_IXUSR) || + (s.st_mode & S_IXGRP))) + return TRUE; + } + } + + return FALSE; +#endif +} + +GQuark +g_file_error_quark (void) +{ + return g_quark_from_static_string ("g-file-error-quark"); +} + +/** + * g_file_error_from_errno: + * @err_no: an "errno" value + * + * Gets a #GFileError constant based on the passed-in @err_no. + * For example, if you pass in EEXIST this function returns + * #G_FILE_ERROR_EXIST. Unlike errno values, you can portably + * assume that all #GFileError values will exist. + * + * Normally a #GFileError value goes into a #GError returned + * from a function that manipulates files. So you would use + * g_file_error_from_errno() when constructing a #GError. + * + * Return value: #GFileError corresponding to the given @errno + **/ +GFileError +g_file_error_from_errno (gint err_no) +{ + switch (err_no) + { +#ifdef EEXIST + case EEXIST: + return G_FILE_ERROR_EXIST; + break; +#endif + +#ifdef EISDIR + case EISDIR: + return G_FILE_ERROR_ISDIR; + break; +#endif + +#ifdef EACCES + case EACCES: + return G_FILE_ERROR_ACCES; + break; +#endif + +#ifdef ENAMETOOLONG + case ENAMETOOLONG: + return G_FILE_ERROR_NAMETOOLONG; + break; +#endif + +#ifdef ENOENT + case ENOENT: + return G_FILE_ERROR_NOENT; + break; +#endif + +#ifdef ENOTDIR + case ENOTDIR: + return G_FILE_ERROR_NOTDIR; + break; +#endif + +#ifdef ENXIO + case ENXIO: + return G_FILE_ERROR_NXIO; + break; +#endif + +#ifdef ENODEV + case ENODEV: + return G_FILE_ERROR_NODEV; + break; +#endif + +#ifdef EROFS + case EROFS: + return G_FILE_ERROR_ROFS; + break; +#endif + +#ifdef ETXTBSY + case ETXTBSY: + return G_FILE_ERROR_TXTBSY; + break; +#endif + +#ifdef EFAULT + case EFAULT: + return G_FILE_ERROR_FAULT; + break; +#endif + +#ifdef ELOOP + case ELOOP: + return G_FILE_ERROR_LOOP; + break; +#endif + +#ifdef ENOSPC + case ENOSPC: + return G_FILE_ERROR_NOSPC; + break; +#endif + +#ifdef ENOMEM + case ENOMEM: + return G_FILE_ERROR_NOMEM; + break; +#endif + +#ifdef EMFILE + case EMFILE: + return G_FILE_ERROR_MFILE; + break; +#endif + +#ifdef ENFILE + case ENFILE: + return G_FILE_ERROR_NFILE; + break; +#endif + +#ifdef EBADF + case EBADF: + return G_FILE_ERROR_BADF; + break; +#endif + +#ifdef EINVAL + case EINVAL: + return G_FILE_ERROR_INVAL; + break; +#endif + +#ifdef EPIPE + case EPIPE: + return G_FILE_ERROR_PIPE; + break; +#endif + +#ifdef EAGAIN + case EAGAIN: + return G_FILE_ERROR_AGAIN; + break; +#endif + +#ifdef EINTR + case EINTR: + return G_FILE_ERROR_INTR; + break; +#endif + +#ifdef EIO + case EIO: + return G_FILE_ERROR_IO; + break; +#endif + +#ifdef EPERM + case EPERM: + return G_FILE_ERROR_PERM; + break; +#endif + +#ifdef ENOSYS + case ENOSYS: + return G_FILE_ERROR_NOSYS; + break; +#endif + + default: + return G_FILE_ERROR_FAILED; + break; + } +} + +static gboolean +get_contents_stdio (const gchar *display_filename, + FILE *f, + gchar **contents, + gsize *length, + GError **error) +{ + gchar buf[4096]; + gsize bytes; + gchar *str = NULL; + gsize total_bytes = 0; + gsize total_allocated = 0; + gchar *tmp; + + g_assert (f != NULL); + + while (!feof (f)) + { + gint save_errno; + + bytes = fread (buf, 1, sizeof (buf), f); + save_errno = errno; + + while ((total_bytes + bytes + 1) > total_allocated) + { + if (str) + total_allocated *= 2; + else + total_allocated = MIN (bytes + 1, sizeof (buf)); + + tmp = g_try_realloc (str, total_allocated); + + if (tmp == NULL) + { + g_set_error (error, + G_FILE_ERROR, + G_FILE_ERROR_NOMEM, + _("Could not allocate %lu bytes to read file \"%s\""), + (gulong) total_allocated, + display_filename); + + goto error; + } + + str = tmp; + } + + if (ferror (f)) + { + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Error reading file '%s': %s"), + display_filename, + g_strerror (save_errno)); + + goto error; + } + + memcpy (str + total_bytes, buf, bytes); + + if (total_bytes + bytes < total_bytes) + { + g_set_error (error, + G_FILE_ERROR, + G_FILE_ERROR_FAILED, + _("File \"%s\" is too large"), + display_filename); + + goto error; + } + + total_bytes += bytes; + } + + fclose (f); + + if (total_allocated == 0) + { + str = g_new (gchar, 1); + total_bytes = 0; + } + + str[total_bytes] = '\0'; + + if (length) + *length = total_bytes; + + *contents = str; + + return TRUE; + + error: + + g_free (str); + fclose (f); + + return FALSE; +} + +#ifndef G_OS_WIN32 + +static gboolean +get_contents_regfile (const gchar *display_filename, + struct stat *stat_buf, + gint fd, + gchar **contents, + gsize *length, + GError **error) +{ + gchar *buf; + gsize bytes_read; + gsize size; + gsize alloc_size; + + size = stat_buf->st_size; + + alloc_size = size + 1; + buf = g_try_malloc (alloc_size); + + if (buf == NULL) + { + g_set_error (error, + G_FILE_ERROR, + G_FILE_ERROR_NOMEM, + _("Could not allocate %lu bytes to read file \"%s\""), + (gulong) alloc_size, + display_filename); + + goto error; + } + + bytes_read = 0; + while (bytes_read < size) + { + gssize rc; + + rc = read (fd, buf + bytes_read, size - bytes_read); + + if (rc < 0) + { + if (errno != EINTR) + { + int save_errno = errno; + + g_free (buf); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to read from file '%s': %s"), + display_filename, + g_strerror (save_errno)); + + goto error; + } + } + else if (rc == 0) + break; + else + bytes_read += rc; + } + + buf[bytes_read] = '\0'; + + if (length) + *length = bytes_read; + + *contents = buf; + + close (fd); + + return TRUE; + + error: + + close (fd); + + return FALSE; +} + +static gboolean +get_contents_posix (const gchar *filename, + gchar **contents, + gsize *length, + GError **error) +{ + struct stat stat_buf; + gint fd; + gchar *display_filename = g_filename_display_name (filename); + + /* O_BINARY useful on Cygwin */ + fd = open (filename, O_RDONLY|O_BINARY); + + if (fd < 0) + { + int save_errno = errno; + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open file '%s': %s"), + display_filename, + g_strerror (save_errno)); + g_free (display_filename); + + return FALSE; + } + + /* I don't think this will ever fail, aside from ENOMEM, but. */ + if (fstat (fd, &stat_buf) < 0) + { + int save_errno = errno; + + close (fd); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to get attributes of file '%s': fstat() failed: %s"), + display_filename, + g_strerror (save_errno)); + g_free (display_filename); + + return FALSE; + } + + if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode)) + { + gboolean retval = get_contents_regfile (display_filename, + &stat_buf, + fd, + contents, + length, + error); + g_free (display_filename); + + return retval; + } + else + { + FILE *f; + gboolean retval; + + f = fdopen (fd, "r"); + + if (f == NULL) + { + int save_errno = errno; + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open file '%s': fdopen() failed: %s"), + display_filename, + g_strerror (save_errno)); + g_free (display_filename); + + return FALSE; + } + + retval = get_contents_stdio (display_filename, f, contents, length, error); + g_free (display_filename); + + return retval; + } +} + +#else /* G_OS_WIN32 */ + +static gboolean +get_contents_win32 (const gchar *filename, + gchar **contents, + gsize *length, + GError **error) +{ + FILE *f; + gboolean retval; + gchar *display_filename = g_filename_display_name (filename); + int save_errno; + + f = g_fopen (filename, "rb"); + save_errno = errno; + + if (f == NULL) + { + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open file '%s': %s"), + display_filename, + g_strerror (save_errno)); + g_free (display_filename); + + return FALSE; + } + + retval = get_contents_stdio (display_filename, f, contents, length, error); + g_free (display_filename); + + return retval; +} + +#endif + +/** + * g_file_get_contents: + * @filename: (type filename): name of a file to read contents from, in the GLib file name encoding + * @contents: (out) (array length=length) (element-type guint8): location to store an allocated string, use g_free() to free + * the returned string + * @length: (allow-none): location to store length in bytes of the contents, or %NULL + * @error: return location for a #GError, or %NULL + * + * Reads an entire file into allocated memory, with good error + * checking. + * + * If the call was successful, it returns %TRUE and sets @contents to the file + * contents and @length to the length of the file contents in bytes. The string + * stored in @contents will be nul-terminated, so for text files you can pass + * %NULL for the @length argument. If the call was not successful, it returns + * %FALSE and sets @error. The error domain is #G_FILE_ERROR. Possible error + * codes are those in the #GFileError enumeration. In the error case, + * @contents is set to %NULL and @length is set to zero. + * + * Return value: %TRUE on success, %FALSE if an error occurred + **/ +gboolean +g_file_get_contents (const gchar *filename, + gchar **contents, + gsize *length, + GError **error) +{ + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (contents != NULL, FALSE); + + *contents = NULL; + if (length) + *length = 0; + +#ifdef G_OS_WIN32 + return get_contents_win32 (filename, contents, length, error); +#else + return get_contents_posix (filename, contents, length, error); +#endif +} + +static gboolean +rename_file (const char *old_name, + const char *new_name, + GError **err) +{ + errno = 0; + if (g_rename (old_name, new_name) == -1) + { + int save_errno = errno; + gchar *display_old_name = g_filename_display_name (old_name); + gchar *display_new_name = g_filename_display_name (new_name); + + g_set_error (err, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to rename file '%s' to '%s': g_rename() failed: %s"), + display_old_name, + display_new_name, + g_strerror (save_errno)); + + g_free (display_old_name); + g_free (display_new_name); + + return FALSE; + } + + return TRUE; +} + +static gchar * +write_to_temp_file (const gchar *contents, + gssize length, + const gchar *dest_file, + GError **err) +{ + gchar *tmp_name; + gchar *display_name; + gchar *retval; + FILE *file; + gint fd; + int save_errno; + + retval = NULL; + + tmp_name = g_strdup_printf ("%s.XXXXXX", dest_file); + + errno = 0; + fd = g_mkstemp_full (tmp_name, O_RDWR | O_BINARY, 0666); + save_errno = errno; + + display_name = g_filename_display_name (tmp_name); + + if (fd == -1) + { + g_set_error (err, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to create file '%s': %s"), + display_name, g_strerror (save_errno)); + + goto out; + } + + errno = 0; + file = fdopen (fd, "wb"); + if (!file) + { + save_errno = errno; + g_set_error (err, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open file '%s' for writing: fdopen() failed: %s"), + display_name, + g_strerror (save_errno)); + + close (fd); + g_unlink (tmp_name); + + goto out; + } + + if (length > 0) + { + gsize n_written; + + errno = 0; + + n_written = fwrite (contents, 1, length, file); + + if (n_written < length) + { + save_errno = errno; + + g_set_error (err, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to write file '%s': fwrite() failed: %s"), + display_name, + g_strerror (save_errno)); + + fclose (file); + g_unlink (tmp_name); + + goto out; + } + } + + errno = 0; + if (fflush (file) != 0) + { + save_errno = errno; + + g_set_error (err, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to write file '%s': fflush() failed: %s"), + display_name, + g_strerror (save_errno)); + + fclose (file); + g_unlink (tmp_name); + + goto out; + } + +#ifdef BTRFS_SUPER_MAGIC + { + struct statfs buf; + + /* On Linux, on btrfs, skip the fsync since rename-over-existing is + * guaranteed to be atomic and this is the only case in which we + * would fsync() anyway. + */ + + if (fstatfs (fd, &buf) == 0 && buf.f_type == BTRFS_SUPER_MAGIC) + goto no_fsync; + } +#endif + +#ifdef HAVE_FSYNC + { + struct stat statbuf; + + errno = 0; + /* If the final destination exists and is > 0 bytes, we want to sync the + * newly written file to ensure the data is on disk when we rename over + * the destination. Otherwise if we get a system crash we can lose both + * the new and the old file on some filesystems. (I.E. those that don't + * guarantee the data is written to the disk before the metadata.) + */ + if (g_lstat (dest_file, &statbuf) == 0 && + statbuf.st_size > 0 && + fsync (fileno (file)) != 0) + { + save_errno = errno; + + g_set_error (err, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to write file '%s': fsync() failed: %s"), + display_name, + g_strerror (save_errno)); + + fclose (file); + g_unlink (tmp_name); + + goto out; + } + } +#endif + +#ifdef BTRFS_SUPER_MAGIC + no_fsync: +#endif + + errno = 0; + if (fclose (file) == EOF) + { + save_errno = errno; + + g_set_error (err, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to close file '%s': fclose() failed: %s"), + display_name, + g_strerror (save_errno)); + + fclose (file); + g_unlink (tmp_name); + + goto out; + } + + retval = g_strdup (tmp_name); + + out: + g_free (tmp_name); + g_free (display_name); + + return retval; +} + +/** + * g_file_set_contents: + * @filename: (type filename): name of a file to write @contents to, in the GLib file name + * encoding + * @contents: (array length=length) (element-type guint8): string to write to the file + * @length: length of @contents, or -1 if @contents is a nul-terminated string + * @error: return location for a #GError, or %NULL + * + * Writes all of @contents to a file named @filename, with good error checking. + * If a file called @filename already exists it will be overwritten. + * + * This write is atomic in the sense that it is first written to a temporary + * file which is then renamed to the final name. Notes: + * + * + * On Unix, if @filename already exists hard links to @filename will break. + * Also since the file is recreated, existing permissions, access control + * lists, metadata etc. may be lost. If @filename is a symbolic link, + * the link itself will be replaced, not the linked file. + * + * + * On Windows renaming a file will not remove an existing file with the + * new name, so on Windows there is a race condition between the existing + * file being removed and the temporary file being renamed. + * + * + * On Windows there is no way to remove a file that is open to some + * process, or mapped into memory. Thus, this function will fail if + * @filename already exists and is open. + * + * + * + * If the call was successful, it returns %TRUE. If the call was not successful, + * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR. + * Possible error codes are those in the #GFileError enumeration. + * + * Note that the name for the temporary file is constructed by appending up + * to 7 characters to @filename. + * + * Return value: %TRUE on success, %FALSE if an error occurred + * + * Since: 2.8 + **/ +gboolean +g_file_set_contents (const gchar *filename, + const gchar *contents, + gssize length, + GError **error) +{ + gchar *tmp_filename; + gboolean retval; + GError *rename_error = NULL; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (contents != NULL || length == 0, FALSE); + g_return_val_if_fail (length >= -1, FALSE); + + if (length == -1) + length = strlen (contents); + + tmp_filename = write_to_temp_file (contents, length, filename, error); + + if (!tmp_filename) + { + retval = FALSE; + goto out; + } + + if (!rename_file (tmp_filename, filename, &rename_error)) + { +#ifndef G_OS_WIN32 + + g_unlink (tmp_filename); + g_propagate_error (error, rename_error); + retval = FALSE; + goto out; + +#else /* G_OS_WIN32 */ + + /* Renaming failed, but on Windows this may just mean + * the file already exists. So if the target file + * exists, try deleting it and do the rename again. + */ + if (!g_file_test (filename, G_FILE_TEST_EXISTS)) + { + g_unlink (tmp_filename); + g_propagate_error (error, rename_error); + retval = FALSE; + goto out; + } + + g_error_free (rename_error); + + if (g_unlink (filename) == -1) + { + gchar *display_filename = g_filename_display_name (filename); + + int save_errno = errno; + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Existing file '%s' could not be removed: g_unlink() failed: %s"), + display_filename, + g_strerror (save_errno)); + + g_free (display_filename); + g_unlink (tmp_filename); + retval = FALSE; + goto out; + } + + if (!rename_file (tmp_filename, filename, error)) + { + g_unlink (tmp_filename); + retval = FALSE; + goto out; + } + +#endif + } + + retval = TRUE; + + out: + g_free (tmp_filename); + return retval; +} + +/* + * get_tmp_file based on the mkstemp implementation from the GNU C library. + * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc. + */ +typedef gint (*GTmpFileCallback) (gchar *, gint, gint); + +static gint +get_tmp_file (gchar *tmpl, + GTmpFileCallback f, + int flags, + int mode) +{ + char *XXXXXX; + int count, fd; + static const char letters[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; + static const int NLETTERS = sizeof (letters) - 1; + glong value; + GTimeVal tv; + static int counter = 0; + + g_return_val_if_fail (tmpl != NULL, -1); + + /* find the last occurrence of "XXXXXX" */ + XXXXXX = g_strrstr (tmpl, "XXXXXX"); + + if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6)) + { + errno = EINVAL; + return -1; + } + + /* Get some more or less random data. */ + g_get_current_time (&tv); + value = (tv.tv_usec ^ tv.tv_sec) + counter++; + + for (count = 0; count < 100; value += 7777, ++count) + { + glong v = value; + + /* Fill in the random bits. */ + XXXXXX[0] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[1] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[2] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[3] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[4] = letters[v % NLETTERS]; + v /= NLETTERS; + XXXXXX[5] = letters[v % NLETTERS]; + + fd = f (tmpl, flags, mode); + + if (fd >= 0) + return fd; + else if (errno != EEXIST) + /* Any other error will apply also to other names we might + * try, and there are 2^32 or so of them, so give up now. + */ + return -1; + } + + /* We got out of the loop because we ran out of combinations to try. */ + errno = EEXIST; + return -1; +} + +static gint +wrap_mkdir (gchar *tmpl, + int flags G_GNUC_UNUSED, + int mode) +{ + /* tmpl is in UTF-8 on Windows, thus use g_mkdir() */ + return g_mkdir (tmpl, mode); +} + +/** + * g_mkdtemp_full: + * @tmpl: (type filename): template directory name + * @mode: permissions to create the temporary directory with + * + * Creates a temporary directory. See the mkdtemp() documentation + * on most UNIX-like systems. + * + * The parameter is a string that should follow the rules for + * mkdtemp() templates, i.e. contain the string "XXXXXX". + * g_mkdtemp() is slightly more flexible than mkdtemp() in that the + * sequence does not have to occur at the very end of the template + * and you can pass a @mode. The X string will be modified to form + * the name of a directory that didn't exist. The string should be + * in the GLib file name encoding. Most importantly, on Windows it + * should be in UTF-8. + * + * Return value: A pointer to @tmpl, which has been modified + * to hold the directory name. In case of errors, %NULL is + * returned, and %errno will be set. + * + * Since: 2.30 + */ +gchar * +g_mkdtemp_full (gchar *tmpl, + gint mode) +{ + if (get_tmp_file (tmpl, wrap_mkdir, 0, mode) == -1) + return NULL; + else + return tmpl; +} + +/** + * g_mkdtemp: + * @tmpl: (type filename): template directory name + * + * Creates a temporary directory. See the mkdtemp() documentation + * on most UNIX-like systems. + * + * The parameter is a string that should follow the rules for + * mkdtemp() templates, i.e. contain the string "XXXXXX". + * g_mkdtemp() is slightly more flexible than mkdtemp() in that the + * sequence does not have to occur at the very end of the template + * and you can pass a @mode and additional @flags. The X string will + * be modified to form the name of a directory that didn't exist. + * The string should be in the GLib file name encoding. Most importantly, + * on Windows it should be in UTF-8. + * + * Return value: A pointer to @tmpl, which has been modified + * to hold the directory name. In case of errors, %NULL is + * returned and %errno will be set. + * + * Since: 2.30 + */ +gchar * +g_mkdtemp (gchar *tmpl) +{ + return g_mkdtemp_full (tmpl, 0700); +} + +/** + * g_mkstemp_full: + * @tmpl: (type filename): template filename + * @flags: flags to pass to an open() call in addition to O_EXCL + * and O_CREAT, which are passed automatically + * @mode: permissions to create the temporary file with + * + * Opens a temporary file. See the mkstemp() documentation + * on most UNIX-like systems. + * + * The parameter is a string that should follow the rules for + * mkstemp() templates, i.e. contain the string "XXXXXX". + * g_mkstemp_full() is slightly more flexible than mkstemp() + * in that the sequence does not have to occur at the very end of the + * template and you can pass a @mode and additional @flags. The X + * string will be modified to form the name of a file that didn't exist. + * The string should be in the GLib file name encoding. Most importantly, + * on Windows it should be in UTF-8. + * + * Return value: A file handle (as from open()) to the file + * opened for reading and writing. The file handle should be + * closed with close(). In case of errors, -1 is returned + * and %errno will be set. + * + * Since: 2.22 + */ +gint +g_mkstemp_full (gchar *tmpl, + gint flags, + gint mode) +{ + /* tmpl is in UTF-8 on Windows, thus use g_open() */ + return get_tmp_file (tmpl, (GTmpFileCallback) g_open, + flags | O_CREAT | O_EXCL, mode); +} + +/** + * g_mkstemp: + * @tmpl: (type filename): template filename + * + * Opens a temporary file. See the mkstemp() documentation + * on most UNIX-like systems. + * + * The parameter is a string that should follow the rules for + * mkstemp() templates, i.e. contain the string "XXXXXX". + * g_mkstemp() is slightly more flexible than mkstemp() in that the + * sequence does not have to occur at the very end of the template. + * The X string will be modified to form the name of a file that + * didn't exist. The string should be in the GLib file name encoding. + * Most importantly, on Windows it should be in UTF-8. + * + * Return value: A file handle (as from open()) to the file + * opened for reading and writing. The file is opened in binary + * mode on platforms where there is a difference. The file handle + * should be closed with close(). In case of errors, -1 is + * returned and %errno will be set. + */ +gint +g_mkstemp (gchar *tmpl) +{ + return g_mkstemp_full (tmpl, O_RDWR | O_BINARY, 0600); +} + +static gint +g_get_tmp_name (const gchar *tmpl, + gchar **name_used, + GTmpFileCallback f, + gint flags, + gint mode, + GError **error) +{ + int retval; + const char *tmpdir; + const char *sep; + char *fulltemplate; + const char *slash; + + if (tmpl == NULL) + tmpl = ".XXXXXX"; + + if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL +#ifdef G_OS_WIN32 + || (strchr (tmpl, '/') != NULL && (slash = "/")) +#endif + ) + { + gchar *display_tmpl = g_filename_display_name (tmpl); + char c[2]; + c[0] = *slash; + c[1] = '\0'; + + g_set_error (error, + G_FILE_ERROR, + G_FILE_ERROR_FAILED, + _("Template '%s' invalid, should not contain a '%s'"), + display_tmpl, c); + g_free (display_tmpl); + + return -1; + } + + if (strstr (tmpl, "XXXXXX") == NULL) + { + gchar *display_tmpl = g_filename_display_name (tmpl); + g_set_error (error, + G_FILE_ERROR, + G_FILE_ERROR_FAILED, + _("Template '%s' doesn't contain XXXXXX"), + display_tmpl); + g_free (display_tmpl); + return -1; + } + + tmpdir = g_get_tmp_dir (); + + if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1])) + sep = ""; + else + sep = G_DIR_SEPARATOR_S; + + fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL); + + retval = get_tmp_file (fulltemplate, f, flags, mode); + if (retval == -1) + { + int save_errno = errno; + gchar *display_fulltemplate = g_filename_display_name (fulltemplate); + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to create file '%s': %s"), + display_fulltemplate, g_strerror (save_errno)); + g_free (display_fulltemplate); + g_free (fulltemplate); + return -1; + } + + *name_used = fulltemplate; + + return retval; +} + +/** + * g_file_open_tmp: + * @tmpl: (type filename) (allow-none): Template for file name, as in + * g_mkstemp(), basename only, or %NULL for a default template + * @name_used: (out) (type filename): location to store actual name used, + * or %NULL + * @error: return location for a #GError + * + * Opens a file for writing in the preferred directory for temporary + * files (as returned by g_get_tmp_dir()). + * + * @tmpl should be a string in the GLib file name encoding containing + * a sequence of six 'X' characters, as the parameter to g_mkstemp(). + * However, unlike these functions, the template should only be a + * basename, no directory components are allowed. If template is + * %NULL, a default template is used. + * + * Note that in contrast to g_mkstemp() (and mkstemp()) @tmpl is not + * modified, and might thus be a read-only literal string. + * + * Upon success, and if @name_used is non-%NULL, the actual name used + * is returned in @name_used. This string should be freed with g_free() + * when not needed any longer. The returned name is in the GLib file + * name encoding. + * + * Return value: A file handle (as from open()) to the file opened for + * reading and writing. The file is opened in binary mode on platforms + * where there is a difference. The file handle should be closed with + * close(). In case of errors, -1 is returned and @error will be set. + */ +gint +g_file_open_tmp (const gchar *tmpl, + gchar **name_used, + GError **error) +{ + gchar *fulltemplate; + gint result; + + result = g_get_tmp_name (tmpl, &fulltemplate, + (GTmpFileCallback) g_open, + O_CREAT | O_EXCL | O_RDWR | O_BINARY, + 0600, + error); + if (result != -1) + { + if (name_used) + *name_used = fulltemplate; + else + g_free (fulltemplate); + } + + return result; +} + +/** + * g_dir_make_tmp: + * @tmpl: (type filename) (allow-none): Template for directory name, + * as in g_mkdtemp(), basename only, or %NULL for a default template + * @error: return location for a #GError + * + * Creates a subdirectory in the preferred directory for temporary + * files (as returned by g_get_tmp_dir()). + * + * @tmpl should be a string in the GLib file name encoding containing + * a sequence of six 'X' characters, as the parameter to g_mkstemp(). + * However, unlike these functions, the template should only be a + * basename, no directory components are allowed. If template is + * %NULL, a default template is used. + * + * Note that in contrast to g_mkdtemp() (and mkdtemp()) @tmpl is not + * modified, and might thus be a read-only literal string. + * + * Return value: (type filename): The actual name used. This string + * should be freed with g_free() when not needed any longer and is + * is in the GLib file name encoding. In case of errors, %NULL is + * returned and @error will be set. + * + * Since: 2.30 + */ +gchar * +g_dir_make_tmp (const gchar *tmpl, + GError **error) +{ + gchar *fulltemplate; + + if (g_get_tmp_name (tmpl, &fulltemplate, wrap_mkdir, 0, 0700, error) == -1) + return NULL; + else + return fulltemplate; +} + +static gchar * +g_build_path_va (const gchar *separator, + const gchar *first_element, + va_list *args, + gchar **str_array) +{ + GString *result; + gint separator_len = strlen (separator); + gboolean is_first = TRUE; + gboolean have_leading = FALSE; + const gchar *single_element = NULL; + const gchar *next_element; + const gchar *last_trailing = NULL; + gint i = 0; + + result = g_string_new (NULL); + + if (str_array) + next_element = str_array[i++]; + else + next_element = first_element; + + while (TRUE) + { + const gchar *element; + const gchar *start; + const gchar *end; + + if (next_element) + { + element = next_element; + if (str_array) + next_element = str_array[i++]; + else + next_element = va_arg (*args, gchar *); + } + else + break; + + /* Ignore empty elements */ + if (!*element) + continue; + + start = element; + + if (separator_len) + { + while (strncmp (start, separator, separator_len) == 0) + start += separator_len; + } + + end = start + strlen (start); + + if (separator_len) + { + while (end >= start + separator_len && + strncmp (end - separator_len, separator, separator_len) == 0) + end -= separator_len; + + last_trailing = end; + while (last_trailing >= element + separator_len && + strncmp (last_trailing - separator_len, separator, separator_len) == 0) + last_trailing -= separator_len; + + if (!have_leading) + { + /* If the leading and trailing separator strings are in the + * same element and overlap, the result is exactly that element + */ + if (last_trailing <= start) + single_element = element; + + g_string_append_len (result, element, start - element); + have_leading = TRUE; + } + else + single_element = NULL; + } + + if (end == start) + continue; + + if (!is_first) + g_string_append (result, separator); + + g_string_append_len (result, start, end - start); + is_first = FALSE; + } + + if (single_element) + { + g_string_free (result, TRUE); + return g_strdup (single_element); + } + else + { + if (last_trailing) + g_string_append (result, last_trailing); + + return g_string_free (result, FALSE); + } +} + +/** + * g_build_pathv: + * @separator: a string used to separator the elements of the path. + * @args: (array zero-terminated=1): %NULL-terminated array of strings containing the path elements. + * + * Behaves exactly like g_build_path(), but takes the path elements + * as a string array, instead of varargs. This function is mainly + * meant for language bindings. + * + * Return value: a newly-allocated string that must be freed with g_free(). + * + * Since: 2.8 + */ +gchar * +g_build_pathv (const gchar *separator, + gchar **args) +{ + if (!args) + return NULL; + + return g_build_path_va (separator, NULL, NULL, args); +} + + +/** + * g_build_path: + * @separator: a string used to separator the elements of the path. + * @first_element: the first element in the path + * @...: remaining elements in path, terminated by %NULL + * + * Creates a path from a series of elements using @separator as the + * separator between elements. At the boundary between two elements, + * any trailing occurrences of separator in the first element, or + * leading occurrences of separator in the second element are removed + * and exactly one copy of the separator is inserted. + * + * Empty elements are ignored. + * + * The number of leading copies of the separator on the result is + * the same as the number of leading copies of the separator on + * the first non-empty element. + * + * The number of trailing copies of the separator on the result is + * the same as the number of trailing copies of the separator on + * the last non-empty element. (Determination of the number of + * trailing copies is done without stripping leading copies, so + * if the separator is ABA, ABABA + * has 1 trailing copy.) + * + * However, if there is only a single non-empty element, and there + * are no characters in that element not part of the leading or + * trailing separators, then the result is exactly the original value + * of that element. + * + * Other than for determination of the number of leading and trailing + * copies of the separator, elements consisting only of copies + * of the separator are ignored. + * + * Return value: a newly-allocated string that must be freed with g_free(). + **/ +gchar * +g_build_path (const gchar *separator, + const gchar *first_element, + ...) +{ + gchar *str; + va_list args; + + g_return_val_if_fail (separator != NULL, NULL); + + va_start (args, first_element); + str = g_build_path_va (separator, first_element, &args, NULL); + va_end (args); + + return str; +} + +#ifdef G_OS_WIN32 + +static gchar * +g_build_pathname_va (const gchar *first_element, + va_list *args, + gchar **str_array) +{ + /* Code copied from g_build_pathv(), and modified to use two + * alternative single-character separators. + */ + GString *result; + gboolean is_first = TRUE; + gboolean have_leading = FALSE; + const gchar *single_element = NULL; + const gchar *next_element; + const gchar *last_trailing = NULL; + gchar current_separator = '\\'; + gint i = 0; + + result = g_string_new (NULL); + + if (str_array) + next_element = str_array[i++]; + else + next_element = first_element; + + while (TRUE) + { + const gchar *element; + const gchar *start; + const gchar *end; + + if (next_element) + { + element = next_element; + if (str_array) + next_element = str_array[i++]; + else + next_element = va_arg (*args, gchar *); + } + else + break; + + /* Ignore empty elements */ + if (!*element) + continue; + + start = element; + + if (TRUE) + { + while (start && + (*start == '\\' || *start == '/')) + { + current_separator = *start; + start++; + } + } + + end = start + strlen (start); + + if (TRUE) + { + while (end >= start + 1 && + (end[-1] == '\\' || end[-1] == '/')) + { + current_separator = end[-1]; + end--; + } + + last_trailing = end; + while (last_trailing >= element + 1 && + (last_trailing[-1] == '\\' || last_trailing[-1] == '/')) + last_trailing--; + + if (!have_leading) + { + /* If the leading and trailing separator strings are in the + * same element and overlap, the result is exactly that element + */ + if (last_trailing <= start) + single_element = element; + + g_string_append_len (result, element, start - element); + have_leading = TRUE; + } + else + single_element = NULL; + } + + if (end == start) + continue; + + if (!is_first) + g_string_append_len (result, ¤t_separator, 1); + + g_string_append_len (result, start, end - start); + is_first = FALSE; + } + + if (single_element) + { + g_string_free (result, TRUE); + return g_strdup (single_element); + } + else + { + if (last_trailing) + g_string_append (result, last_trailing); + + return g_string_free (result, FALSE); + } +} + +#endif + +/** + * g_build_filenamev: + * @args: (array zero-terminated=1): %NULL-terminated array of strings containing the path elements. + * + * Behaves exactly like g_build_filename(), but takes the path elements + * as a string array, instead of varargs. This function is mainly + * meant for language bindings. + * + * Return value: a newly-allocated string that must be freed with g_free(). + * + * Since: 2.8 + */ +gchar * +g_build_filenamev (gchar **args) +{ + gchar *str; + +#ifndef G_OS_WIN32 + str = g_build_path_va (G_DIR_SEPARATOR_S, NULL, NULL, args); +#else + str = g_build_pathname_va (NULL, NULL, args); +#endif + + return str; +} + +/** + * g_build_filename: + * @first_element: the first element in the path + * @...: remaining elements in path, terminated by %NULL + * + * Creates a filename from a series of elements using the correct + * separator for filenames. + * + * On Unix, this function behaves identically to g_build_path + * (G_DIR_SEPARATOR_S, first_element, ....). + * + * On Windows, it takes into account that either the backslash + * (\ or slash (/) can be used + * as separator in filenames, but otherwise behaves as on Unix. When + * file pathname separators need to be inserted, the one that last + * previously occurred in the parameters (reading from left to right) + * is used. + * + * No attempt is made to force the resulting filename to be an absolute + * path. If the first element is a relative path, the result will + * be a relative path. + * + * Return value: a newly-allocated string that must be freed with g_free(). + **/ +gchar * +g_build_filename (const gchar *first_element, + ...) +{ + gchar *str; + va_list args; + + va_start (args, first_element); +#ifndef G_OS_WIN32 + str = g_build_path_va (G_DIR_SEPARATOR_S, first_element, &args, NULL); +#else + str = g_build_pathname_va (first_element, &args, NULL); +#endif + va_end (args); + + return str; +} + +/** + * g_file_read_link: + * @filename: the symbolic link + * @error: return location for a #GError + * + * Reads the contents of the symbolic link @filename like the POSIX + * readlink() function. The returned string is in the encoding used + * for filenames. Use g_filename_to_utf8() to convert it to UTF-8. + * + * Returns: A newly-allocated string with the contents of the symbolic link, + * or %NULL if an error occurred. + * + * Since: 2.4 + */ +gchar * +g_file_read_link (const gchar *filename, + GError **error) +{ +#ifdef HAVE_READLINK + gchar *buffer; + guint size; + gint read_size; + + size = 256; + buffer = g_malloc (size); + + while (TRUE) + { + read_size = readlink (filename, buffer, size); + if (read_size < 0) { + int save_errno = errno; + gchar *display_filename = g_filename_display_name (filename); + + g_free (buffer); + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to read the symbolic link '%s': %s"), + display_filename, + g_strerror (save_errno)); + g_free (display_filename); + + return NULL; + } + + if (read_size < size) + { + buffer[read_size] = 0; + return buffer; + } + + size *= 2; + buffer = g_realloc (buffer, size); + } +#else + g_set_error_literal (error, + G_FILE_ERROR, + G_FILE_ERROR_INVAL, + _("Symbolic links not supported")); + + return NULL; +#endif +} + +/** + * g_path_is_absolute: + * @file_name: a file name + * + * Returns %TRUE if the given @file_name is an absolute file name. + * Note that this is a somewhat vague concept on Windows. + * + * On POSIX systems, an absolute file name is well-defined. It always + * starts from the single root directory. For example "/usr/local". + * + * On Windows, the concepts of current drive and drive-specific + * current directory introduce vagueness. This function interprets as + * an absolute file name one that either begins with a directory + * separator such as "\Users\tml" or begins with the root on a drive, + * for example "C:\Windows". The first case also includes UNC paths + * such as "\\myserver\docs\foo". In all cases, either slashes or + * backslashes are accepted. + * + * Note that a file name relative to the current drive root does not + * truly specify a file uniquely over time and across processes, as + * the current drive is a per-process value and can be changed. + * + * File names relative the current directory on some specific drive, + * such as "D:foo/bar", are not interpreted as absolute by this + * function, but they obviously are not relative to the normal current + * directory as returned by getcwd() or g_get_current_dir() + * either. Such paths should be avoided, or need to be handled using + * Windows-specific code. + * + * Returns: %TRUE if @file_name is absolute + */ +gboolean +g_path_is_absolute (const gchar *file_name) +{ + g_return_val_if_fail (file_name != NULL, FALSE); + + if (G_IS_DIR_SEPARATOR (file_name[0])) + return TRUE; + +#ifdef G_OS_WIN32 + /* Recognize drive letter on native Windows */ + if (g_ascii_isalpha (file_name[0]) && + file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2])) + return TRUE; +#endif + + return FALSE; +} + +/** + * g_path_skip_root: + * @file_name: a file name + * + * Returns a pointer into @file_name after the root component, + * i.e. after the "/" in UNIX or "C:\" under Windows. If @file_name + * is not an absolute path it returns %NULL. + * + * Returns: a pointer into @file_name after the root component + */ +const gchar * +g_path_skip_root (const gchar *file_name) +{ + g_return_val_if_fail (file_name != NULL, NULL); + +#ifdef G_PLATFORM_WIN32 + /* Skip \\server\share or //server/share */ + if (G_IS_DIR_SEPARATOR (file_name[0]) && + G_IS_DIR_SEPARATOR (file_name[1]) && + file_name[2] && + !G_IS_DIR_SEPARATOR (file_name[2])) + { + gchar *p; + p = strchr (file_name + 2, G_DIR_SEPARATOR); + +#ifdef G_OS_WIN32 + { + gchar *q; + + q = strchr (file_name + 2, '/'); + if (p == NULL || (q != NULL && q < p)) + p = q; + } +#endif + + if (p && p > file_name + 2 && p[1]) + { + file_name = p + 1; + + while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0])) + file_name++; + + /* Possibly skip a backslash after the share name */ + if (G_IS_DIR_SEPARATOR (file_name[0])) + file_name++; + + return (gchar *)file_name; + } + } +#endif + + /* Skip initial slashes */ + if (G_IS_DIR_SEPARATOR (file_name[0])) + { + while (G_IS_DIR_SEPARATOR (file_name[0])) + file_name++; + return (gchar *)file_name; + } + +#ifdef G_OS_WIN32 + /* Skip X:\ */ + if (g_ascii_isalpha (file_name[0]) && + file_name[1] == ':' && + G_IS_DIR_SEPARATOR (file_name[2])) + return (gchar *)file_name + 3; +#endif + + return NULL; +} + +/** + * g_basename: + * @file_name: the name of the file + * + * Gets the name of the file without any leading directory + * components. It returns a pointer into the given file name + * string. + * + * Return value: the name of the file without any leading + * directory components + * + * Deprecated:2.2: Use g_path_get_basename() instead, but notice + * that g_path_get_basename() allocates new memory for the + * returned string, unlike this function which returns a pointer + * into the argument. + */ +const gchar * +g_basename (const gchar *file_name) +{ + gchar *base; + + g_return_val_if_fail (file_name != NULL, NULL); + + base = strrchr (file_name, G_DIR_SEPARATOR); + +#ifdef G_OS_WIN32 + { + gchar *q; + q = strrchr (file_name, '/'); + if (base == NULL || (q != NULL && q > base)) + base = q; + } +#endif + + if (base) + return base + 1; + +#ifdef G_OS_WIN32 + if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':') + return (gchar*) file_name + 2; +#endif + + return (gchar*) file_name; +} + +/** + * g_path_get_basename: + * @file_name: the name of the file + * + * Gets the last component of the filename. + * + * If @file_name ends with a directory separator it gets the component + * before the last slash. If @file_name consists only of directory + * separators (and on Windows, possibly a drive letter), a single + * separator is returned. If @file_name is empty, it gets ".". + * + * Return value: a newly allocated string containing the last + * component of the filename + */ +gchar * +g_path_get_basename (const gchar *file_name) +{ + gssize base; + gssize last_nonslash; + gsize len; + gchar *retval; + + g_return_val_if_fail (file_name != NULL, NULL); + + if (file_name[0] == '\0') + return g_strdup ("."); + + last_nonslash = strlen (file_name) - 1; + + while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash])) + last_nonslash--; + + if (last_nonslash == -1) + /* string only containing slashes */ + return g_strdup (G_DIR_SEPARATOR_S); + +#ifdef G_OS_WIN32 + if (last_nonslash == 1 && + g_ascii_isalpha (file_name[0]) && + file_name[1] == ':') + /* string only containing slashes and a drive */ + return g_strdup (G_DIR_SEPARATOR_S); +#endif + base = last_nonslash; + + while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base])) + base--; + +#ifdef G_OS_WIN32 + if (base == -1 && + g_ascii_isalpha (file_name[0]) && + file_name[1] == ':') + base = 1; +#endif /* G_OS_WIN32 */ + + len = last_nonslash - base; + retval = g_malloc (len + 1); + memcpy (retval, file_name + base + 1, len); + retval [len] = '\0'; + + return retval; +} + +/** + * g_dirname: + * @file_name: the name of the file + * + * Gets the directory components of a file name. + * + * If the file name has no directory components "." is returned. + * The returned string should be freed when no longer needed. + * + * Returns: the directory components of the file + * + * Deprecated: use g_path_get_dirname() instead + */ + +/** + * g_path_get_dirname: + * @file_name: the name of the file + * + * Gets the directory components of a file name. + * + * If the file name has no directory components "." is returned. + * The returned string should be freed when no longer needed. + * + * Returns: the directory components of the file + */ +gchar * +g_path_get_dirname (const gchar *file_name) +{ + gchar *base; + gsize len; + + g_return_val_if_fail (file_name != NULL, NULL); + + base = strrchr (file_name, G_DIR_SEPARATOR); + +#ifdef G_OS_WIN32 + { + gchar *q; + q = strrchr (file_name, '/'); + if (base == NULL || (q != NULL && q > base)) + base = q; + } +#endif + + if (!base) + { +#ifdef G_OS_WIN32 + if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':') + { + gchar drive_colon_dot[4]; + + drive_colon_dot[0] = file_name[0]; + drive_colon_dot[1] = ':'; + drive_colon_dot[2] = '.'; + drive_colon_dot[3] = '\0'; + + return g_strdup (drive_colon_dot); + } +#endif + return g_strdup ("."); + } + + while (base > file_name && G_IS_DIR_SEPARATOR (*base)) + base--; + +#ifdef G_OS_WIN32 + /* base points to the char before the last slash. + * + * In case file_name is the root of a drive (X:\) or a child of the + * root of a drive (X:\foo), include the slash. + * + * In case file_name is the root share of an UNC path + * (\\server\share), add a slash, returning \\server\share\ . + * + * In case file_name is a direct child of a share in an UNC path + * (\\server\share\foo), include the slash after the share name, + * returning \\server\share\ . + */ + if (base == file_name + 1 && + g_ascii_isalpha (file_name[0]) && + file_name[1] == ':') + base++; + else if (G_IS_DIR_SEPARATOR (file_name[0]) && + G_IS_DIR_SEPARATOR (file_name[1]) && + file_name[2] && + !G_IS_DIR_SEPARATOR (file_name[2]) && + base >= file_name + 2) + { + const gchar *p = file_name + 2; + while (*p && !G_IS_DIR_SEPARATOR (*p)) + p++; + if (p == base + 1) + { + len = (guint) strlen (file_name) + 1; + base = g_new (gchar, len + 1); + strcpy (base, file_name); + base[len-1] = G_DIR_SEPARATOR; + base[len] = 0; + return base; + } + if (G_IS_DIR_SEPARATOR (*p)) + { + p++; + while (*p && !G_IS_DIR_SEPARATOR (*p)) + p++; + if (p == base + 1) + base++; + } + } +#endif + + len = (guint) 1 + base - file_name; + base = g_new (gchar, len + 1); + g_memmove (base, file_name, len); + base[len] = 0; + + return base; +} + +#if defined(MAXPATHLEN) +#define G_PATH_LENGTH MAXPATHLEN +#elif defined(PATH_MAX) +#define G_PATH_LENGTH PATH_MAX +#elif defined(_PC_PATH_MAX) +#define G_PATH_LENGTH sysconf(_PC_PATH_MAX) +#else +#define G_PATH_LENGTH 2048 +#endif + +/** + * g_get_current_dir: + * + * Gets the current directory. + * + * The returned string should be freed when no longer needed. + * The encoding of the returned string is system defined. + * On Windows, it is always UTF-8. + * + * Returns: the current directory + */ +gchar * +g_get_current_dir (void) +{ +#ifdef G_OS_WIN32 + + gchar *dir = NULL; + wchar_t dummy[2], *wdir; + int len; + + len = GetCurrentDirectoryW (2, dummy); + wdir = g_new (wchar_t, len); + + if (GetCurrentDirectoryW (len, wdir) == len - 1) + dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL); + + g_free (wdir); + + if (dir == NULL) + dir = g_strdup ("\\"); + + return dir; + +#else + + gchar *buffer = NULL; + gchar *dir = NULL; + static gulong max_len = 0; + + if (max_len == 0) + max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH; + + /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd") + * and, if that wasn't bad enough, hangs in doing so. + */ +#if (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD) + buffer = g_new (gchar, max_len + 1); + *buffer = 0; + dir = getwd (buffer); +#else + while (max_len < G_MAXULONG / 2) + { + g_free (buffer); + buffer = g_new (gchar, max_len + 1); + *buffer = 0; + dir = getcwd (buffer, max_len); + + if (dir || errno != ERANGE) + break; + + max_len *= 2; + } +#endif /* !sun || !HAVE_GETCWD */ + + if (!dir || !*buffer) + { + /* hm, should we g_error() out here? + * this can happen if e.g. "./" has mode \0000 + */ + buffer[0] = G_DIR_SEPARATOR; + buffer[1] = 0; + } + + dir = g_strdup (buffer); + g_free (buffer); + + return dir; + +#endif /* !G_OS_WIN32 */ +} + + +/* NOTE : Keep this part last to ensure nothing in this file uses thn + * below binary compatibility versions. + */ +#if defined (G_OS_WIN32) && !defined (_WIN64) + +/* Binary compatibility versions. Will be called by code compiled + * against quite old (pre-2.8, I think) headers only, not from more + * recently compiled code. + */ + +#undef g_file_test + +gboolean +g_file_test (const gchar *filename, + GFileTest test) +{ + gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL); + gboolean retval; + + if (utf8_filename == NULL) + return FALSE; + + retval = g_file_test_utf8 (utf8_filename, test); + + g_free (utf8_filename); + + return retval; +} + +#undef g_file_get_contents + +gboolean +g_file_get_contents (const gchar *filename, + gchar **contents, + gsize *length, + GError **error) +{ + gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error); + gboolean retval; + + if (utf8_filename == NULL) + return FALSE; + + retval = g_file_get_contents_utf8 (utf8_filename, contents, length, error); + + g_free (utf8_filename); + + return retval; +} + +#undef g_mkstemp + +gint +g_mkstemp (gchar *tmpl) +{ + /* This is the backward compatibility system codepage version, + * thus use normal open(). + */ + return get_tmp_file (tmpl, (GTmpFileCallback) open, + O_RDWR | O_CREAT | O_EXCL, 0600); +} + +#undef g_file_open_tmp + +gint +g_file_open_tmp (const gchar *tmpl, + gchar **name_used, + GError **error) +{ + gchar *utf8_tmpl = g_locale_to_utf8 (tmpl, -1, NULL, NULL, error); + gchar *utf8_name_used; + gint retval; + + if (utf8_tmpl == NULL) + return -1; + + retval = g_file_open_tmp_utf8 (utf8_tmpl, &utf8_name_used, error); + + if (retval == -1) + return -1; + + if (name_used) + *name_used = g_locale_from_utf8 (utf8_name_used, -1, NULL, NULL, NULL); + + g_free (utf8_name_used); + + return retval; +} + +#undef g_get_current_dir + +gchar * +g_get_current_dir (void) +{ + gchar *utf8_dir = g_get_current_dir_utf8 (); + gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL); + g_free (utf8_dir); + return dir; +} + +#endif + diff --git a/glib/glib/gfileutils.h b/glib/glib/gfileutils.h new file mode 100644 index 0000000..f591461 --- /dev/null +++ b/glib/glib/gfileutils.h @@ -0,0 +1,176 @@ +/* gfileutils.h - File utility functions + * + * Copyright 2000 Red Hat, Inc. + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_FILEUTILS_H__ +#define __G_FILEUTILS_H__ + +#include + +G_BEGIN_DECLS + +#define G_FILE_ERROR g_file_error_quark () + +typedef enum +{ + G_FILE_ERROR_EXIST, + G_FILE_ERROR_ISDIR, + G_FILE_ERROR_ACCES, + G_FILE_ERROR_NAMETOOLONG, + G_FILE_ERROR_NOENT, + G_FILE_ERROR_NOTDIR, + G_FILE_ERROR_NXIO, + G_FILE_ERROR_NODEV, + G_FILE_ERROR_ROFS, + G_FILE_ERROR_TXTBSY, + G_FILE_ERROR_FAULT, + G_FILE_ERROR_LOOP, + G_FILE_ERROR_NOSPC, + G_FILE_ERROR_NOMEM, + G_FILE_ERROR_MFILE, + G_FILE_ERROR_NFILE, + G_FILE_ERROR_BADF, + G_FILE_ERROR_INVAL, + G_FILE_ERROR_PIPE, + G_FILE_ERROR_AGAIN, + G_FILE_ERROR_INTR, + G_FILE_ERROR_IO, + G_FILE_ERROR_PERM, + G_FILE_ERROR_NOSYS, + G_FILE_ERROR_FAILED +} GFileError; + +/* For backward-compat reasons, these are synced to an old + * anonymous enum in libgnome. But don't use that enum + * in new code. + */ +typedef enum +{ + G_FILE_TEST_IS_REGULAR = 1 << 0, + G_FILE_TEST_IS_SYMLINK = 1 << 1, + G_FILE_TEST_IS_DIR = 1 << 2, + G_FILE_TEST_IS_EXECUTABLE = 1 << 3, + G_FILE_TEST_EXISTS = 1 << 4 +} GFileTest; + +GQuark g_file_error_quark (void); +/* So other code can generate a GFileError */ +GFileError g_file_error_from_errno (gint err_no); + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +#define g_file_test g_file_test_utf8 +#define g_file_get_contents g_file_get_contents_utf8 +#define g_mkstemp g_mkstemp_utf8 +#define g_file_open_tmp g_file_open_tmp_utf8 +#endif +#endif + +gboolean g_file_test (const gchar *filename, + GFileTest test); +gboolean g_file_get_contents (const gchar *filename, + gchar **contents, + gsize *length, + GError **error); +gboolean g_file_set_contents (const gchar *filename, + const gchar *contents, + gssize length, + GError **error); +gchar *g_file_read_link (const gchar *filename, + GError **error); + +/* Wrapper / workalike for mkdtemp() */ +gchar *g_mkdtemp (gchar *tmpl); +gchar *g_mkdtemp_full (gchar *tmpl, + gint mode); + +/* Wrapper / workalike for mkstemp() */ +gint g_mkstemp (gchar *tmpl); +gint g_mkstemp_full (gchar *tmpl, + gint flags, + gint mode); + +/* Wrappers for g_mkstemp and g_mkdtemp() */ +gint g_file_open_tmp (const gchar *tmpl, + gchar **name_used, + GError **error); +gchar *g_dir_make_tmp (const gchar *tmpl, + GError **error); + +gchar *g_build_path (const gchar *separator, + const gchar *first_element, + ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; +gchar *g_build_pathv (const gchar *separator, + gchar **args) G_GNUC_MALLOC; + +gchar *g_build_filename (const gchar *first_element, + ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; +gchar *g_build_filenamev (gchar **args) G_GNUC_MALLOC; + +gint g_mkdir_with_parents (const gchar *pathname, + gint mode); + +#ifdef G_OS_WIN32 + +/* On Win32, the canonical directory separator is the backslash, and + * the search path separator is the semicolon. Note that also the + * (forward) slash works as directory separator. + */ +#define G_DIR_SEPARATOR '\\' +#define G_DIR_SEPARATOR_S "\\" +#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR || (c) == '/') +#define G_SEARCHPATH_SEPARATOR ';' +#define G_SEARCHPATH_SEPARATOR_S ";" + +#else /* !G_OS_WIN32 */ + +#define G_DIR_SEPARATOR '/' +#define G_DIR_SEPARATOR_S "/" +#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR) +#define G_SEARCHPATH_SEPARATOR ':' +#define G_SEARCHPATH_SEPARATOR_S ":" + +#endif /* !G_OS_WIN32 */ + +gboolean g_path_is_absolute (const gchar *file_name); +const gchar *g_path_skip_root (const gchar *file_name); + +GLIB_DEPRECATED_FOR(g_path_get_basename) +const gchar *g_basename (const gchar *file_name); +#ifndef G_DISABLE_DEPRECATED +#define g_dirname g_path_get_dirname +#endif + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +#define g_get_current_dir g_get_current_dir_utf8 +#endif +#endif + +gchar *g_get_current_dir (void); +gchar *g_path_get_basename (const gchar *file_name) G_GNUC_MALLOC; +gchar *g_path_get_dirname (const gchar *file_name) G_GNUC_MALLOC; + +G_END_DECLS + +#endif /* __G_FILEUTILS_H__ */ diff --git a/glib/glib/ggettext.c b/glib/glib/ggettext.c new file mode 100644 index 0000000..41b8abc --- /dev/null +++ b/glib/glib/ggettext.c @@ -0,0 +1,614 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "config.h" + +#include "ggettext.h" + +#include "galloca.h" +#include "gthread.h" +#include "gmem.h" +#ifdef G_OS_WIN32 +#include "gwin32.h" +#include "gfileutils.h" +#include "gstrfuncs.h" +#include "glib-init.h" +#endif + +#include +#include +#include + +#ifdef G_OS_WIN32 + +/** + * _glib_get_locale_dir: + * + * Return the path to the share\locale or lib\locale subfolder of the + * GLib installation folder. The path is in the system codepage. We + * have to use system codepage as bindtextdomain() doesn't have a + * UTF-8 interface. + */ +gchar * +_glib_get_locale_dir (void) +{ + gchar *install_dir = NULL, *locale_dir; + gchar *retval = NULL; + + if (glib_dll != NULL) + install_dir = g_win32_get_package_installation_directory_of_module (glib_dll); + + if (install_dir) + { + /* + * Append "/share/locale" or "/lib/locale" depending on whether + * autoconfigury detected GNU gettext or not. + */ + const char *p = GLIB_LOCALE_DIR + strlen (GLIB_LOCALE_DIR); + while (*--p != '/') + ; + while (*--p != '/') + ; + + locale_dir = g_build_filename (install_dir, p, NULL); + + retval = g_win32_locale_filename_from_utf8 (locale_dir); + + g_free (install_dir); + g_free (locale_dir); + } + + if (retval) + return retval; + else + return g_strdup (""); +} + +#undef GLIB_LOCALE_DIR + +#endif /* G_OS_WIN32 */ + + +static void +ensure_gettext_initialized (void) +{ + static gsize initialised; + + if (g_once_init_enter (&initialised)) + { +#ifdef G_OS_WIN32 + gchar *tmp = _glib_get_locale_dir (); + bindtextdomain (GETTEXT_PACKAGE, tmp); + g_free (tmp); +#else + bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR); +#endif +# ifdef HAVE_BIND_TEXTDOMAIN_CODESET + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); +# endif + g_once_init_leave (&initialised, TRUE); + } +} + +/** + * glib_gettext: + * @str: The string to be translated + * + * Returns the translated string from the glib translations. + * This is an internal function and should only be used by + * the internals of glib (such as libgio). + * + * Returns: the transation of @str to the current locale + */ +const gchar * +glib_gettext (const gchar *str) +{ + ensure_gettext_initialized (); + + return g_dgettext (GETTEXT_PACKAGE, str); +} + +/** + * glib_pgettext: + * @msgctxtid: a combined message context and message id, separated + * by a \004 character + * @msgidoffset: the offset of the message id in @msgctxid + * + * This function is a variant of glib_gettext() which supports + * a disambiguating message context. See g_dpgettext() for full + * details. + * + * This is an internal function and should only be used by + * the internals of glib (such as libgio). + * + * Returns: the translation of @str to the current locale + */ +const gchar * +glib_pgettext (const gchar *msgctxtid, + gsize msgidoffset) +{ + ensure_gettext_initialized (); + + return g_dpgettext (GETTEXT_PACKAGE, msgctxtid, msgidoffset); +} + +/** + * g_strip_context: + * @msgid: a string + * @msgval: another string + * + * An auxiliary function for gettext() support (see Q_()). + * + * Return value: @msgval, unless @msgval is identical to @msgid + * and contains a '|' character, in which case a pointer to + * the substring of msgid after the first '|' character is returned. + * + * Since: 2.4 + */ +const gchar * +g_strip_context (const gchar *msgid, + const gchar *msgval) +{ + if (msgval == msgid) + { + const char *c = strchr (msgid, '|'); + if (c != NULL) + return c + 1; + } + + return msgval; +} + +/** + * g_dpgettext: + * @domain: the translation domain to use, or %NULL to use + * the domain set with textdomain() + * @msgctxtid: a combined message context and message id, separated + * by a \004 character + * @msgidoffset: the offset of the message id in @msgctxid + * + * This function is a variant of g_dgettext() which supports + * a disambiguating message context. GNU gettext uses the + * '\004' character to separate the message context and + * message id in @msgctxtid. + * If 0 is passed as @msgidoffset, this function will fall back to + * trying to use the deprecated convention of using "|" as a separation + * character. + * + * This uses g_dgettext() internally. See that functions for differences + * with dgettext() proper. + * + * Applications should normally not use this function directly, + * but use the C_() macro for translations with context. + * + * Returns: The translated string + * + * Since: 2.16 + */ +const gchar * +g_dpgettext (const gchar *domain, + const gchar *msgctxtid, + gsize msgidoffset) +{ + const gchar *translation; + gchar *sep; + + translation = g_dgettext (domain, msgctxtid); + + if (translation == msgctxtid) + { + if (msgidoffset > 0) + return msgctxtid + msgidoffset; + sep = strchr (msgctxtid, '|'); + + if (sep) + { + /* try with '\004' instead of '|', in case + * xgettext -kQ_:1g was used + */ + gchar *tmp = g_alloca (strlen (msgctxtid) + 1); + strcpy (tmp, msgctxtid); + tmp[sep - msgctxtid] = '\004'; + + translation = g_dgettext (domain, tmp); + + if (translation == tmp) + return sep + 1; + } + } + + return translation; +} + +/* This function is taken from gettext.h + * GNU gettext uses '\004' to separate context and msgid in .mo files. + */ +/** + * g_dpgettext2: + * @domain: the translation domain to use, or %NULL to use + * the domain set with textdomain() + * @context: the message context + * @msgid: the message + * + * This function is a variant of g_dgettext() which supports + * a disambiguating message context. GNU gettext uses the + * '\004' character to separate the message context and + * message id in @msgctxtid. + * + * This uses g_dgettext() internally. See that functions for differences + * with dgettext() proper. + * + * This function differs from C_() in that it is not a macro and + * thus you may use non-string-literals as context and msgid arguments. + * + * Returns: The translated string + * + * Since: 2.18 + */ +const gchar * +g_dpgettext2 (const gchar *domain, + const gchar *msgctxt, + const gchar *msgid) +{ + size_t msgctxt_len = strlen (msgctxt) + 1; + size_t msgid_len = strlen (msgid) + 1; + const char *translation; + char* msg_ctxt_id; + + msg_ctxt_id = g_alloca (msgctxt_len + msgid_len); + + memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1); + msg_ctxt_id[msgctxt_len - 1] = '\004'; + memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len); + + translation = g_dgettext (domain, msg_ctxt_id); + + if (translation == msg_ctxt_id) + { + /* try the old way of doing message contexts, too */ + msg_ctxt_id[msgctxt_len - 1] = '|'; + translation = g_dgettext (domain, msg_ctxt_id); + + if (translation == msg_ctxt_id) + return msgid; + } + + return translation; +} + +static gboolean +_g_dgettext_should_translate (void) +{ + static gsize translate = 0; + enum { + SHOULD_TRANSLATE = 1, + SHOULD_NOT_TRANSLATE = 2 + }; + + if (G_UNLIKELY (g_once_init_enter (&translate))) + { + gboolean should_translate = TRUE; + + const char *default_domain = textdomain (NULL); + const char *translator_comment = gettext (""); +#ifndef G_OS_WIN32 + const char *translate_locale = setlocale (LC_MESSAGES, NULL); +#else + const char *translate_locale = g_win32_getlocale (); +#endif + /* We should NOT translate only if all the following hold: + * - user has called textdomain() and set textdomain to non-default + * - default domain has no translations + * - locale does not start with "en_" and is not "C" + * + * Rationale: + * - If text domain is still the default domain, maybe user calls + * it later. Continue with old behavior of translating. + * - If locale starts with "en_", we can continue using the + * translations even if the app doesn't have translations for + * this locale. That is, en_UK and en_CA for example. + * - If locale is "C", maybe user calls setlocale(LC_ALL,"") later. + * Continue with old behavior of translating. + */ + if (0 != strcmp (default_domain, "messages") && + '\0' == *translator_comment && + 0 != strncmp (translate_locale, "en_", 3) && + 0 != strcmp (translate_locale, "C")) + should_translate = FALSE; + + g_once_init_leave (&translate, + should_translate ? + SHOULD_TRANSLATE : + SHOULD_NOT_TRANSLATE); + } + + return translate == SHOULD_TRANSLATE; +} + +/** + * g_dgettext: + * @domain: the translation domain to use, or %NULL to use + * the domain set with textdomain() + * @msgid: message to translate + * + * This function is a wrapper of dgettext() which does not translate + * the message if the default domain as set with textdomain() has no + * translations for the current locale. + * + * The advantage of using this function over dgettext() proper is that + * libraries using this function (like GTK+) will not use translations + * if the application using the library does not have translations for + * the current locale. This results in a consistent English-only + * interface instead of one having partial translations. For this + * feature to work, the call to textdomain() and setlocale() should + * precede any g_dgettext() invocations. For GTK+, it means calling + * textdomain() before gtk_init or its variants. + * + * This function disables translations if and only if upon its first + * call all the following conditions hold: + * + * @domain is not %NULL + * textdomain() has been called to set a default text domain + * there is no translations available for the default text domain + * and the current locale + * current locale is not "C" or any English locales (those + * starting with "en_") + * + * + * Note that this behavior may not be desired for example if an application + * has its untranslated messages in a language other than English. In those + * cases the application should call textdomain() after initializing GTK+. + * + * Applications should normally not use this function directly, + * but use the _() macro for translations. + * + * Returns: The translated string + * + * Since: 2.18 + */ +const gchar * +g_dgettext (const gchar *domain, + const gchar *msgid) +{ + if (domain && G_UNLIKELY (!_g_dgettext_should_translate ())) + return msgid; + + return dgettext (domain, msgid); +} + +/** + * g_dcgettext: + * @domain: (allow-none): the translation domain to use, or %NULL to use + * the domain set with textdomain() + * @msgid: message to translate + * @category: a locale category + * + * This is a variant of g_dgettext() that allows specifying a locale + * category instead of always using LC_MESSAGES. See g_dgettext() for + * more information about how this functions differs from calling + * dcgettext() directly. + * + * Returns: the translated string for the given locale category + * + * Since: 2.26 + */ +const gchar * +g_dcgettext (const gchar *domain, + const gchar *msgid, + gint category) +{ + if (domain && G_UNLIKELY (!_g_dgettext_should_translate ())) + return msgid; + + return dcgettext (domain, msgid, category); +} + +/** + * g_dngettext: + * @domain: the translation domain to use, or %NULL to use + * the domain set with textdomain() + * @msgid: message to translate + * @msgid_plural: plural form of the message + * @n: the quantity for which translation is needed + * + * This function is a wrapper of dngettext() which does not translate + * the message if the default domain as set with textdomain() has no + * translations for the current locale. + * + * See g_dgettext() for details of how this differs from dngettext() + * proper. + * + * Returns: The translated string + * + * Since: 2.18 + */ +const gchar * +g_dngettext (const gchar *domain, + const gchar *msgid, + const gchar *msgid_plural, + gulong n) +{ + if (domain && G_UNLIKELY (!_g_dgettext_should_translate ())) + return n == 1 ? msgid : msgid_plural; + + return dngettext (domain, msgid, msgid_plural, n); +} + + +/** + * SECTION:i18n + * @title: Internationalization + * @short_description: gettext support macros + * @see_also: the gettext manual + * + * GLib doesn't force any particular localization method upon its users. + * But since GLib itself is localized using the gettext() mechanism, it seems + * natural to offer the de-facto standard gettext() support macros in an + * easy-to-use form. + * + * In order to use these macros in an application, you must include + * glib/gi18n.h. For use in a library, must include + * glib/gi18n-lib.h after defining + * the GETTEXT_PACKAGE macro suitably for your library: + * |[ + * #define GETTEXT_PACKAGE "gtk20" + * #include <glib/gi18n-lib.h> + * ]| + * Note that you also have to call setlocale() and textdomain() (as well as + * bindtextdomain() and bind_textdomain_codeset()) early on in your main() + * to make gettext() work. + * + * The gettext manual covers details of how to set up message extraction + * with xgettext. + */ + +/** + * _: + * @String: the string to be translated + * + * Marks a string for translation, gets replaced with the translated string + * at runtime. + * + * Since: 2.4 + */ + +/** + * Q_: + * @String: the string to be translated, with a '|'-separated prefix + * which must not be translated + * + * Like _(), but handles context in message ids. This has the advantage + * that the string can be adorned with a prefix to guarantee uniqueness + * and provide context to the translator. + * + * One use case given in the gettext manual is GUI translation, where one + * could e.g. disambiguate two "Open" menu entries as "File|Open" and + * "Printer|Open". Another use case is the string "Russian" which may + * have to be translated differently depending on whether it's the name + * of a character set or a language. This could be solved by using + * "charset|Russian" and "language|Russian". + * + * See the C_() macro for a different way to mark up translatable strings + * with context. + * + * If you are using the Q_() macro, you need to make sure + * that you pass to xgettext when extracting + * messages. If you are using GNU gettext >= 0.15, you can also use + * to let xgettext split the context + * string off into a msgctxt line in the po file. + * + * Returns: the translated message + * + * Since: 2.4 + */ + +/** + * C_: + * @Context: a message context, must be a string literal + * @String: a message id, must be a string literal + * + * Uses gettext to get the translation for @String. @Context is + * used as a context. This is mainly useful for short strings which + * may need different translations, depending on the context in which + * they are used. + * |[ + * label1 = C_("Navigation", "Back"); + * label2 = C_("Body part", "Back"); + * ]| + * + * If you are using the C_() macro, you need to make sure + * that you pass to xgettext when + * extracting messages. Note that this only works with GNU + * gettext >= 0.15. + * + * Returns: the translated message + * + * Since: 2.16 + */ + +/** + * N_: + * @String: the string to be translated + * + * Only marks a string for translation. This is useful in situations + * where the translated strings can't be directly used, e.g. in string + * array initializers. To get the translated string, call gettext() + * at runtime. + * |[ + * { + * static const char *messages[] = { + * N_("some very meaningful message"), + * N_("and another one") + * }; + * const char *string; + * ... + * string + * = index > 1 ? _("a default message") : gettext (messages[index]); + * + * fputs (string); + * ... + * } + * ]| + * + * Since: 2.4 + */ + +/** + * NC_: + * @Context: a message context, must be a string literal + * @String: a message id, must be a string literal + * + * Only marks a string for translation, with context. + * This is useful in situations where the translated strings can't + * be directly used, e.g. in string array initializers. To get the + * translated string, you should call g_dpgettext2() at runtime. + * + * |[ + * { + * static const char *messages[] = { + * NC_("some context", "some very meaningful message"), + * NC_("some context", "and another one") + * }; + * const char *string; + * ... + * string + * = index > 1 ? g_dpgettext2 (NULL, "some context", "a default message") + * : g_dpgettext2 (NULL, "some context", messages[index]); + * + * fputs (string); + * ... + * } + * ]| + * + * If you are using the NC_() macro, you need to make sure + * that you pass to xgettext when + * extracting messages. Note that this only works with GNU gettext >= 0.15. + * Intltool has support for the NC_() macro since version 0.40.1. + * + * + * Since: 2.18 + */ + diff --git a/glib/glib/ggettext.h b/glib/glib/ggettext.h new file mode 100644 index 0000000..54bbaa8 --- /dev/null +++ b/glib/glib/ggettext.h @@ -0,0 +1,59 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_GETTEXT_H__ +#define __G_GETTEXT_H__ + +#include + +G_BEGIN_DECLS + +const gchar *g_strip_context (const gchar *msgid, + const gchar *msgval) G_GNUC_FORMAT(1); + +const gchar *g_dgettext (const gchar *domain, + const gchar *msgid) G_GNUC_FORMAT(2); +const gchar *g_dcgettext (const gchar *domain, + const gchar *msgid, + gint category) G_GNUC_FORMAT(2); +const gchar *g_dngettext (const gchar *domain, + const gchar *msgid, + const gchar *msgid_plural, + gulong n) G_GNUC_FORMAT(3); +const gchar *g_dpgettext (const gchar *domain, + const gchar *msgctxtid, + gsize msgidoffset) G_GNUC_FORMAT(2); +const gchar *g_dpgettext2 (const gchar *domain, + const gchar *context, + const gchar *msgid) G_GNUC_FORMAT(3); + +G_END_DECLS + +#endif /* __G_GETTEXT_H__ */ diff --git a/glib/glib/ghash.c b/glib/glib/ghash.c new file mode 100644 index 0000000..e204a40 --- /dev/null +++ b/glib/glib/ghash.c @@ -0,0 +1,1903 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include /* memset */ + +#include "ghash.h" + +#include "gstrfuncs.h" +#include "gatomic.h" +#include "gtestutils.h" +#include "gslice.h" + + +/** + * SECTION:hash_tables + * @title: Hash Tables + * @short_description: associations between keys and values so that + * given a key the value can be found quickly + * + * A #GHashTable provides associations between keys and values which is + * optimized so that given a key, the associated value can be found + * very quickly. + * + * Note that neither keys nor values are copied when inserted into the + * #GHashTable, so they must exist for the lifetime of the #GHashTable. + * This means that the use of static strings is OK, but temporary + * strings (i.e. those created in buffers and those returned by GTK+ + * widgets) should be copied with g_strdup() before being inserted. + * + * If keys or values are dynamically allocated, you must be careful to + * ensure that they are freed when they are removed from the + * #GHashTable, and also when they are overwritten by new insertions + * into the #GHashTable. It is also not advisable to mix static strings + * and dynamically-allocated strings in a #GHashTable, because it then + * becomes difficult to determine whether the string should be freed. + * + * To create a #GHashTable, use g_hash_table_new(). + * + * To insert a key and value into a #GHashTable, use + * g_hash_table_insert(). + * + * To lookup a value corresponding to a given key, use + * g_hash_table_lookup() and g_hash_table_lookup_extended(). + * + * g_hash_table_lookup_extended() can also be used to simply + * check if a key is present in the hash table. + * + * To remove a key and value, use g_hash_table_remove(). + * + * To call a function for each key and value pair use + * g_hash_table_foreach() or use a iterator to iterate over the + * key/value pairs in the hash table, see #GHashTableIter. + * + * To destroy a #GHashTable use g_hash_table_destroy(). + * + * + * Using a GHashTable as a set + * + * A common use-case for hash tables is to store information about + * a set of keys, without associating any particular value with each + * key. GHashTable optimizes one way of doing so: If you store only + * key-value pairs where key == value, then GHashTable does not + * allocate memory to store the values, which can be a considerable + * space saving, if your set is large. + * + * + * GHashTable * + * set_new (GHashFunc hash_func, + * GEqualFunc equal_func, + * GDestroyNotify destroy) + * { + * return g_hash_table_new_full (hash_func, equal_func, destroy, NULL); + * } + * + * void + * set_add (GHashTable *set, + * gpointer element) + * { + * g_hash_table_replace (set, element, element); + * } + * + * gboolean + * set_contains (GHashTable *set, + * gpointer element) + * { + * return g_hash_table_lookup_extended (set, element, NULL, NULL); + * } + * + * gboolean + * set_remove (GHashTable *set, + * gpointer element) + * { + * return g_hash_table_remove (set, element); + * } + * + * + * + * As of version 2.32, there is also a g_hash_table_add() function to + * add a key to a #GHashTable that is being used as a set. + */ + +/** + * GHashTable: + * + * The #GHashTable struct is an opaque data structure to represent a + * Hash Table. It should only be + * accessed via the following functions. + */ + +/** + * GHashFunc: + * @key: a key + * + * Specifies the type of the hash function which is passed to + * g_hash_table_new() when a #GHashTable is created. + * + * The function is passed a key and should return a #guint hash value. + * The functions g_direct_hash(), g_int_hash() and g_str_hash() provide + * hash functions which can be used when the key is a #gpointer, #gint*, + * and #gchar* respectively. + * + * g_direct_hash() is also the appropriate hash function for keys + * of the form GINT_TO_POINTER (n) (or similar macros). + * + * A good hash functions should produce + * hash values that are evenly distributed over a fairly large range. + * The modulus is taken with the hash table size (a prime number) to + * find the 'bucket' to place each key into. The function should also + * be very fast, since it is called for each key lookup. + * + * Note that the hash functions provided by GLib have these qualities, + * but are not particularly robust against manufactured keys that + * cause hash collisions. Therefore, you should consider choosing + * a more secure hash function when using a GHashTable with keys + * that originate in untrusted data (such as HTTP requests). + * Using g_str_hash() in that situation might make your application + * vulerable to Algorithmic Complexity Attacks. + * + * The key to choosing a good hash is unpredictability. Even + * cryptographic hashes are very easy to find collisions for when the + * remainder is taken modulo a somewhat predictable prime number. There + * must be an element of randomness that an attacker is unable to guess. + * + * Returns: the hash value corresponding to the key + */ + +/** + * GHFunc: + * @key: a key + * @value: the value corresponding to the key + * @user_data: user data passed to g_hash_table_foreach() + * + * Specifies the type of the function passed to g_hash_table_foreach(). + * It is called with each key/value pair, together with the @user_data + * parameter which is passed to g_hash_table_foreach(). + */ + +/** + * GHRFunc: + * @key: a key + * @value: the value associated with the key + * @user_data: user data passed to g_hash_table_remove() + * + * Specifies the type of the function passed to + * g_hash_table_foreach_remove(). It is called with each key/value + * pair, together with the @user_data parameter passed to + * g_hash_table_foreach_remove(). It should return %TRUE if the + * key/value pair should be removed from the #GHashTable. + * + * Returns: %TRUE if the key/value pair should be removed from the + * #GHashTable + */ + +/** + * GEqualFunc: + * @a: a value + * @b: a value to compare with + * + * Specifies the type of a function used to test two values for + * equality. The function should return %TRUE if both values are equal + * and %FALSE otherwise. + * + * Returns: %TRUE if @a = @b; %FALSE otherwise + */ + +/** + * GHashTableIter: + * + * A GHashTableIter structure represents an iterator that can be used + * to iterate over the elements of a #GHashTable. GHashTableIter + * structures are typically allocated on the stack and then initialized + * with g_hash_table_iter_init(). + */ + +/** + * g_hash_table_freeze: + * @hash_table: a #GHashTable + * + * This function is deprecated and will be removed in the next major + * release of GLib. It does nothing. + */ + +/** + * g_hash_table_thaw: + * @hash_table: a #GHashTable + * + * This function is deprecated and will be removed in the next major + * release of GLib. It does nothing. + */ + +#define HASH_TABLE_MIN_SHIFT 3 /* 1 << 3 == 8 buckets */ + +#define UNUSED_HASH_VALUE 0 +#define TOMBSTONE_HASH_VALUE 1 +#define HASH_IS_UNUSED(h_) ((h_) == UNUSED_HASH_VALUE) +#define HASH_IS_TOMBSTONE(h_) ((h_) == TOMBSTONE_HASH_VALUE) +#define HASH_IS_REAL(h_) ((h_) >= 2) + +struct _GHashTable +{ + gint size; + gint mod; + guint mask; + gint nnodes; + gint noccupied; /* nnodes + tombstones */ + + gpointer *keys; + guint *hashes; + gpointer *values; + + GHashFunc hash_func; + GEqualFunc key_equal_func; + gint ref_count; +#ifndef G_DISABLE_ASSERT + /* + * Tracks the structure of the hash table, not its contents: is only + * incremented when a node is added or removed (is not incremented + * when the key or data of a node is modified). + */ + int version; +#endif + GDestroyNotify key_destroy_func; + GDestroyNotify value_destroy_func; +}; + +typedef struct +{ + GHashTable *hash_table; + gpointer dummy1; + gpointer dummy2; + int position; + gboolean dummy3; + int version; +} RealIter; + +/* Each table size has an associated prime modulo (the first prime + * lower than the table size) used to find the initial bucket. Probing + * then works modulo 2^n. The prime modulo is necessary to get a + * good distribution with poor hash functions. + */ +static const gint prime_mod [] = +{ + 1, /* For 1 << 0 */ + 2, + 3, + 7, + 13, + 31, + 61, + 127, + 251, + 509, + 1021, + 2039, + 4093, + 8191, + 16381, + 32749, + 65521, /* For 1 << 16 */ + 131071, + 262139, + 524287, + 1048573, + 2097143, + 4194301, + 8388593, + 16777213, + 33554393, + 67108859, + 134217689, + 268435399, + 536870909, + 1073741789, + 2147483647 /* For 1 << 31 */ +}; + +static void +g_hash_table_set_shift (GHashTable *hash_table, gint shift) +{ + gint i; + guint mask = 0; + + hash_table->size = 1 << shift; + hash_table->mod = prime_mod [shift]; + + for (i = 0; i < shift; i++) + { + mask <<= 1; + mask |= 1; + } + + hash_table->mask = mask; +} + +static gint +g_hash_table_find_closest_shift (gint n) +{ + gint i; + + for (i = 0; n; i++) + n >>= 1; + + return i; +} + +static void +g_hash_table_set_shift_from_size (GHashTable *hash_table, gint size) +{ + gint shift; + + shift = g_hash_table_find_closest_shift (size); + shift = MAX (shift, HASH_TABLE_MIN_SHIFT); + + g_hash_table_set_shift (hash_table, shift); +} + +/* + * g_hash_table_lookup_node: + * @hash_table: our #GHashTable + * @key: the key to lookup against + * @hash_return: key hash return location + * + * Performs a lookup in the hash table, preserving extra information + * usually needed for insertion. + * + * This function first computes the hash value of the key using the + * user's hash function. + * + * If an entry in the table matching @key is found then this function + * returns the index of that entry in the table, and if not, the + * index of an unused node (empty or tombstone) where the key can be + * inserted. + * + * The computed hash value is returned in the variable pointed to + * by @hash_return. This is to save insertions from having to compute + * the hash record again for the new record. + * + * Returns: index of the described node + */ +static inline guint +g_hash_table_lookup_node (GHashTable *hash_table, + gconstpointer key, + guint *hash_return) +{ + guint node_index; + guint node_hash; + guint hash_value; + guint first_tombstone = 0; + gboolean have_tombstone = FALSE; + guint step = 0; + + hash_value = hash_table->hash_func (key); + if (G_UNLIKELY (!HASH_IS_REAL (hash_value))) + hash_value = 2; + + *hash_return = hash_value; + + node_index = hash_value % hash_table->mod; + node_hash = hash_table->hashes[node_index]; + + while (!HASH_IS_UNUSED (node_hash)) + { + /* We first check if our full hash values + * are equal so we can avoid calling the full-blown + * key equality function in most cases. + */ + if (node_hash == hash_value) + { + gpointer node_key = hash_table->keys[node_index]; + + if (hash_table->key_equal_func) + { + if (hash_table->key_equal_func (node_key, key)) + return node_index; + } + else if (node_key == key) + { + return node_index; + } + } + else if (HASH_IS_TOMBSTONE (node_hash) && !have_tombstone) + { + first_tombstone = node_index; + have_tombstone = TRUE; + } + + step++; + node_index += step; + node_index &= hash_table->mask; + node_hash = hash_table->hashes[node_index]; + } + + if (have_tombstone) + return first_tombstone; + + return node_index; +} + +/* + * g_hash_table_remove_node: + * @hash_table: our #GHashTable + * @node: pointer to node to remove + * @notify: %TRUE if the destroy notify handlers are to be called + * + * Removes a node from the hash table and updates the node count. + * The node is replaced by a tombstone. No table resize is performed. + * + * If @notify is %TRUE then the destroy notify functions are called + * for the key and value of the hash node. + */ +static void +g_hash_table_remove_node (GHashTable *hash_table, + gint i, + gboolean notify) +{ + gpointer key; + gpointer value; + + key = hash_table->keys[i]; + value = hash_table->values[i]; + + /* Erect tombstone */ + hash_table->hashes[i] = TOMBSTONE_HASH_VALUE; + + /* Be GC friendly */ + hash_table->keys[i] = NULL; + hash_table->values[i] = NULL; + + hash_table->nnodes--; + + if (notify && hash_table->key_destroy_func) + hash_table->key_destroy_func (key); + + if (notify && hash_table->value_destroy_func) + hash_table->value_destroy_func (value); + +} + +/* + * g_hash_table_remove_all_nodes: + * @hash_table: our #GHashTable + * @notify: %TRUE if the destroy notify handlers are to be called + * + * Removes all nodes from the table. Since this may be a precursor to + * freeing the table entirely, no resize is performed. + * + * If @notify is %TRUE then the destroy notify functions are called + * for the key and value of the hash node. + */ +static void +g_hash_table_remove_all_nodes (GHashTable *hash_table, + gboolean notify) +{ + int i; + gpointer key; + gpointer value; + + hash_table->nnodes = 0; + hash_table->noccupied = 0; + + if (!notify || + (hash_table->key_destroy_func == NULL && + hash_table->value_destroy_func == NULL)) + { + memset (hash_table->hashes, 0, hash_table->size * sizeof (guint)); + memset (hash_table->keys, 0, hash_table->size * sizeof (gpointer)); + memset (hash_table->values, 0, hash_table->size * sizeof (gpointer)); + + return; + } + + for (i = 0; i < hash_table->size; i++) + { + if (HASH_IS_REAL (hash_table->hashes[i])) + { + key = hash_table->keys[i]; + value = hash_table->values[i]; + + hash_table->hashes[i] = UNUSED_HASH_VALUE; + hash_table->keys[i] = NULL; + hash_table->values[i] = NULL; + + if (hash_table->key_destroy_func != NULL) + hash_table->key_destroy_func (key); + + if (hash_table->value_destroy_func != NULL) + hash_table->value_destroy_func (value); + } + else if (HASH_IS_TOMBSTONE (hash_table->hashes[i])) + { + hash_table->hashes[i] = UNUSED_HASH_VALUE; + } + } +} + +/* + * g_hash_table_resize: + * @hash_table: our #GHashTable + * + * Resizes the hash table to the optimal size based on the number of + * nodes currently held. If you call this function then a resize will + * occur, even if one does not need to occur. + * Use g_hash_table_maybe_resize() instead. + * + * This function may "resize" the hash table to its current size, with + * the side effect of cleaning up tombstones and otherwise optimizing + * the probe sequences. + */ +static void +g_hash_table_resize (GHashTable *hash_table) +{ + gpointer *new_keys; + gpointer *new_values; + guint *new_hashes; + gint old_size; + gint i; + + old_size = hash_table->size; + g_hash_table_set_shift_from_size (hash_table, hash_table->nnodes * 2); + + new_keys = g_new0 (gpointer, hash_table->size); + if (hash_table->keys == hash_table->values) + new_values = new_keys; + else + new_values = g_new0 (gpointer, hash_table->size); + new_hashes = g_new0 (guint, hash_table->size); + + for (i = 0; i < old_size; i++) + { + guint node_hash = hash_table->hashes[i]; + guint hash_val; + guint step = 0; + + if (!HASH_IS_REAL (node_hash)) + continue; + + hash_val = node_hash % hash_table->mod; + + while (!HASH_IS_UNUSED (new_hashes[hash_val])) + { + step++; + hash_val += step; + hash_val &= hash_table->mask; + } + + new_hashes[hash_val] = hash_table->hashes[i]; + new_keys[hash_val] = hash_table->keys[i]; + new_values[hash_val] = hash_table->values[i]; + } + + if (hash_table->keys != hash_table->values) + g_free (hash_table->values); + + g_free (hash_table->keys); + g_free (hash_table->hashes); + + hash_table->keys = new_keys; + hash_table->values = new_values; + hash_table->hashes = new_hashes; + + hash_table->noccupied = hash_table->nnodes; +} + +/* + * g_hash_table_maybe_resize: + * @hash_table: our #GHashTable + * + * Resizes the hash table, if needed. + * + * Essentially, calls g_hash_table_resize() if the table has strayed + * too far from its ideal size for its number of nodes. + */ +static inline void +g_hash_table_maybe_resize (GHashTable *hash_table) +{ + gint noccupied = hash_table->noccupied; + gint size = hash_table->size; + + if ((size > hash_table->nnodes * 4 && size > 1 << HASH_TABLE_MIN_SHIFT) || + (size <= noccupied + (noccupied / 16))) + g_hash_table_resize (hash_table); +} + +/** + * g_hash_table_new: + * @hash_func: a function to create a hash value from a key + * @key_equal_func: a function to check two keys for equality + * + * Creates a new #GHashTable with a reference count of 1. + * + * Hash values returned by @hash_func are used to determine where keys + * are stored within the #GHashTable data structure. The g_direct_hash(), + * g_int_hash(), g_int64_hash(), g_double_hash() and g_str_hash() + * functions are provided for some common types of keys. + * If @hash_func is %NULL, g_direct_hash() is used. + * + * @key_equal_func is used when looking up keys in the #GHashTable. + * The g_direct_equal(), g_int_equal(), g_int64_equal(), g_double_equal() + * and g_str_equal() functions are provided for the most common types + * of keys. If @key_equal_func is %NULL, keys are compared directly in + * a similar fashion to g_direct_equal(), but without the overhead of + * a function call. + * + * Return value: a new #GHashTable + */ +GHashTable * +g_hash_table_new (GHashFunc hash_func, + GEqualFunc key_equal_func) +{ + return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL); +} + + +/** + * g_hash_table_new_full: + * @hash_func: a function to create a hash value from a key + * @key_equal_func: a function to check two keys for equality + * @key_destroy_func: a function to free the memory allocated for the key + * used when removing the entry from the #GHashTable, or %NULL + * if you don't want to supply such a function. + * @value_destroy_func: a function to free the memory allocated for the + * value used when removing the entry from the #GHashTable, or %NULL + * if you don't want to supply such a function. + * + * Creates a new #GHashTable like g_hash_table_new() with a reference + * count of 1 and allows to specify functions to free the memory + * allocated for the key and value that get called when removing the + * entry from the #GHashTable. + * + * Return value: a new #GHashTable + */ +GHashTable * +g_hash_table_new_full (GHashFunc hash_func, + GEqualFunc key_equal_func, + GDestroyNotify key_destroy_func, + GDestroyNotify value_destroy_func) +{ + GHashTable *hash_table; + + hash_table = g_slice_new (GHashTable); + g_hash_table_set_shift (hash_table, HASH_TABLE_MIN_SHIFT); + hash_table->nnodes = 0; + hash_table->noccupied = 0; + hash_table->hash_func = hash_func ? hash_func : g_direct_hash; + hash_table->key_equal_func = key_equal_func; + hash_table->ref_count = 1; +#ifndef G_DISABLE_ASSERT + hash_table->version = 0; +#endif + hash_table->key_destroy_func = key_destroy_func; + hash_table->value_destroy_func = value_destroy_func; + hash_table->keys = g_new0 (gpointer, hash_table->size); + hash_table->values = hash_table->keys; + hash_table->hashes = g_new0 (guint, hash_table->size); + + return hash_table; +} + +/** + * g_hash_table_iter_init: + * @iter: an uninitialized #GHashTableIter + * @hash_table: a #GHashTable + * + * Initializes a key/value pair iterator and associates it with + * @hash_table. Modifying the hash table after calling this function + * invalidates the returned iterator. + * |[ + * GHashTableIter iter; + * gpointer key, value; + * + * g_hash_table_iter_init (&iter, hash_table); + * while (g_hash_table_iter_next (&iter, &key, &value)) + * { + * /* do something with key and value */ + * } + * ]| + * + * Since: 2.16 + */ +void +g_hash_table_iter_init (GHashTableIter *iter, + GHashTable *hash_table) +{ + RealIter *ri = (RealIter *) iter; + + g_return_if_fail (iter != NULL); + g_return_if_fail (hash_table != NULL); + + ri->hash_table = hash_table; + ri->position = -1; +#ifndef G_DISABLE_ASSERT + ri->version = hash_table->version; +#endif +} + +/** + * g_hash_table_iter_next: + * @iter: an initialized #GHashTableIter + * @key: a location to store the key, or %NULL + * @value: a location to store the value, or %NULL + * + * Advances @iter and retrieves the key and/or value that are now + * pointed to as a result of this advancement. If %FALSE is returned, + * @key and @value are not set, and the iterator becomes invalid. + * + * Return value: %FALSE if the end of the #GHashTable has been reached. + * + * Since: 2.16 + */ +gboolean +g_hash_table_iter_next (GHashTableIter *iter, + gpointer *key, + gpointer *value) +{ + RealIter *ri = (RealIter *) iter; + gint position; + + g_return_val_if_fail (iter != NULL, FALSE); +#ifndef G_DISABLE_ASSERT + g_return_val_if_fail (ri->version == ri->hash_table->version, FALSE); +#endif + g_return_val_if_fail (ri->position < ri->hash_table->size, FALSE); + + position = ri->position; + + do + { + position++; + if (position >= ri->hash_table->size) + { + ri->position = position; + return FALSE; + } + } + while (!HASH_IS_REAL (ri->hash_table->hashes[position])); + + if (key != NULL) + *key = ri->hash_table->keys[position]; + if (value != NULL) + *value = ri->hash_table->values[position]; + + ri->position = position; + return TRUE; +} + +/** + * g_hash_table_iter_get_hash_table: + * @iter: an initialized #GHashTableIter + * + * Returns the #GHashTable associated with @iter. + * + * Return value: the #GHashTable associated with @iter. + * + * Since: 2.16 + */ +GHashTable * +g_hash_table_iter_get_hash_table (GHashTableIter *iter) +{ + g_return_val_if_fail (iter != NULL, NULL); + + return ((RealIter *) iter)->hash_table; +} + +static void +iter_remove_or_steal (RealIter *ri, gboolean notify) +{ + g_return_if_fail (ri != NULL); +#ifndef G_DISABLE_ASSERT + g_return_if_fail (ri->version == ri->hash_table->version); +#endif + g_return_if_fail (ri->position >= 0); + g_return_if_fail (ri->position < ri->hash_table->size); + + g_hash_table_remove_node (ri->hash_table, ri->position, notify); + +#ifndef G_DISABLE_ASSERT + ri->version++; + ri->hash_table->version++; +#endif +} + +/** + * g_hash_table_iter_remove: + * @iter: an initialized #GHashTableIter + * + * Removes the key/value pair currently pointed to by the iterator + * from its associated #GHashTable. Can only be called after + * g_hash_table_iter_next() returned %TRUE, and cannot be called + * more than once for the same key/value pair. + * + * If the #GHashTable was created using g_hash_table_new_full(), + * the key and value are freed using the supplied destroy functions, + * otherwise you have to make sure that any dynamically allocated + * values are freed yourself. + * + * Since: 2.16 + */ +void +g_hash_table_iter_remove (GHashTableIter *iter) +{ + iter_remove_or_steal ((RealIter *) iter, TRUE); +} + +/* + * g_hash_table_insert_node: + * @hash_table: our #GHashTable + * @node_index: pointer to node to insert/replace + * @key_hash: key hash + * @key: key to replace with, or %NULL + * @value: value to replace with + * @keep_new_key: whether to replace the key in the node with @key + * @reusing_key: whether @key was taken out of the existing node + * + * Inserts a value at @node_index in the hash table and updates it. + * + * If @key has been taken out of the existing node (ie it is not + * passed in via a g_hash_table_insert/replace) call, then @reusing_key + * should be %TRUE. + */ +static void +g_hash_table_insert_node (GHashTable *hash_table, + guint node_index, + guint key_hash, + gpointer key, + gpointer value, + gboolean keep_new_key, + gboolean reusing_key) +{ + guint old_hash; + gpointer old_key; + gpointer old_value; + + if (G_UNLIKELY (hash_table->keys == hash_table->values && key != value)) + hash_table->values = g_memdup (hash_table->keys, sizeof (gpointer) * hash_table->size); + + old_hash = hash_table->hashes[node_index]; + old_key = hash_table->keys[node_index]; + old_value = hash_table->values[node_index]; + + if (HASH_IS_REAL (old_hash)) + { + if (keep_new_key) + hash_table->keys[node_index] = key; + hash_table->values[node_index] = value; + } + else + { + hash_table->keys[node_index] = key; + hash_table->values[node_index] = value; + hash_table->hashes[node_index] = key_hash; + + hash_table->nnodes++; + + if (HASH_IS_UNUSED (old_hash)) + { + /* We replaced an empty node, and not a tombstone */ + hash_table->noccupied++; + g_hash_table_maybe_resize (hash_table); + } + +#ifndef G_DISABLE_ASSERT + hash_table->version++; +#endif + } + + if (HASH_IS_REAL (old_hash)) + { + if (hash_table->key_destroy_func && !reusing_key) + hash_table->key_destroy_func (keep_new_key ? old_key : key); + if (hash_table->value_destroy_func) + hash_table->value_destroy_func (old_value); + } +} + +/** + * g_hash_table_iter_replace: + * @iter: an initialized #GHashTableIter + * @value: the value to replace with + * + * Replaces the value currently pointed to by the iterator + * from its associated #GHashTable. Can only be called after + * g_hash_table_iter_next() returned %TRUE. + * + * If you supplied a @value_destroy_func when creating the + * #GHashTable, the old value is freed using that function. + * + * Since: 2.30 + */ +void +g_hash_table_iter_replace (GHashTableIter *iter, + gpointer value) +{ + RealIter *ri; + guint node_hash; + gpointer key; + + ri = (RealIter *) iter; + + g_return_if_fail (ri != NULL); +#ifndef G_DISABLE_ASSERT + g_return_if_fail (ri->version == ri->hash_table->version); +#endif + g_return_if_fail (ri->position >= 0); + g_return_if_fail (ri->position < ri->hash_table->size); + + node_hash = ri->hash_table->hashes[ri->position]; + key = ri->hash_table->keys[ri->position]; + + g_hash_table_insert_node (ri->hash_table, ri->position, node_hash, key, value, TRUE, TRUE); + +#ifndef G_DISABLE_ASSERT + ri->version++; + ri->hash_table->version++; +#endif +} + +/** + * g_hash_table_iter_steal: + * @iter: an initialized #GHashTableIter + * + * Removes the key/value pair currently pointed to by the + * iterator from its associated #GHashTable, without calling + * the key and value destroy functions. Can only be called + * after g_hash_table_iter_next() returned %TRUE, and cannot + * be called more than once for the same key/value pair. + * + * Since: 2.16 + */ +void +g_hash_table_iter_steal (GHashTableIter *iter) +{ + iter_remove_or_steal ((RealIter *) iter, FALSE); +} + + +/** + * g_hash_table_ref: + * @hash_table: a valid #GHashTable + * + * Atomically increments the reference count of @hash_table by one. + * This function is MT-safe and may be called from any thread. + * + * Return value: the passed in #GHashTable + * + * Since: 2.10 + */ +GHashTable * +g_hash_table_ref (GHashTable *hash_table) +{ + g_return_val_if_fail (hash_table != NULL, NULL); + + g_atomic_int_inc (&hash_table->ref_count); + + return hash_table; +} + +/** + * g_hash_table_unref: + * @hash_table: a valid #GHashTable + * + * Atomically decrements the reference count of @hash_table by one. + * If the reference count drops to 0, all keys and values will be + * destroyed, and all memory allocated by the hash table is released. + * This function is MT-safe and may be called from any thread. + * + * Since: 2.10 + */ +void +g_hash_table_unref (GHashTable *hash_table) +{ + g_return_if_fail (hash_table != NULL); + + if (g_atomic_int_dec_and_test (&hash_table->ref_count)) + { + g_hash_table_remove_all_nodes (hash_table, TRUE); + if (hash_table->keys != hash_table->values) + g_free (hash_table->values); + g_free (hash_table->keys); + g_free (hash_table->hashes); + g_slice_free (GHashTable, hash_table); + } +} + +/** + * g_hash_table_destroy: + * @hash_table: a #GHashTable + * + * Destroys all keys and values in the #GHashTable and decrements its + * reference count by 1. If keys and/or values are dynamically allocated, + * you should either free them first or create the #GHashTable with destroy + * notifiers using g_hash_table_new_full(). In the latter case the destroy + * functions you supplied will be called on all keys and values during the + * destruction phase. + */ +void +g_hash_table_destroy (GHashTable *hash_table) +{ + g_return_if_fail (hash_table != NULL); + + g_hash_table_remove_all (hash_table); + g_hash_table_unref (hash_table); +} + +/** + * g_hash_table_lookup: + * @hash_table: a #GHashTable + * @key: the key to look up + * + * Looks up a key in a #GHashTable. Note that this function cannot + * distinguish between a key that is not present and one which is present + * and has the value %NULL. If you need this distinction, use + * g_hash_table_lookup_extended(). + * + * Return value: (allow-none): the associated value, or %NULL if the key is not found + */ +gpointer +g_hash_table_lookup (GHashTable *hash_table, + gconstpointer key) +{ + guint node_index; + guint node_hash; + + g_return_val_if_fail (hash_table != NULL, NULL); + + node_index = g_hash_table_lookup_node (hash_table, key, &node_hash); + + return HASH_IS_REAL (hash_table->hashes[node_index]) + ? hash_table->values[node_index] + : NULL; +} + +/** + * g_hash_table_lookup_extended: + * @hash_table: a #GHashTable + * @lookup_key: the key to look up + * @orig_key: (allow-none): return location for the original key, or %NULL + * @value: (allow-none): return location for the value associated with the key, or %NULL + * + * Looks up a key in the #GHashTable, returning the original key and the + * associated value and a #gboolean which is %TRUE if the key was found. This + * is useful if you need to free the memory allocated for the original key, + * for example before calling g_hash_table_remove(). + * + * You can actually pass %NULL for @lookup_key to test + * whether the %NULL key exists, provided the hash and equal functions + * of @hash_table are %NULL-safe. + * + * Return value: %TRUE if the key was found in the #GHashTable + */ +gboolean +g_hash_table_lookup_extended (GHashTable *hash_table, + gconstpointer lookup_key, + gpointer *orig_key, + gpointer *value) +{ + guint node_index; + guint node_hash; + + g_return_val_if_fail (hash_table != NULL, FALSE); + + node_index = g_hash_table_lookup_node (hash_table, lookup_key, &node_hash); + + if (!HASH_IS_REAL (hash_table->hashes[node_index])) + return FALSE; + + if (orig_key) + *orig_key = hash_table->keys[node_index]; + + if (value) + *value = hash_table->values[node_index]; + + return TRUE; +} + +/* + * g_hash_table_insert_internal: + * @hash_table: our #GHashTable + * @key: the key to insert + * @value: the value to insert + * @keep_new_key: if %TRUE and this key already exists in the table + * then call the destroy notify function on the old key. If %FALSE + * then call the destroy notify function on the new key. + * + * Implements the common logic for the g_hash_table_insert() and + * g_hash_table_replace() functions. + * + * Do a lookup of @key. If it is found, replace it with the new + * @value (and perhaps the new @key). If it is not found, create + * a new node. + */ +static void +g_hash_table_insert_internal (GHashTable *hash_table, + gpointer key, + gpointer value, + gboolean keep_new_key) +{ + guint key_hash; + guint node_index; + + g_return_if_fail (hash_table != NULL); + + node_index = g_hash_table_lookup_node (hash_table, key, &key_hash); + + g_hash_table_insert_node (hash_table, node_index, key_hash, key, value, keep_new_key, FALSE); +} + +/** + * g_hash_table_insert: + * @hash_table: a #GHashTable + * @key: a key to insert + * @value: the value to associate with the key + * + * Inserts a new key and value into a #GHashTable. + * + * If the key already exists in the #GHashTable its current + * value is replaced with the new value. If you supplied a + * @value_destroy_func when creating the #GHashTable, the old + * value is freed using that function. If you supplied a + * @key_destroy_func when creating the #GHashTable, the passed + * key is freed using that function. + */ +void +g_hash_table_insert (GHashTable *hash_table, + gpointer key, + gpointer value) +{ + g_hash_table_insert_internal (hash_table, key, value, FALSE); +} + +/** + * g_hash_table_replace: + * @hash_table: a #GHashTable + * @key: a key to insert + * @value: the value to associate with the key + * + * Inserts a new key and value into a #GHashTable similar to + * g_hash_table_insert(). The difference is that if the key + * already exists in the #GHashTable, it gets replaced by the + * new key. If you supplied a @value_destroy_func when creating + * the #GHashTable, the old value is freed using that function. + * If you supplied a @key_destroy_func when creating the + * #GHashTable, the old key is freed using that function. + */ +void +g_hash_table_replace (GHashTable *hash_table, + gpointer key, + gpointer value) +{ + g_hash_table_insert_internal (hash_table, key, value, TRUE); +} + +/** + * g_hash_table_add: + * @hash_table: a #GHashTable + * @key: a key to insert + * + * This is a convenience function for using a #GHashTable as a set. It + * is equivalent to calling g_hash_table_replace() with @key as both the + * key and the value. + * + * When a hash table only ever contains keys that have themselves as the + * corresponding value it is able to be stored more efficiently. See + * the discussion in the section description. + * + * Since: 2.32 + **/ +void +g_hash_table_add (GHashTable *hash_table, + gpointer key) +{ + g_hash_table_insert_internal (hash_table, key, key, TRUE); +} + +/** + * g_hash_table_contains: + * @hash_table: a #GHashTable + * @key: a key to check + * + * Checks if @key is in @hash_table. + * + * Since: 2.32 + **/ +gboolean +g_hash_table_contains (GHashTable *hash_table, + gconstpointer key) +{ + guint node_index; + guint node_hash; + + g_return_val_if_fail (hash_table != NULL, FALSE); + + node_index = g_hash_table_lookup_node (hash_table, key, &node_hash); + + return HASH_IS_REAL (hash_table->hashes[node_index]); +} + +/* + * g_hash_table_remove_internal: + * @hash_table: our #GHashTable + * @key: the key to remove + * @notify: %TRUE if the destroy notify handlers are to be called + * Return value: %TRUE if a node was found and removed, else %FALSE + * + * Implements the common logic for the g_hash_table_remove() and + * g_hash_table_steal() functions. + * + * Do a lookup of @key and remove it if it is found, calling the + * destroy notify handlers only if @notify is %TRUE. + */ +static gboolean +g_hash_table_remove_internal (GHashTable *hash_table, + gconstpointer key, + gboolean notify) +{ + guint node_index; + guint node_hash; + + g_return_val_if_fail (hash_table != NULL, FALSE); + + node_index = g_hash_table_lookup_node (hash_table, key, &node_hash); + + if (!HASH_IS_REAL (hash_table->hashes[node_index])) + return FALSE; + + g_hash_table_remove_node (hash_table, node_index, notify); + g_hash_table_maybe_resize (hash_table); + +#ifndef G_DISABLE_ASSERT + hash_table->version++; +#endif + + return TRUE; +} + +/** + * g_hash_table_remove: + * @hash_table: a #GHashTable + * @key: the key to remove + * + * Removes a key and its associated value from a #GHashTable. + * + * If the #GHashTable was created using g_hash_table_new_full(), the + * key and value are freed using the supplied destroy functions, otherwise + * you have to make sure that any dynamically allocated values are freed + * yourself. + * + * Returns: %TRUE if the key was found and removed from the #GHashTable + */ +gboolean +g_hash_table_remove (GHashTable *hash_table, + gconstpointer key) +{ + return g_hash_table_remove_internal (hash_table, key, TRUE); +} + +/** + * g_hash_table_steal: + * @hash_table: a #GHashTable + * @key: the key to remove + * + * Removes a key and its associated value from a #GHashTable without + * calling the key and value destroy functions. + * + * Returns: %TRUE if the key was found and removed from the #GHashTable + */ +gboolean +g_hash_table_steal (GHashTable *hash_table, + gconstpointer key) +{ + return g_hash_table_remove_internal (hash_table, key, FALSE); +} + +/** + * g_hash_table_remove_all: + * @hash_table: a #GHashTable + * + * Removes all keys and their associated values from a #GHashTable. + * + * If the #GHashTable was created using g_hash_table_new_full(), + * the keys and values are freed using the supplied destroy functions, + * otherwise you have to make sure that any dynamically allocated + * values are freed yourself. + * + * Since: 2.12 + */ +void +g_hash_table_remove_all (GHashTable *hash_table) +{ + g_return_if_fail (hash_table != NULL); + +#ifndef G_DISABLE_ASSERT + if (hash_table->nnodes != 0) + hash_table->version++; +#endif + + g_hash_table_remove_all_nodes (hash_table, TRUE); + g_hash_table_maybe_resize (hash_table); +} + +/** + * g_hash_table_steal_all: + * @hash_table: a #GHashTable + * + * Removes all keys and their associated values from a #GHashTable + * without calling the key and value destroy functions. + * + * Since: 2.12 + */ +void +g_hash_table_steal_all (GHashTable *hash_table) +{ + g_return_if_fail (hash_table != NULL); + +#ifndef G_DISABLE_ASSERT + if (hash_table->nnodes != 0) + hash_table->version++; +#endif + + g_hash_table_remove_all_nodes (hash_table, FALSE); + g_hash_table_maybe_resize (hash_table); +} + +/* + * g_hash_table_foreach_remove_or_steal: + * @hash_table: a #GHashTable + * @func: the user's callback function + * @user_data: data for @func + * @notify: %TRUE if the destroy notify handlers are to be called + * + * Implements the common logic for g_hash_table_foreach_remove() + * and g_hash_table_foreach_steal(). + * + * Iterates over every node in the table, calling @func with the key + * and value of the node (and @user_data). If @func returns %TRUE the + * node is removed from the table. + * + * If @notify is true then the destroy notify handlers will be called + * for each removed node. + */ +static guint +g_hash_table_foreach_remove_or_steal (GHashTable *hash_table, + GHRFunc func, + gpointer user_data, + gboolean notify) +{ + guint deleted = 0; + gint i; +#ifndef G_DISABLE_ASSERT + gint version = hash_table->version; +#endif + + for (i = 0; i < hash_table->size; i++) + { + guint node_hash = hash_table->hashes[i]; + gpointer node_key = hash_table->keys[i]; + gpointer node_value = hash_table->values[i]; + + if (HASH_IS_REAL (node_hash) && + (* func) (node_key, node_value, user_data)) + { + g_hash_table_remove_node (hash_table, i, notify); + deleted++; + } + +#ifndef G_DISABLE_ASSERT + g_return_val_if_fail (version == hash_table->version, 0); +#endif + } + + g_hash_table_maybe_resize (hash_table); + +#ifndef G_DISABLE_ASSERT + if (deleted > 0) + hash_table->version++; +#endif + + return deleted; +} + +/** + * g_hash_table_foreach_remove: + * @hash_table: a #GHashTable + * @func: the function to call for each key/value pair + * @user_data: user data to pass to the function + * + * Calls the given function for each key/value pair in the + * #GHashTable. If the function returns %TRUE, then the key/value + * pair is removed from the #GHashTable. If you supplied key or + * value destroy functions when creating the #GHashTable, they are + * used to free the memory allocated for the removed keys and values. + * + * See #GHashTableIter for an alternative way to loop over the + * key/value pairs in the hash table. + * + * Return value: the number of key/value pairs removed + */ +guint +g_hash_table_foreach_remove (GHashTable *hash_table, + GHRFunc func, + gpointer user_data) +{ + g_return_val_if_fail (hash_table != NULL, 0); + g_return_val_if_fail (func != NULL, 0); + + return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE); +} + +/** + * g_hash_table_foreach_steal: + * @hash_table: a #GHashTable + * @func: the function to call for each key/value pair + * @user_data: user data to pass to the function + * + * Calls the given function for each key/value pair in the + * #GHashTable. If the function returns %TRUE, then the key/value + * pair is removed from the #GHashTable, but no key or value + * destroy functions are called. + * + * See #GHashTableIter for an alternative way to loop over the + * key/value pairs in the hash table. + * + * Return value: the number of key/value pairs removed. + */ +guint +g_hash_table_foreach_steal (GHashTable *hash_table, + GHRFunc func, + gpointer user_data) +{ + g_return_val_if_fail (hash_table != NULL, 0); + g_return_val_if_fail (func != NULL, 0); + + return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE); +} + +/** + * g_hash_table_foreach: + * @hash_table: a #GHashTable + * @func: the function to call for each key/value pair + * @user_data: user data to pass to the function + * + * Calls the given function for each of the key/value pairs in the + * #GHashTable. The function is passed the key and value of each + * pair, and the given @user_data parameter. The hash table may not + * be modified while iterating over it (you can't add/remove + * items). To remove all items matching a predicate, use + * g_hash_table_foreach_remove(). + * + * See g_hash_table_find() for performance caveats for linear + * order searches in contrast to g_hash_table_lookup(). + */ +void +g_hash_table_foreach (GHashTable *hash_table, + GHFunc func, + gpointer user_data) +{ + gint i; +#ifndef G_DISABLE_ASSERT + gint version; +#endif + + g_return_if_fail (hash_table != NULL); + g_return_if_fail (func != NULL); + +#ifndef G_DISABLE_ASSERT + version = hash_table->version; +#endif + + for (i = 0; i < hash_table->size; i++) + { + guint node_hash = hash_table->hashes[i]; + gpointer node_key = hash_table->keys[i]; + gpointer node_value = hash_table->values[i]; + + if (HASH_IS_REAL (node_hash)) + (* func) (node_key, node_value, user_data); + +#ifndef G_DISABLE_ASSERT + g_return_if_fail (version == hash_table->version); +#endif + } +} + +/** + * g_hash_table_find: + * @hash_table: a #GHashTable + * @predicate: function to test the key/value pairs for a certain property + * @user_data: user data to pass to the function + * + * Calls the given function for key/value pairs in the #GHashTable + * until @predicate returns %TRUE. The function is passed the key + * and value of each pair, and the given @user_data parameter. The + * hash table may not be modified while iterating over it (you can't + * add/remove items). + * + * Note, that hash tables are really only optimized for forward + * lookups, i.e. g_hash_table_lookup(). So code that frequently issues + * g_hash_table_find() or g_hash_table_foreach() (e.g. in the order of + * once per every entry in a hash table) should probably be reworked + * to use additional or different data structures for reverse lookups + * (keep in mind that an O(n) find/foreach operation issued for all n + * values in a hash table ends up needing O(n*n) operations). + * + * Return value: (allow-none): The value of the first key/value pair is returned, + * for which @predicate evaluates to %TRUE. If no pair with the + * requested property is found, %NULL is returned. + * + * Since: 2.4 + */ +gpointer +g_hash_table_find (GHashTable *hash_table, + GHRFunc predicate, + gpointer user_data) +{ + gint i; +#ifndef G_DISABLE_ASSERT + gint version; +#endif + gboolean match; + + g_return_val_if_fail (hash_table != NULL, NULL); + g_return_val_if_fail (predicate != NULL, NULL); + +#ifndef G_DISABLE_ASSERT + version = hash_table->version; +#endif + + match = FALSE; + + for (i = 0; i < hash_table->size; i++) + { + guint node_hash = hash_table->hashes[i]; + gpointer node_key = hash_table->keys[i]; + gpointer node_value = hash_table->values[i]; + + if (HASH_IS_REAL (node_hash)) + match = predicate (node_key, node_value, user_data); + +#ifndef G_DISABLE_ASSERT + g_return_val_if_fail (version == hash_table->version, NULL); +#endif + + if (match) + return node_value; + } + + return NULL; +} + +/** + * g_hash_table_size: + * @hash_table: a #GHashTable + * + * Returns the number of elements contained in the #GHashTable. + * + * Return value: the number of key/value pairs in the #GHashTable. + */ +guint +g_hash_table_size (GHashTable *hash_table) +{ + g_return_val_if_fail (hash_table != NULL, 0); + + return hash_table->nnodes; +} + +/** + * g_hash_table_get_keys: + * @hash_table: a #GHashTable + * + * Retrieves every key inside @hash_table. The returned data + * is valid until @hash_table is modified. + * + * Return value: a #GList containing all the keys inside the hash + * table. The content of the list is owned by the hash table and + * should not be modified or freed. Use g_list_free() when done + * using the list. + * + * Since: 2.14 + */ +GList * +g_hash_table_get_keys (GHashTable *hash_table) +{ + gint i; + GList *retval; + + g_return_val_if_fail (hash_table != NULL, NULL); + + retval = NULL; + for (i = 0; i < hash_table->size; i++) + { + if (HASH_IS_REAL (hash_table->hashes[i])) + retval = g_list_prepend (retval, hash_table->keys[i]); + } + + return retval; +} + +/** + * g_hash_table_get_values: + * @hash_table: a #GHashTable + * + * Retrieves every value inside @hash_table. The returned data + * is valid until @hash_table is modified. + * + * Return value: a #GList containing all the values inside the hash + * table. The content of the list is owned by the hash table and + * should not be modified or freed. Use g_list_free() when done + * using the list. + * + * Since: 2.14 + */ +GList * +g_hash_table_get_values (GHashTable *hash_table) +{ + gint i; + GList *retval; + + g_return_val_if_fail (hash_table != NULL, NULL); + + retval = NULL; + for (i = 0; i < hash_table->size; i++) + { + if (HASH_IS_REAL (hash_table->hashes[i])) + retval = g_list_prepend (retval, hash_table->values[i]); + } + + return retval; +} + +/* Hash functions. + */ + +/** + * g_str_equal: + * @v1: a key + * @v2: a key to compare with @v1 + * + * Compares two strings for byte-by-byte equality and returns %TRUE + * if they are equal. It can be passed to g_hash_table_new() as the + * @key_equal_func parameter, when using non-%NULL strings as keys in a + * #GHashTable. + * + * Note that this function is primarily meant as a hash table comparison + * function. For a general-purpose, %NULL-safe string comparison function, + * see g_strcmp0(). + * + * Returns: %TRUE if the two keys match + */ +gboolean +g_str_equal (gconstpointer v1, + gconstpointer v2) +{ + const gchar *string1 = v1; + const gchar *string2 = v2; + + return strcmp (string1, string2) == 0; +} + +/** + * g_str_hash: + * @v: a string key + * + * Converts a string to a hash value. + * + * This function implements the widely used "djb" hash apparently posted + * by Daniel Bernstein to comp.lang.c some time ago. The 32 bit + * unsigned hash value starts at 5381 and for each byte 'c' in the + * string, is updated: hash = hash * 33 + c. This + * function uses the signed value of each byte. + * + * It can be passed to g_hash_table_new() as the @hash_func parameter, + * when using non-%NULL strings as keys in a #GHashTable. + * + * Returns: a hash value corresponding to the key + */ +guint +g_str_hash (gconstpointer v) +{ + const signed char *p; + guint32 h = 5381; + + for (p = v; *p != '\0'; p++) + h = (h << 5) + h + *p; + + return h; +} + +/** + * g_direct_hash: + * @v: (allow-none): a #gpointer key + * + * Converts a gpointer to a hash value. + * It can be passed to g_hash_table_new() as the @hash_func parameter, + * when using opaque pointers compared by pointer value as keys in a + * #GHashTable. + * + * This hash function is also appropriate for keys that are integers stored + * in pointers, such as GINT_TO_POINTER (n). + * + * Returns: a hash value corresponding to the key. + */ +guint +g_direct_hash (gconstpointer v) +{ + return GPOINTER_TO_UINT (v); +} + +/** + * g_direct_equal: + * @v1: (allow-none): a key + * @v2: (allow-none): a key to compare with @v1 + * + * Compares two #gpointer arguments and returns %TRUE if they are equal. + * It can be passed to g_hash_table_new() as the @key_equal_func + * parameter, when using opaque pointers compared by pointer value as keys + * in a #GHashTable. + * + * This equality function is also appropriate for keys that are integers stored + * in pointers, such as GINT_TO_POINTER (n). + * + * Returns: %TRUE if the two keys match. + */ +gboolean +g_direct_equal (gconstpointer v1, + gconstpointer v2) +{ + return v1 == v2; +} + +/** + * g_int_equal: + * @v1: a pointer to a #gint key + * @v2: a pointer to a #gint key to compare with @v1 + * + * Compares the two #gint values being pointed to and returns + * %TRUE if they are equal. + * It can be passed to g_hash_table_new() as the @key_equal_func + * parameter, when using non-%NULL pointers to integers as keys in a + * #GHashTable. + * + * Note that this function acts on pointers to #gint, not on #gint directly: + * if your hash table's keys are of the form + * GINT_TO_POINTER (n), use g_direct_equal() instead. + * + * Returns: %TRUE if the two keys match. + */ +gboolean +g_int_equal (gconstpointer v1, + gconstpointer v2) +{ + return *((const gint*) v1) == *((const gint*) v2); +} + +/** + * g_int_hash: + * @v: a pointer to a #gint key + * + * Converts a pointer to a #gint to a hash value. + * It can be passed to g_hash_table_new() as the @hash_func parameter, + * when using non-%NULL pointers to integer values as keys in a #GHashTable. + * + * Note that this function acts on pointers to #gint, not on #gint directly: + * if your hash table's keys are of the form + * GINT_TO_POINTER (n), use g_direct_hash() instead. + * + * Returns: a hash value corresponding to the key. + */ +guint +g_int_hash (gconstpointer v) +{ + return *(const gint*) v; +} + +/** + * g_int64_equal: + * @v1: a pointer to a #gint64 key + * @v2: a pointer to a #gint64 key to compare with @v1 + * + * Compares the two #gint64 values being pointed to and returns + * %TRUE if they are equal. + * It can be passed to g_hash_table_new() as the @key_equal_func + * parameter, when using non-%NULL pointers to 64-bit integers as keys in a + * #GHashTable. + * + * Returns: %TRUE if the two keys match. + * + * Since: 2.22 + */ +gboolean +g_int64_equal (gconstpointer v1, + gconstpointer v2) +{ + return *((const gint64*) v1) == *((const gint64*) v2); +} + +/** + * g_int64_hash: + * @v: a pointer to a #gint64 key + * + * Converts a pointer to a #gint64 to a hash value. + * + * It can be passed to g_hash_table_new() as the @hash_func parameter, + * when using non-%NULL pointers to 64-bit integer values as keys in a + * #GHashTable. + * + * Returns: a hash value corresponding to the key. + * + * Since: 2.22 + */ +guint +g_int64_hash (gconstpointer v) +{ + return (guint) *(const gint64*) v; +} + +/** + * g_double_equal: + * @v1: a pointer to a #gdouble key + * @v2: a pointer to a #gdouble key to compare with @v1 + * + * Compares the two #gdouble values being pointed to and returns + * %TRUE if they are equal. + * It can be passed to g_hash_table_new() as the @key_equal_func + * parameter, when using non-%NULL pointers to doubles as keys in a + * #GHashTable. + * + * Returns: %TRUE if the two keys match. + * + * Since: 2.22 + */ +gboolean +g_double_equal (gconstpointer v1, + gconstpointer v2) +{ + return *((const gdouble*) v1) == *((const gdouble*) v2); +} + +/** + * g_double_hash: + * @v: a pointer to a #gdouble key + * + * Converts a pointer to a #gdouble to a hash value. + * It can be passed to g_hash_table_new() as the @hash_func parameter, + * It can be passed to g_hash_table_new() as the @hash_func parameter, + * when using non-%NULL pointers to doubles as keys in a #GHashTable. + * + * Returns: a hash value corresponding to the key. + * + * Since: 2.22 + */ +guint +g_double_hash (gconstpointer v) +{ + return (guint) *(const gdouble*) v; +} diff --git a/glib/glib/ghash.h b/glib/glib/ghash.h new file mode 100644 index 0000000..b369989 --- /dev/null +++ b/glib/glib/ghash.h @@ -0,0 +1,146 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_HASH_H__ +#define __G_HASH_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GHashTable GHashTable; + +typedef gboolean (*GHRFunc) (gpointer key, + gpointer value, + gpointer user_data); + +typedef struct _GHashTableIter GHashTableIter; + +struct _GHashTableIter +{ + /*< private >*/ + gpointer dummy1; + gpointer dummy2; + gpointer dummy3; + int dummy4; + gboolean dummy5; + gpointer dummy6; +}; + +GHashTable* g_hash_table_new (GHashFunc hash_func, + GEqualFunc key_equal_func); +GHashTable* g_hash_table_new_full (GHashFunc hash_func, + GEqualFunc key_equal_func, + GDestroyNotify key_destroy_func, + GDestroyNotify value_destroy_func); +void g_hash_table_destroy (GHashTable *hash_table); +void g_hash_table_insert (GHashTable *hash_table, + gpointer key, + gpointer value); +void g_hash_table_replace (GHashTable *hash_table, + gpointer key, + gpointer value); +void g_hash_table_add (GHashTable *hash_table, + gpointer key); +gboolean g_hash_table_remove (GHashTable *hash_table, + gconstpointer key); +void g_hash_table_remove_all (GHashTable *hash_table); +gboolean g_hash_table_steal (GHashTable *hash_table, + gconstpointer key); +void g_hash_table_steal_all (GHashTable *hash_table); +gpointer g_hash_table_lookup (GHashTable *hash_table, + gconstpointer key); +gboolean g_hash_table_contains (GHashTable *hash_table, + gconstpointer key); +gboolean g_hash_table_lookup_extended (GHashTable *hash_table, + gconstpointer lookup_key, + gpointer *orig_key, + gpointer *value); +void g_hash_table_foreach (GHashTable *hash_table, + GHFunc func, + gpointer user_data); +gpointer g_hash_table_find (GHashTable *hash_table, + GHRFunc predicate, + gpointer user_data); +guint g_hash_table_foreach_remove (GHashTable *hash_table, + GHRFunc func, + gpointer user_data); +guint g_hash_table_foreach_steal (GHashTable *hash_table, + GHRFunc func, + gpointer user_data); +guint g_hash_table_size (GHashTable *hash_table); +GList * g_hash_table_get_keys (GHashTable *hash_table); +GList * g_hash_table_get_values (GHashTable *hash_table); + +void g_hash_table_iter_init (GHashTableIter *iter, + GHashTable *hash_table); +gboolean g_hash_table_iter_next (GHashTableIter *iter, + gpointer *key, + gpointer *value); +GHashTable* g_hash_table_iter_get_hash_table (GHashTableIter *iter); +void g_hash_table_iter_remove (GHashTableIter *iter); +void g_hash_table_iter_replace (GHashTableIter *iter, + gpointer value); +void g_hash_table_iter_steal (GHashTableIter *iter); + +GHashTable* g_hash_table_ref (GHashTable *hash_table); +void g_hash_table_unref (GHashTable *hash_table); + +#ifndef G_DISABLE_DEPRECATED +#define g_hash_table_freeze(hash_table) ((void)0) +#define g_hash_table_thaw(hash_table) ((void)0) +#endif + +/* Hash Functions + */ +gboolean g_str_equal (gconstpointer v1, + gconstpointer v2); +guint g_str_hash (gconstpointer v); + +gboolean g_int_equal (gconstpointer v1, + gconstpointer v2); +guint g_int_hash (gconstpointer v); + +gboolean g_int64_equal (gconstpointer v1, + gconstpointer v2); +guint g_int64_hash (gconstpointer v); + +gboolean g_double_equal (gconstpointer v1, + gconstpointer v2); +guint g_double_hash (gconstpointer v); + +guint g_direct_hash (gconstpointer v) G_GNUC_CONST; +gboolean g_direct_equal (gconstpointer v1, + gconstpointer v2) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __G_HASH_H__ */ diff --git a/glib/glib/ghmac.c b/glib/glib/ghmac.c new file mode 100644 index 0000000..1da1b7f --- /dev/null +++ b/glib/glib/ghmac.c @@ -0,0 +1,400 @@ +/* ghmac.h - data hashing functions + * + * Copyright (C) 2011 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Stef Walter + */ + +#include "config.h" + +#include + +#include "ghmac.h" + +#include "glib/galloca.h" +#include "gatomic.h" +#include "gslice.h" +#include "gmem.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gtypes.h" +#include "glibintl.h" + + +/** + * SECTION:hmac + * @title: Secure HMAC Digests + * @short_description: computes the HMAC for data + * + * HMACs should be used when producing a cookie or hash based on data + * and a key. Simple mechanisms for using SHA1 and other algorithms to + * digest a key and data together are vulnerable to various security + * issues. HMAC + * uses algorithms like SHA1 in a secure way to produce a digest of a + * key and data. + * + * Both the key and data are arbitrary byte arrays of bytes or characters. + * + * Support for HMAC Digests has been added in GLib 2.30. + */ + +struct _GHmac +{ + int ref_count; + GChecksumType digest_type; + GChecksum *digesti; + GChecksum *digesto; +}; + +/** + * g_hmac_new: + * @digest_type: the desired type of digest + * @key: (array length=key_len): the key for the HMAC + * @key_len: the length of the keys + * + * Creates a new #GHmac, using the digest algorithm @digest_type. + * If the @digest_type is not known, %NULL is returned. + * A #GHmac can be used to compute the HMAC of a key and an + * arbitrary binary blob, using different hashing algorithms. + * + * A #GHmac works by feeding a binary blob through g_hmac_update() + * until the data is complete; the digest can then be extracted + * using g_hmac_get_string(), which will return the checksum as a + * hexadecimal string; or g_hmac_get_digest(), which will return a + * array of raw bytes. Once either g_hmac_get_string() or + * g_hmac_get_digest() have been called on a #GHmac, the HMAC + * will be closed and it won't be possible to call g_hmac_update() + * on it anymore. + * + * Return value: the newly created #GHmac, or %NULL. + * Use g_hmac_unref() to free the memory allocated by it. + * + * Since: 2.30 + */ +GHmac * +g_hmac_new (GChecksumType digest_type, + const guchar *key, + gsize key_len) +{ + GChecksum *checksum; + GHmac *hmac; + guchar *buffer; + guchar *pad; + gsize i, len; + gsize block_size; + + checksum = g_checksum_new (digest_type); + g_return_val_if_fail (checksum != NULL, NULL); + + switch (digest_type) + { + case G_CHECKSUM_MD5: + case G_CHECKSUM_SHA1: + block_size = 64; /* RFC 2104 */ + break; + case G_CHECKSUM_SHA256: + block_size = 64; /* RFC draft-kelly-ipsec-ciph-sha2-01 */ + break; + default: + g_return_val_if_reached (NULL); + } + + hmac = g_slice_new0 (GHmac); + hmac->ref_count = 1; + hmac->digest_type = digest_type; + hmac->digesti = checksum; + hmac->digesto = g_checksum_new (digest_type); + + buffer = g_alloca (block_size); + pad = g_alloca (block_size); + + memset (buffer, 0, block_size); + + /* If the key is too long, hash it */ + if (key_len > block_size) + { + len = block_size; + g_checksum_update (hmac->digesti, key, key_len); + g_checksum_get_digest (hmac->digesti, buffer, &len); + g_checksum_reset (hmac->digesti); + } + + /* Otherwise pad it with zeros */ + else + { + memcpy (buffer, key, key_len); + } + + /* First pad */ + for (i = 0; i < block_size; i++) + pad[i] = 0x36 ^ buffer[i]; /* ipad value */ + g_checksum_update (hmac->digesti, pad, block_size); + + /* Second pad */ + for (i = 0; i < block_size; i++) + pad[i] = 0x5c ^ buffer[i]; /* opad value */ + g_checksum_update (hmac->digesto, pad, block_size); + + return hmac; +} + +/** + * g_hmac_copy: + * @hmac: the #GHmac to copy + * + * Copies a #GHmac. If @hmac has been closed, by calling + * g_hmac_get_string() or g_hmac_get_digest(), the copied + * HMAC will be closed as well. + * + * Return value: the copy of the passed #GHmac. Use g_hmac_unref() + * when finished using it. + * + * Since: 2.30 + */ +GHmac * +g_hmac_copy (const GHmac *hmac) +{ + GHmac *copy; + + g_return_val_if_fail (hmac != NULL, NULL); + + copy = g_slice_new (GHmac); + copy->ref_count = 1; + copy->digest_type = hmac->digest_type; + copy->digesti = g_checksum_copy (hmac->digesti); + copy->digesto = g_checksum_copy (hmac->digesto); + + return copy; +} + +/** + * g_hmac_ref: + * @hmac: a valid #GHmac + * + * Atomically increments the reference count of @hmac by one. + * + * This function is MT-safe and may be called from any thread. + * + * Return value: the passed in #GHmac. + * + * Since: 2.30 + **/ +GHmac * +g_hmac_ref (GHmac *hmac) +{ + g_return_val_if_fail (hmac != NULL, NULL); + + g_atomic_int_inc (&hmac->ref_count); + + return hmac; +} + +/** + * g_hmac_unref: + * @hmac: a #GHmac + * + * Atomically decrements the reference count of @hmac by one. + * + * If the reference count drops to 0, all keys and values will be + * destroyed, and all memory allocated by the hash table is released. + * This function is MT-safe and may be called from any thread. + * Frees the memory allocated for @hmac. + * + * Since: 2.30 + */ +void +g_hmac_unref (GHmac *hmac) +{ + g_return_if_fail (hmac != NULL); + + if (g_atomic_int_dec_and_test (&hmac->ref_count)) + { + g_checksum_free (hmac->digesti); + g_checksum_free (hmac->digesto); + g_slice_free (GHmac, hmac); + } +} + +/** + * g_hmac_update: + * @hmac: a #GHmac + * @data: (array length=length): buffer used to compute the checksum + * @length: size of the buffer, or -1 if it is a nul-terminated string + * + * Feeds @data into an existing #GHmac. + * + * The HMAC must still be open, that is g_hmac_get_string() or + * g_hmac_get_digest() must not have been called on @hmac. + * + * Since: 2.30 + */ +void +g_hmac_update (GHmac *hmac, + const guchar *data, + gssize length) +{ + g_return_if_fail (hmac != NULL); + g_return_if_fail (length == 0 || data != NULL); + + g_checksum_update (hmac->digesti, data, length); +} + +/** + * g_hmac_get_string: + * @hmac: a #GHmac + * + * Gets the HMAC as an hexadecimal string. + * + * Once this function has been called the #GHmac can no longer be + * updated with g_hmac_update(). + * + * The hexadecimal characters will be lower case. + * + * Return value: the hexadecimal representation of the HMAC. The + * returned string is owned by the HMAC and should not be modified + * or freed. + * + * Since: 2.30 + */ +const gchar * +g_hmac_get_string (GHmac *hmac) +{ + guint8 *buffer; + gsize digest_len; + + g_return_val_if_fail (hmac != NULL, NULL); + + digest_len = g_checksum_type_get_length (hmac->digest_type); + buffer = g_alloca (digest_len); + + /* This is only called for its side-effect of updating hmac->digesto... */ + g_hmac_get_digest (hmac, buffer, &digest_len); + /* ... because we get the string from the checksum rather than + * stringifying buffer ourselves + */ + return g_checksum_get_string (hmac->digesto); +} + +/** + * g_hmac_get_digest: + * @hmac: a #GHmac + * @buffer: output buffer + * @digest_len: an inout parameter. The caller initializes it to the + * size of @buffer. After the call it contains the length of the digest + * + * Gets the digest from @checksum as a raw binary array and places it + * into @buffer. The size of the digest depends on the type of checksum. + * + * Once this function has been called, the #GHmac is closed and can + * no longer be updated with g_checksum_update(). + * + * Since: 2.30 + */ +void +g_hmac_get_digest (GHmac *hmac, + guint8 *buffer, + gsize *digest_len) +{ + gsize len; + + g_return_if_fail (hmac != NULL); + + len = g_checksum_type_get_length (hmac->digest_type); + g_return_if_fail (*digest_len >= len); + + /* Use the same buffer, because we can :) */ + g_checksum_get_digest (hmac->digesti, buffer, &len); + g_checksum_update (hmac->digesto, buffer, len); + g_checksum_get_digest (hmac->digesto, buffer, digest_len); +} + +/** + * g_compute_hmac_for_data: + * @digest_type: a #GChecksumType to use for the HMAC + * @key: (array length=key_len): the key to use in the HMAC + * @key_len: the length of the key + * @data: binary blob to compute the HMAC of + * @length: length of @data + * + * Computes the HMAC for a binary @data of @length. This is a + * convenience wrapper for g_hmac_new(), g_hmac_get_string() + * and g_hmac_unref(). + * + * The hexadecimal string returned will be in lower case. + * + * Return value: the HMAC of the binary data as a string in hexadecimal. + * The returned string should be freed with g_free() when done using it. + * + * Since: 2.30 + */ +gchar * +g_compute_hmac_for_data (GChecksumType digest_type, + const guchar *key, + gsize key_len, + const guchar *data, + gsize length) +{ + GHmac *hmac; + gchar *retval; + + g_return_val_if_fail (length == 0 || data != NULL, NULL); + + hmac = g_hmac_new (digest_type, key, key_len); + if (!hmac) + return NULL; + + g_hmac_update (hmac, data, length); + retval = g_strdup (g_hmac_get_string (hmac)); + g_hmac_unref (hmac); + + return retval; +} + +/** + * g_compute_hmac_for_string: + * @digest_type: a #GChecksumType to use for the HMAC + * @key: (array length=key_len): the key to use in the HMAC + * @key_len: the length of the key + * @str: the string to compute the HMAC for + * @length: the length of the string, or -1 if the string is nul-terminated + * + * Computes the HMAC for a string. + * + * The hexadecimal string returned will be in lower case. + * + * Return value: the HMAC as a hexadecimal string. + * The returned string should be freed with g_free() + * when done using it. + * + * Since: 2.30 + */ +gchar * +g_compute_hmac_for_string (GChecksumType digest_type, + const guchar *key, + gsize key_len, + const gchar *str, + gssize length) +{ + g_return_val_if_fail (length == 0 || str != NULL, NULL); + + if (length < 0) + length = strlen (str); + + return g_compute_hmac_for_data (digest_type, key, key_len, + (const guchar *) str, length); +} diff --git a/glib/glib/ghmac.h b/glib/glib/ghmac.h new file mode 100644 index 0000000..e9b57de --- /dev/null +++ b/glib/glib/ghmac.h @@ -0,0 +1,71 @@ +/* ghmac.h - secure data hashing + * + * Copyright (C) 2011 Stef Walter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_HMAC_H__ +#define __G_HMAC_H__ + +#include +#include "gchecksum.h" + +G_BEGIN_DECLS + +/** + * GHmac: + * + * An opaque structure representing a HMAC operation. + * To create a new GHmac, use g_hmac_new(). To free + * a GHmac, use g_hmac_unref(). + * + * Since: 2.30 + */ +typedef struct _GHmac GHmac; + +GHmac * g_hmac_new (GChecksumType digest_type, + const guchar *key, + gsize key_len); +GHmac * g_hmac_copy (const GHmac *hmac); +GHmac * g_hmac_ref (GHmac *hmac); +void g_hmac_unref (GHmac *hmac); +void g_hmac_update (GHmac *hmac, + const guchar *data, + gssize length); +const gchar * g_hmac_get_string (GHmac *hmac); +void g_hmac_get_digest (GHmac *hmac, + guint8 *buffer, + gsize *digest_len); + +gchar *g_compute_hmac_for_data (GChecksumType digest_type, + const guchar *key, + gsize key_len, + const guchar *data, + gsize length); +gchar *g_compute_hmac_for_string (GChecksumType digest_type, + const guchar *key, + gsize key_len, + const gchar *str, + gssize length); + +G_END_DECLS + +#endif /* __G_CHECKSUM_H__ */ diff --git a/glib/glib/ghook.c b/glib/glib/ghook.c new file mode 100644 index 0000000..93ea846 --- /dev/null +++ b/glib/glib/ghook.c @@ -0,0 +1,1054 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GHook: Callback maintenance functions + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "ghook.h" + +#include "gtestutils.h" +#include "gslice.h" + +/** + * SECTION:hooks + * @title: Hook Functions + * @short_description: support for manipulating lists of hook functions + * + * The #GHookList, #GHook and their related functions provide support for + * lists of hook functions. Functions can be added and removed from the lists, + * and the list of hook functions can be invoked. + */ + +/** + * GHookList: + * @seq_id: the next free #GHook id + * @hook_size: the size of the #GHookList elements, in bytes + * @is_setup: 1 if the #GHookList has been initialized + * @hooks: the first #GHook element in the list + * @dummy3: unused + * @finalize_hook: the function to call to finalize a #GHook element. + * The default behaviour is to call the hooks @destroy function + * @dummy: unused + * + * The GHookList struct represents a + * list of hook functions. + */ + +/** + * GHookFinalizeFunc: + * @hook_list: a #GHookList + * @hook: the hook in @hook_list that gets finalized + * + * Defines the type of function to be called when a hook in a + * list of hooks gets finalized. + */ + +/** + * GHookFlagMask: + * @G_HOOK_FLAG_ACTIVE: set if the hook has not been destroyed + * @G_HOOK_FLAG_IN_CALL: set if the hook is currently being run + * @G_HOOK_FLAG_MASK: A mask covering all bits reserved for + * hook flags; see %G_HOOK_FLAG_USER_SHIFT + * + * Flags used internally in the #GHook implementation. + */ + +/** + * G_HOOK_FLAGS: + * @hook: a #GHook + * + * Gets the flags of a hook. + */ + +/** + * G_HOOK_FLAG_USER_SHIFT: + * + * The position of the first bit which is not reserved for internal + * use be the #GHook implementation, i.e. + * 1 << G_HOOK_FLAG_USER_SHIFT is the first + * bit which can be used for application-defined flags. + */ + +/** + * G_HOOK: + * @hook: a pointer + * + * Casts a pointer to a GHook*. + */ + +/** + * G_HOOK_IS_VALID: + * @hook: a #GHook + * + * Returns %TRUE if the #GHook is valid, i.e. it is in a #GHookList, + * it is active and it has not been destroyed. + * + * Returns: %TRUE if the #GHook is valid + */ + +/** + * G_HOOK_ACTIVE: + * @hook: a #GHook + * + * Returns %TRUE if the #GHook is active, which is normally the case + * until the #GHook is destroyed. + * + * Returns: %TRUE if the #GHook is active + */ + +/** + * G_HOOK_IN_CALL: + * @hook: a #GHook + * + * Returns %TRUE if the #GHook function is currently executing. + * + * Returns: %TRUE if the #GHook function is currently executing + */ + +/** + * G_HOOK_IS_UNLINKED: + * @hook: a #GHook + * + * Returns %TRUE if the #GHook is not in a #GHookList. + + * Returns: %TRUE if the #GHook is not in a #GHookList + */ + +/** + * GHook: + * @data: data which is passed to func when this hook is invoked + * @next: pointer to the next hook in the list + * @prev: pointer to the previous hook in the list + * @ref_count: the reference count of this hook + * @hook_id: the id of this hook, which is unique within its list + * @flags: flags which are set for this hook. See #GHookFlagMask for + * predefined flags + * @func: the function to call when this hook is invoked. The possible + * signatures for this function are #GHookFunc and #GHookCheckFunc + * @destroy: the default @finalize_hook function of a #GHookList calls + * this member of the hook that is being finalized + * + * The GHook struct represents a single hook + * function in a #GHookList. + */ + +/** + * GHookFunc: + * @data: the data field of the #GHook is passed to the hook function here + * + * Defines the type of a hook function that can be invoked + * by g_hook_list_invoke(). + */ + +/** + * GHookCheckFunc: + * @data: the data field of the #GHook is passed to the hook function here + * + * Defines the type of a hook function that can be invoked + * by g_hook_list_invoke_check(). + * + * Returns: %FALSE if the #GHook should be destroyed + */ + +/* --- functions --- */ +static void +default_finalize_hook (GHookList *hook_list, + GHook *hook) +{ + GDestroyNotify destroy = hook->destroy; + + if (destroy) + { + hook->destroy = NULL; + destroy (hook->data); + } +} + +/** + * g_hook_list_init: + * @hook_list: a #GHookList + * @hook_size: the size of each element in the #GHookList, + * typically sizeof (GHook) + * + * Initializes a #GHookList. + * This must be called before the #GHookList is used. + */ +void +g_hook_list_init (GHookList *hook_list, + guint hook_size) +{ + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook_size >= sizeof (GHook)); + + hook_list->seq_id = 1; + hook_list->hook_size = hook_size; + hook_list->is_setup = TRUE; + hook_list->hooks = NULL; + hook_list->dummy3 = NULL; + hook_list->finalize_hook = default_finalize_hook; + hook_list->dummy[0] = NULL; + hook_list->dummy[1] = NULL; +} + +/** + * g_hook_list_clear: + * @hook_list: a #GHookList + * + * Removes all the #GHook elements from a #GHookList. + */ +void +g_hook_list_clear (GHookList *hook_list) +{ + g_return_if_fail (hook_list != NULL); + + if (hook_list->is_setup) + { + GHook *hook; + + hook_list->is_setup = FALSE; + + hook = hook_list->hooks; + if (!hook) + { + /* destroy hook_list->hook_memchunk */ + } + else + do + { + GHook *tmp; + + g_hook_ref (hook_list, hook); + g_hook_destroy_link (hook_list, hook); + tmp = hook->next; + g_hook_unref (hook_list, hook); + hook = tmp; + } + while (hook); + } +} + +/** + * g_hook_alloc: + * @hook_list: a #GHookList + * + * Allocates space for a #GHook and initializes it. + * + * Returns: a new #GHook + */ +GHook* +g_hook_alloc (GHookList *hook_list) +{ + GHook *hook; + + g_return_val_if_fail (hook_list != NULL, NULL); + g_return_val_if_fail (hook_list->is_setup, NULL); + + hook = g_slice_alloc0 (hook_list->hook_size); + hook->data = NULL; + hook->next = NULL; + hook->prev = NULL; + hook->flags = G_HOOK_FLAG_ACTIVE; + hook->ref_count = 0; + hook->hook_id = 0; + hook->func = NULL; + hook->destroy = NULL; + + return hook; +} +/** + * g_hook_free: + * @hook_list: a #GHookList + * @hook: the #GHook to free + * + * Calls the #GHookList @finalize_hook function if it exists, + * and frees the memory allocated for the #GHook. + */ +void +g_hook_free (GHookList *hook_list, + GHook *hook) +{ + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook_list->is_setup); + g_return_if_fail (hook != NULL); + g_return_if_fail (G_HOOK_IS_UNLINKED (hook)); + g_return_if_fail (!G_HOOK_IN_CALL (hook)); + + if(hook_list->finalize_hook != NULL) + hook_list->finalize_hook (hook_list, hook); + g_slice_free1 (hook_list->hook_size, hook); +} + +/** + * g_hook_destroy_link: + * @hook_list: a #GHookList + * @hook: the #GHook to remove + * + * Removes one #GHook from a #GHookList, marking it + * inactive and calling g_hook_unref() on it. + */ +void +g_hook_destroy_link (GHookList *hook_list, + GHook *hook) +{ + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook != NULL); + + hook->flags &= ~G_HOOK_FLAG_ACTIVE; + if (hook->hook_id) + { + hook->hook_id = 0; + g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */ + } +} + +/** + * g_hook_destroy: + * @hook_list: a #GHookList + * @hook_id: a hook ID + * + * Destroys a #GHook, given its ID. + * + * Returns: %TRUE if the #GHook was found in the #GHookList and destroyed + */ +gboolean +g_hook_destroy (GHookList *hook_list, + gulong hook_id) +{ + GHook *hook; + + g_return_val_if_fail (hook_list != NULL, FALSE); + g_return_val_if_fail (hook_id > 0, FALSE); + + hook = g_hook_get (hook_list, hook_id); + if (hook) + { + g_hook_destroy_link (hook_list, hook); + return TRUE; + } + + return FALSE; +} + +/** + * g_hook_unref: + * @hook_list: a #GHookList + * @hook: the #GHook to unref + * + * Decrements the reference count of a #GHook. + * If the reference count falls to 0, the #GHook is removed + * from the #GHookList and g_hook_free() is called to free it. + */ +void +g_hook_unref (GHookList *hook_list, + GHook *hook) +{ + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook != NULL); + g_return_if_fail (hook->ref_count > 0); + + hook->ref_count--; + if (!hook->ref_count) + { + g_return_if_fail (hook->hook_id == 0); + g_return_if_fail (!G_HOOK_IN_CALL (hook)); + + if (hook->prev) + hook->prev->next = hook->next; + else + hook_list->hooks = hook->next; + if (hook->next) + { + hook->next->prev = hook->prev; + hook->next = NULL; + } + hook->prev = NULL; + + if (!hook_list->is_setup) + { + hook_list->is_setup = TRUE; + g_hook_free (hook_list, hook); + hook_list->is_setup = FALSE; + + if (!hook_list->hooks) + { + /* destroy hook_list->hook_memchunk */ + } + } + else + g_hook_free (hook_list, hook); + } +} + +/** + * g_hook_ref: + * @hook_list: a #GHookList + * @hook: the #GHook to increment the reference count of + * + * Increments the reference count for a #GHook. + * + * Returns: the @hook that was passed in (since 2.6) + */ +GHook * +g_hook_ref (GHookList *hook_list, + GHook *hook) +{ + g_return_val_if_fail (hook_list != NULL, NULL); + g_return_val_if_fail (hook != NULL, NULL); + g_return_val_if_fail (hook->ref_count > 0, NULL); + + hook->ref_count++; + + return hook; +} + +/** + * g_hook_append: + * @hook_list: a #GHookList + * @hook: the #GHook to add to the end of @hook_list + * + * Appends a #GHook onto the end of a #GHookList. + */ + +/** + * g_hook_prepend: + * @hook_list: a #GHookList + * @hook: the #GHook to add to the start of @hook_list + * + * Prepends a #GHook on the start of a #GHookList. + */ +void +g_hook_prepend (GHookList *hook_list, + GHook *hook) +{ + g_return_if_fail (hook_list != NULL); + + g_hook_insert_before (hook_list, hook_list->hooks, hook); +} + +/** + * g_hook_insert_before: + * @hook_list: a #GHookList + * @sibling: the #GHook to insert the new #GHook before + * @hook: the #GHook to insert + * + * Inserts a #GHook into a #GHookList, before a given #GHook. + */ +void +g_hook_insert_before (GHookList *hook_list, + GHook *sibling, + GHook *hook) +{ + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook_list->is_setup); + g_return_if_fail (hook != NULL); + g_return_if_fail (G_HOOK_IS_UNLINKED (hook)); + g_return_if_fail (hook->ref_count == 0); + + hook->hook_id = hook_list->seq_id++; + hook->ref_count = 1; /* counterpart to g_hook_destroy_link */ + + if (sibling) + { + if (sibling->prev) + { + hook->prev = sibling->prev; + hook->prev->next = hook; + hook->next = sibling; + sibling->prev = hook; + } + else + { + hook_list->hooks = hook; + hook->next = sibling; + sibling->prev = hook; + } + } + else + { + if (hook_list->hooks) + { + sibling = hook_list->hooks; + while (sibling->next) + sibling = sibling->next; + hook->prev = sibling; + sibling->next = hook; + } + else + hook_list->hooks = hook; + } +} + +/** + * g_hook_list_invoke: + * @hook_list: a #GHookList + * @may_recurse: %TRUE if functions which are already running + * (e.g. in another thread) can be called. If set to %FALSE, + * these are skipped + * + * Calls all of the #GHook functions in a #GHookList. + */ +void +g_hook_list_invoke (GHookList *hook_list, + gboolean may_recurse) +{ + GHook *hook; + + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook_list->is_setup); + + hook = g_hook_first_valid (hook_list, may_recurse); + while (hook) + { + GHookFunc func; + gboolean was_in_call; + + func = (GHookFunc) hook->func; + + was_in_call = G_HOOK_IN_CALL (hook); + hook->flags |= G_HOOK_FLAG_IN_CALL; + func (hook->data); + if (!was_in_call) + hook->flags &= ~G_HOOK_FLAG_IN_CALL; + + hook = g_hook_next_valid (hook_list, hook, may_recurse); + } +} + +/** + * g_hook_list_invoke_check: + * @hook_list: a #GHookList + * @may_recurse: %TRUE if functions which are already running + * (e.g. in another thread) can be called. If set to %FALSE, + * these are skipped + * + * Calls all of the #GHook functions in a #GHookList. + * Any function which returns %FALSE is removed from the #GHookList. + */ +void +g_hook_list_invoke_check (GHookList *hook_list, + gboolean may_recurse) +{ + GHook *hook; + + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook_list->is_setup); + + hook = g_hook_first_valid (hook_list, may_recurse); + while (hook) + { + GHookCheckFunc func; + gboolean was_in_call; + gboolean need_destroy; + + func = (GHookCheckFunc) hook->func; + + was_in_call = G_HOOK_IN_CALL (hook); + hook->flags |= G_HOOK_FLAG_IN_CALL; + need_destroy = !func (hook->data); + if (!was_in_call) + hook->flags &= ~G_HOOK_FLAG_IN_CALL; + if (need_destroy) + g_hook_destroy_link (hook_list, hook); + + hook = g_hook_next_valid (hook_list, hook, may_recurse); + } +} + +/** + * GHookCheckMarshaller: + * @hook: a #GHook + * @marshal_data: user data + * + * Defines the type of function used by g_hook_list_marshal_check(). + * + * Returns: %FALSE if @hook should be destroyed + */ + +/** + * g_hook_list_marshal_check: + * @hook_list: a #GHookList + * @may_recurse: %TRUE if hooks which are currently running + * (e.g. in another thread) are considered valid. If set to %FALSE, + * these are skipped + * @marshaller: the function to call for each #GHook + * @marshal_data: data to pass to @marshaller + * + * Calls a function on each valid #GHook and destroys it if the + * function returns %FALSE. + */ +void +g_hook_list_marshal_check (GHookList *hook_list, + gboolean may_recurse, + GHookCheckMarshaller marshaller, + gpointer data) +{ + GHook *hook; + + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook_list->is_setup); + g_return_if_fail (marshaller != NULL); + + hook = g_hook_first_valid (hook_list, may_recurse); + while (hook) + { + gboolean was_in_call; + gboolean need_destroy; + + was_in_call = G_HOOK_IN_CALL (hook); + hook->flags |= G_HOOK_FLAG_IN_CALL; + need_destroy = !marshaller (hook, data); + if (!was_in_call) + hook->flags &= ~G_HOOK_FLAG_IN_CALL; + if (need_destroy) + g_hook_destroy_link (hook_list, hook); + + hook = g_hook_next_valid (hook_list, hook, may_recurse); + } +} + +/** + * GHookMarshaller: + * @hook: a #GHook + * @marshal_data: user data + * + * Defines the type of function used by g_hook_list_marshal(). + */ + +/** + * g_hook_list_marshal: + * @hook_list: a #GHookList + * @may_recurse: %TRUE if hooks which are currently running + * (e.g. in another thread) are considered valid. If set to %FALSE, + * these are skipped + * @marshaller: the function to call for each #GHook + * @marshal_data: data to pass to @marshaller + * + * Calls a function on each valid #GHook. + */ +void +g_hook_list_marshal (GHookList *hook_list, + gboolean may_recurse, + GHookMarshaller marshaller, + gpointer data) +{ + GHook *hook; + + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook_list->is_setup); + g_return_if_fail (marshaller != NULL); + + hook = g_hook_first_valid (hook_list, may_recurse); + while (hook) + { + gboolean was_in_call; + + was_in_call = G_HOOK_IN_CALL (hook); + hook->flags |= G_HOOK_FLAG_IN_CALL; + marshaller (hook, data); + if (!was_in_call) + hook->flags &= ~G_HOOK_FLAG_IN_CALL; + + hook = g_hook_next_valid (hook_list, hook, may_recurse); + } +} + +/** + * g_hook_first_valid: + * @hook_list: a #GHookList + * @may_be_in_call: %TRUE if hooks which are currently running + * (e.g. in another thread) are considered valid. If set to %FALSE, + * these are skipped + * + * Returns the first #GHook in a #GHookList which has not been destroyed. + * The reference count for the #GHook is incremented, so you must call + * g_hook_unref() to restore it when no longer needed. (Or call + * g_hook_next_valid() if you are stepping through the #GHookList.) + * + * Returns: the first valid #GHook, or %NULL if none are valid + */ +GHook* +g_hook_first_valid (GHookList *hook_list, + gboolean may_be_in_call) +{ + g_return_val_if_fail (hook_list != NULL, NULL); + + if (hook_list->is_setup) + { + GHook *hook; + + hook = hook_list->hooks; + if (hook) + { + g_hook_ref (hook_list, hook); + if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook))) + return hook; + else + return g_hook_next_valid (hook_list, hook, may_be_in_call); + } + } + + return NULL; +} + +/** + * g_hook_next_valid: + * @hook_list: a #GHookList + * @hook: the current #GHook + * @may_be_in_call: %TRUE if hooks which are currently running + * (e.g. in another thread) are considered valid. If set to %FALSE, + * these are skipped + * + * Returns the next #GHook in a #GHookList which has not been destroyed. + * The reference count for the #GHook is incremented, so you must call + * g_hook_unref() to restore it when no longer needed. (Or continue to call + * g_hook_next_valid() until %NULL is returned.) + * + * Returns: the next valid #GHook, or %NULL if none are valid + */ +GHook* +g_hook_next_valid (GHookList *hook_list, + GHook *hook, + gboolean may_be_in_call) +{ + GHook *ohook = hook; + + g_return_val_if_fail (hook_list != NULL, NULL); + + if (!hook) + return NULL; + + hook = hook->next; + while (hook) + { + if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook))) + { + g_hook_ref (hook_list, hook); + g_hook_unref (hook_list, ohook); + + return hook; + } + hook = hook->next; + } + g_hook_unref (hook_list, ohook); + + return NULL; +} + +/** + * g_hook_get: + * @hook_list: a #GHookList + * @hook_id: a hook id + * + * Returns the #GHook with the given id, or %NULL if it is not found. + * + * Returns: the #GHook with the given id, or %NULL if it is not found + */ +GHook* +g_hook_get (GHookList *hook_list, + gulong hook_id) +{ + GHook *hook; + + g_return_val_if_fail (hook_list != NULL, NULL); + g_return_val_if_fail (hook_id > 0, NULL); + + hook = hook_list->hooks; + while (hook) + { + if (hook->hook_id == hook_id) + return hook; + hook = hook->next; + } + + return NULL; +} + +/** + * GHookFindFunc: + * @hook: a #GHook + * @data: user data passed to g_hook_find_func() + * + * Defines the type of the function passed to g_hook_find(). + * + * Returns: %TRUE if the required #GHook has been found + */ + +/** + * g_hook_find: + * @hook_list: a #GHookList + * @need_valids: %TRUE if #GHook elements which have been destroyed + * should be skipped + * @func: the function to call for each #GHook, which should return + * %TRUE when the #GHook has been found + * @data: the data to pass to @func + * + * Finds a #GHook in a #GHookList using the given function to + * test for a match. + * + * Returns: the found #GHook or %NULL if no matching #GHook is found + */ +GHook* +g_hook_find (GHookList *hook_list, + gboolean need_valids, + GHookFindFunc func, + gpointer data) +{ + GHook *hook; + + g_return_val_if_fail (hook_list != NULL, NULL); + g_return_val_if_fail (func != NULL, NULL); + + hook = hook_list->hooks; + while (hook) + { + GHook *tmp; + + /* test only non-destroyed hooks */ + if (!hook->hook_id) + { + hook = hook->next; + continue; + } + + g_hook_ref (hook_list, hook); + + if (func (hook, data) && hook->hook_id && (!need_valids || G_HOOK_ACTIVE (hook))) + { + g_hook_unref (hook_list, hook); + + return hook; + } + + tmp = hook->next; + g_hook_unref (hook_list, hook); + hook = tmp; + } + + return NULL; +} + +/** + * g_hook_find_data: + * @hook_list: a #GHookList + * @need_valids: %TRUE if #GHook elements which have been destroyed + * should be skipped + * @data: the data to find + * + * Finds a #GHook in a #GHookList with the given data. + * + * Returns: the #GHook with the given @data or %NULL if no matching + * #GHook is found + */ +GHook* +g_hook_find_data (GHookList *hook_list, + gboolean need_valids, + gpointer data) +{ + GHook *hook; + + g_return_val_if_fail (hook_list != NULL, NULL); + + hook = hook_list->hooks; + while (hook) + { + /* test only non-destroyed hooks */ + if (hook->data == data && + hook->hook_id && + (!need_valids || G_HOOK_ACTIVE (hook))) + return hook; + + hook = hook->next; + } + + return NULL; +} + +/** + * g_hook_find_func: + * @hook_list: a #GHookList + * @need_valids: %TRUE if #GHook elements which have been destroyed + * should be skipped + * @func: the function to find + * + * Finds a #GHook in a #GHookList with the given function. + * + * Returns: the #GHook with the given @func or %NULL if no matching + * #GHook is found + */ +GHook* +g_hook_find_func (GHookList *hook_list, + gboolean need_valids, + gpointer func) +{ + GHook *hook; + + g_return_val_if_fail (hook_list != NULL, NULL); + g_return_val_if_fail (func != NULL, NULL); + + hook = hook_list->hooks; + while (hook) + { + /* test only non-destroyed hooks */ + if (hook->func == func && + hook->hook_id && + (!need_valids || G_HOOK_ACTIVE (hook))) + return hook; + + hook = hook->next; + } + + return NULL; +} + +/** + * g_hook_find_func_data: + * @hook_list: a #GHookList + * @need_valids: %TRUE if #GHook elements which have been destroyed + * should be skipped + * @func: the function to find + * @data: the data to find + * + * Finds a #GHook in a #GHookList with the given function and data. + * + * Returns: the #GHook with the given @func and @data or %NULL if + * no matching #GHook is found + */ +GHook* +g_hook_find_func_data (GHookList *hook_list, + gboolean need_valids, + gpointer func, + gpointer data) +{ + GHook *hook; + + g_return_val_if_fail (hook_list != NULL, NULL); + g_return_val_if_fail (func != NULL, NULL); + + hook = hook_list->hooks; + while (hook) + { + /* test only non-destroyed hooks */ + if (hook->data == data && + hook->func == func && + hook->hook_id && + (!need_valids || G_HOOK_ACTIVE (hook))) + return hook; + + hook = hook->next; + } + + return NULL; +} + +/** + * GHookCompareFunc: + * @new_hook: the #GHook being inserted + * @sibling: the #GHook to compare with @new_hook + * + * Defines the type of function used to compare #GHook elements in + * g_hook_insert_sorted(). + * + * Returns: a value <= 0 if @new_hook should be before @sibling + */ + +/** + * g_hook_insert_sorted: + * @hook_list: a #GHookList + * @hook: the #GHook to insert + * @func: the comparison function used to sort the #GHook elements + * + * Inserts a #GHook into a #GHookList, sorted by the given function. + */ +void +g_hook_insert_sorted (GHookList *hook_list, + GHook *hook, + GHookCompareFunc func) +{ + GHook *sibling; + + g_return_if_fail (hook_list != NULL); + g_return_if_fail (hook_list->is_setup); + g_return_if_fail (hook != NULL); + g_return_if_fail (G_HOOK_IS_UNLINKED (hook)); + g_return_if_fail (hook->func != NULL); + g_return_if_fail (func != NULL); + + /* first non-destroyed hook */ + sibling = hook_list->hooks; + while (sibling && !sibling->hook_id) + sibling = sibling->next; + + while (sibling) + { + GHook *tmp; + + g_hook_ref (hook_list, sibling); + if (func (hook, sibling) <= 0 && sibling->hook_id) + { + g_hook_unref (hook_list, sibling); + break; + } + + /* next non-destroyed hook */ + tmp = sibling->next; + while (tmp && !tmp->hook_id) + tmp = tmp->next; + + g_hook_unref (hook_list, sibling); + sibling = tmp; + + } + + g_hook_insert_before (hook_list, sibling, hook); +} + +/** + * g_hook_compare_ids: + * @new_hook: a #GHook + * @sibling: a #GHook to compare with @new_hook + * + * Compares the ids of two #GHook elements, returning a negative value + * if the second id is greater than the first. + * + * Returns: a value <= 0 if the id of @sibling is >= the id of @new_hook + */ +gint +g_hook_compare_ids (GHook *new_hook, + GHook *sibling) +{ + if (new_hook->hook_id < sibling->hook_id) + return -1; + else if (new_hook->hook_id > sibling->hook_id) + return 1; + + return 0; +} diff --git a/glib/glib/ghook.h b/glib/glib/ghook.h new file mode 100644 index 0000000..e7292ea --- /dev/null +++ b/glib/glib/ghook.h @@ -0,0 +1,181 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_HOOK_H__ +#define __G_HOOK_H__ + +#include + +G_BEGIN_DECLS + + +/* --- typedefs --- */ +typedef struct _GHook GHook; +typedef struct _GHookList GHookList; + +typedef gint (*GHookCompareFunc) (GHook *new_hook, + GHook *sibling); +typedef gboolean (*GHookFindFunc) (GHook *hook, + gpointer data); +typedef void (*GHookMarshaller) (GHook *hook, + gpointer marshal_data); +typedef gboolean (*GHookCheckMarshaller) (GHook *hook, + gpointer marshal_data); +typedef void (*GHookFunc) (gpointer data); +typedef gboolean (*GHookCheckFunc) (gpointer data); +typedef void (*GHookFinalizeFunc) (GHookList *hook_list, + GHook *hook); +typedef enum +{ + G_HOOK_FLAG_ACTIVE = 1 << 0, + G_HOOK_FLAG_IN_CALL = 1 << 1, + G_HOOK_FLAG_MASK = 0x0f +} GHookFlagMask; +#define G_HOOK_FLAG_USER_SHIFT (4) + + +/* --- structures --- */ +struct _GHookList +{ + gulong seq_id; + guint hook_size : 16; + guint is_setup : 1; + GHook *hooks; + gpointer dummy3; + GHookFinalizeFunc finalize_hook; + gpointer dummy[2]; +}; +struct _GHook +{ + gpointer data; + GHook *next; + GHook *prev; + guint ref_count; + gulong hook_id; + guint flags; + gpointer func; + GDestroyNotify destroy; +}; + + +/* --- macros --- */ +#define G_HOOK(hook) ((GHook*) (hook)) +#define G_HOOK_FLAGS(hook) (G_HOOK (hook)->flags) +#define G_HOOK_ACTIVE(hook) ((G_HOOK_FLAGS (hook) & \ + G_HOOK_FLAG_ACTIVE) != 0) +#define G_HOOK_IN_CALL(hook) ((G_HOOK_FLAGS (hook) & \ + G_HOOK_FLAG_IN_CALL) != 0) +#define G_HOOK_IS_VALID(hook) (G_HOOK (hook)->hook_id != 0 && \ + (G_HOOK_FLAGS (hook) & \ + G_HOOK_FLAG_ACTIVE)) +#define G_HOOK_IS_UNLINKED(hook) (G_HOOK (hook)->next == NULL && \ + G_HOOK (hook)->prev == NULL && \ + G_HOOK (hook)->hook_id == 0 && \ + G_HOOK (hook)->ref_count == 0) + + +/* --- prototypes --- */ +/* callback maintenance functions */ +void g_hook_list_init (GHookList *hook_list, + guint hook_size); +void g_hook_list_clear (GHookList *hook_list); +GHook* g_hook_alloc (GHookList *hook_list); +void g_hook_free (GHookList *hook_list, + GHook *hook); +GHook * g_hook_ref (GHookList *hook_list, + GHook *hook); +void g_hook_unref (GHookList *hook_list, + GHook *hook); +gboolean g_hook_destroy (GHookList *hook_list, + gulong hook_id); +void g_hook_destroy_link (GHookList *hook_list, + GHook *hook); +void g_hook_prepend (GHookList *hook_list, + GHook *hook); +void g_hook_insert_before (GHookList *hook_list, + GHook *sibling, + GHook *hook); +void g_hook_insert_sorted (GHookList *hook_list, + GHook *hook, + GHookCompareFunc func); +GHook* g_hook_get (GHookList *hook_list, + gulong hook_id); +GHook* g_hook_find (GHookList *hook_list, + gboolean need_valids, + GHookFindFunc func, + gpointer data); +GHook* g_hook_find_data (GHookList *hook_list, + gboolean need_valids, + gpointer data); +GHook* g_hook_find_func (GHookList *hook_list, + gboolean need_valids, + gpointer func); +GHook* g_hook_find_func_data (GHookList *hook_list, + gboolean need_valids, + gpointer func, + gpointer data); +/* return the first valid hook, and increment its reference count */ +GHook* g_hook_first_valid (GHookList *hook_list, + gboolean may_be_in_call); +/* return the next valid hook with incremented reference count, and + * decrement the reference count of the original hook + */ +GHook* g_hook_next_valid (GHookList *hook_list, + GHook *hook, + gboolean may_be_in_call); +/* GHookCompareFunc implementation to insert hooks sorted by their id */ +gint g_hook_compare_ids (GHook *new_hook, + GHook *sibling); +/* convenience macros */ +#define g_hook_append( hook_list, hook ) \ + g_hook_insert_before ((hook_list), NULL, (hook)) +/* invoke all valid hooks with the (*GHookFunc) signature. + */ +void g_hook_list_invoke (GHookList *hook_list, + gboolean may_recurse); +/* invoke all valid hooks with the (*GHookCheckFunc) signature, + * and destroy the hook if FALSE is returned. + */ +void g_hook_list_invoke_check (GHookList *hook_list, + gboolean may_recurse); +/* invoke a marshaller on all valid hooks. + */ +void g_hook_list_marshal (GHookList *hook_list, + gboolean may_recurse, + GHookMarshaller marshaller, + gpointer marshal_data); +void g_hook_list_marshal_check (GHookList *hook_list, + gboolean may_recurse, + GHookCheckMarshaller marshaller, + gpointer marshal_data); + +G_END_DECLS + +#endif /* __G_HOOK_H__ */ diff --git a/glib/glib/ghostutils.c b/glib/glib/ghostutils.c new file mode 100644 index 0000000..99afe9a --- /dev/null +++ b/glib/glib/ghostutils.c @@ -0,0 +1,800 @@ +/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ + +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "ghostutils.h" + +#include "garray.h" +#include "gmem.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "glibintl.h" + + +/** + * SECTION:ghostutils + * @short_description: Internet hostname utilities + * + * Functions for manipulating internet hostnames; in particular, for + * converting between Unicode and ASCII-encoded forms of + * Internationalized Domain Names (IDNs). + * + * The Internationalized Domain + * Names for Applications (IDNA) standards allow for the use + * of Unicode domain names in applications, while providing + * backward-compatibility with the old ASCII-only DNS, by defining an + * ASCII-Compatible Encoding of any given Unicode name, which can be + * used with non-IDN-aware applications and protocols. (For example, + * "Παν語.org" maps to "xn--4wa8awb4637h.org".) + **/ + +#define IDNA_ACE_PREFIX "xn--" +#define IDNA_ACE_PREFIX_LEN 4 + +/* Punycode constants, from RFC 3492. */ + +#define PUNYCODE_BASE 36 +#define PUNYCODE_TMIN 1 +#define PUNYCODE_TMAX 26 +#define PUNYCODE_SKEW 38 +#define PUNYCODE_DAMP 700 +#define PUNYCODE_INITIAL_BIAS 72 +#define PUNYCODE_INITIAL_N 0x80 + +#define PUNYCODE_IS_BASIC(cp) ((guint)(cp) < 0x80) + +/* Encode/decode a single base-36 digit */ +static inline gchar +encode_digit (guint dig) +{ + if (dig < 26) + return dig + 'a'; + else + return dig - 26 + '0'; +} + +static inline guint +decode_digit (gchar dig) +{ + if (dig >= 'A' && dig <= 'Z') + return dig - 'A'; + else if (dig >= 'a' && dig <= 'z') + return dig - 'a'; + else if (dig >= '0' && dig <= '9') + return dig - '0' + 26; + else + return G_MAXUINT; +} + +/* Punycode bias adaptation algorithm, RFC 3492 section 6.1 */ +static guint +adapt (guint delta, + guint numpoints, + gboolean firsttime) +{ + guint k; + + delta = firsttime ? delta / PUNYCODE_DAMP : delta / 2; + delta += delta / numpoints; + + k = 0; + while (delta > ((PUNYCODE_BASE - PUNYCODE_TMIN) * PUNYCODE_TMAX) / 2) + { + delta /= PUNYCODE_BASE - PUNYCODE_TMIN; + k += PUNYCODE_BASE; + } + + return k + ((PUNYCODE_BASE - PUNYCODE_TMIN + 1) * delta / + (delta + PUNYCODE_SKEW)); +} + +/* Punycode encoder, RFC 3492 section 6.3. The algorithm is + * sufficiently bizarre that it's not really worth trying to explain + * here. + */ +static gboolean +punycode_encode (const gchar *input_utf8, + gsize input_utf8_length, + GString *output) +{ + guint delta, handled_chars, num_basic_chars, bias, j, q, k, t, digit; + gunichar n, m, *input; + glong input_length; + gboolean success = FALSE; + + /* Convert from UTF-8 to Unicode code points */ + input = g_utf8_to_ucs4 (input_utf8, input_utf8_length, NULL, + &input_length, NULL); + if (!input) + return FALSE; + + /* Copy basic chars */ + for (j = num_basic_chars = 0; j < input_length; j++) + { + if (PUNYCODE_IS_BASIC (input[j])) + { + g_string_append_c (output, g_ascii_tolower (input[j])); + num_basic_chars++; + } + } + if (num_basic_chars) + g_string_append_c (output, '-'); + + handled_chars = num_basic_chars; + + /* Encode non-basic chars */ + delta = 0; + bias = PUNYCODE_INITIAL_BIAS; + n = PUNYCODE_INITIAL_N; + while (handled_chars < input_length) + { + /* let m = the minimum {non-basic} code point >= n in the input */ + for (m = G_MAXUINT, j = 0; j < input_length; j++) + { + if (input[j] >= n && input[j] < m) + m = input[j]; + } + + if (m - n > (G_MAXUINT - delta) / (handled_chars + 1)) + goto fail; + delta += (m - n) * (handled_chars + 1); + n = m; + + for (j = 0; j < input_length; j++) + { + if (input[j] < n) + { + if (++delta == 0) + goto fail; + } + else if (input[j] == n) + { + q = delta; + for (k = PUNYCODE_BASE; ; k += PUNYCODE_BASE) + { + if (k <= bias) + t = PUNYCODE_TMIN; + else if (k >= bias + PUNYCODE_TMAX) + t = PUNYCODE_TMAX; + else + t = k - bias; + if (q < t) + break; + digit = t + (q - t) % (PUNYCODE_BASE - t); + g_string_append_c (output, encode_digit (digit)); + q = (q - t) / (PUNYCODE_BASE - t); + } + + g_string_append_c (output, encode_digit (q)); + bias = adapt (delta, handled_chars + 1, handled_chars == num_basic_chars); + delta = 0; + handled_chars++; + } + } + + delta++; + n++; + } + + success = TRUE; + + fail: + g_free (input); + return success; +} + +/* From RFC 3454, Table B.1 */ +#define idna_is_junk(ch) ((ch) == 0x00AD || (ch) == 0x1806 || (ch) == 0x200B || (ch) == 0x2060 || (ch) == 0xFEFF || (ch) == 0x034F || (ch) == 0x180B || (ch) == 0x180C || (ch) == 0x180D || (ch) == 0x200C || (ch) == 0x200D || ((ch) >= 0xFE00 && (ch) <= 0xFE0F)) + +/* Scan @str for "junk" and return a cleaned-up string if any junk + * is found. Else return %NULL. + */ +static gchar * +remove_junk (const gchar *str, + gint len) +{ + GString *cleaned = NULL; + const gchar *p; + gunichar ch; + + for (p = str; len == -1 ? *p : p < str + len; p = g_utf8_next_char (p)) + { + ch = g_utf8_get_char (p); + if (idna_is_junk (ch)) + { + if (!cleaned) + { + cleaned = g_string_new (NULL); + g_string_append_len (cleaned, str, p - str); + } + } + else if (cleaned) + g_string_append_unichar (cleaned, ch); + } + + if (cleaned) + return g_string_free (cleaned, FALSE); + else + return NULL; +} + +static inline gboolean +contains_uppercase_letters (const gchar *str, + gint len) +{ + const gchar *p; + + for (p = str; len == -1 ? *p : p < str + len; p = g_utf8_next_char (p)) + { + if (g_unichar_isupper (g_utf8_get_char (p))) + return TRUE; + } + return FALSE; +} + +static inline gboolean +contains_non_ascii (const gchar *str, + gint len) +{ + const gchar *p; + + for (p = str; len == -1 ? *p : p < str + len; p++) + { + if ((guchar)*p > 0x80) + return TRUE; + } + return FALSE; +} + +/* RFC 3454, Appendix C. ish. */ +static inline gboolean +idna_is_prohibited (gunichar ch) +{ + switch (g_unichar_type (ch)) + { + case G_UNICODE_CONTROL: + case G_UNICODE_FORMAT: + case G_UNICODE_UNASSIGNED: + case G_UNICODE_PRIVATE_USE: + case G_UNICODE_SURROGATE: + case G_UNICODE_LINE_SEPARATOR: + case G_UNICODE_PARAGRAPH_SEPARATOR: + case G_UNICODE_SPACE_SEPARATOR: + return TRUE; + + case G_UNICODE_OTHER_SYMBOL: + if (ch == 0xFFFC || ch == 0xFFFD || + (ch >= 0x2FF0 && ch <= 0x2FFB)) + return TRUE; + return FALSE; + + case G_UNICODE_NON_SPACING_MARK: + if (ch == 0x0340 || ch == 0x0341) + return TRUE; + return FALSE; + + default: + return FALSE; + } +} + +/* RFC 3491 IDN cleanup algorithm. */ +static gchar * +nameprep (const gchar *hostname, + gint len, + gboolean *is_unicode) +{ + gchar *name, *tmp = NULL, *p; + + /* It would be nice if we could do this without repeatedly + * allocating strings and converting back and forth between + * gunichars and UTF-8... The code does at least avoid doing most of + * the sub-operations when they would just be equivalent to a + * g_strdup(). + */ + + /* Remove presentation-only characters */ + name = remove_junk (hostname, len); + if (name) + { + tmp = name; + len = -1; + } + else + name = (gchar *)hostname; + + /* Convert to lowercase */ + if (contains_uppercase_letters (name, len)) + { + name = g_utf8_strdown (name, len); + g_free (tmp); + tmp = name; + len = -1; + } + + /* If there are no UTF8 characters, we're done. */ + if (!contains_non_ascii (name, len)) + { + *is_unicode = FALSE; + if (name == (gchar *)hostname) + return len == -1 ? g_strdup (hostname) : g_strndup (hostname, len); + else + return name; + } + + *is_unicode = TRUE; + + /* Normalize */ + name = g_utf8_normalize (name, len, G_NORMALIZE_NFKC); + g_free (tmp); + tmp = name; + + if (!name) + return NULL; + + /* KC normalization may have created more capital letters (eg, + * angstrom -> capital A with ring). So we have to lowercasify a + * second time. (This is more-or-less how the nameprep algorithm + * does it. If tolower(nfkc(tolower(X))) is guaranteed to be the + * same as tolower(nfkc(X)), then we could skip the first tolower, + * but I'm not sure it is.) + */ + if (contains_uppercase_letters (name, -1)) + { + name = g_utf8_strdown (name, -1); + g_free (tmp); + tmp = name; + } + + /* Check for prohibited characters */ + for (p = name; *p; p = g_utf8_next_char (p)) + { + if (idna_is_prohibited (g_utf8_get_char (p))) + { + name = NULL; + g_free (tmp); + goto done; + } + } + + /* FIXME: We're supposed to verify certain constraints on bidi + * characters, but glib does not appear to have that information. + */ + + done: + return name; +} + +/* RFC 3490, section 3.1 says '.', 0x3002, 0xFF0E, and 0xFF61 count as + * label-separating dots. @str must be '\0'-terminated. + */ +#define idna_is_dot(str) ( \ + ((guchar)(str)[0] == '.') || \ + ((guchar)(str)[0] == 0xE3 && (guchar)(str)[1] == 0x80 && (guchar)(str)[2] == 0x82) || \ + ((guchar)(str)[0] == 0xEF && (guchar)(str)[1] == 0xBC && (guchar)(str)[2] == 0x8E) || \ + ((guchar)(str)[0] == 0xEF && (guchar)(str)[1] == 0xBD && (guchar)(str)[2] == 0xA1) ) + +static const gchar * +idna_end_of_label (const gchar *str) +{ + for (; *str; str = g_utf8_next_char (str)) + { + if (idna_is_dot (str)) + return str; + } + return str; +} + +/** + * g_hostname_to_ascii: + * @hostname: a valid UTF-8 or ASCII hostname + * + * Converts @hostname to its canonical ASCII form; an ASCII-only + * string containing no uppercase letters and not ending with a + * trailing dot. + * + * Return value: an ASCII hostname, which must be freed, or %NULL if + * @hostname is in some way invalid. + * + * Since: 2.22 + **/ +gchar * +g_hostname_to_ascii (const gchar *hostname) +{ + gchar *name, *label, *p; + GString *out; + gssize llen, oldlen; + gboolean unicode; + + label = name = nameprep (hostname, -1, &unicode); + if (!name || !unicode) + return name; + + out = g_string_new (NULL); + + do + { + unicode = FALSE; + for (p = label; *p && !idna_is_dot (p); p++) + { + if ((guchar)*p > 0x80) + unicode = TRUE; + } + + oldlen = out->len; + llen = p - label; + if (unicode) + { + if (!strncmp (label, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN)) + goto fail; + + g_string_append (out, IDNA_ACE_PREFIX); + if (!punycode_encode (label, llen, out)) + goto fail; + } + else + g_string_append_len (out, label, llen); + + if (out->len - oldlen > 63) + goto fail; + + label += llen; + if (*label) + label = g_utf8_next_char (label); + if (*label) + g_string_append_c (out, '.'); + } + while (*label); + + g_free (name); + return g_string_free (out, FALSE); + + fail: + g_free (name); + g_string_free (out, TRUE); + return NULL; +} + +/** + * g_hostname_is_non_ascii: + * @hostname: a hostname + * + * Tests if @hostname contains Unicode characters. If this returns + * %TRUE, you need to encode the hostname with g_hostname_to_ascii() + * before using it in non-IDN-aware contexts. + * + * Note that a hostname might contain a mix of encoded and unencoded + * segments, and so it is possible for g_hostname_is_non_ascii() and + * g_hostname_is_ascii_encoded() to both return %TRUE for a name. + * + * Return value: %TRUE if @hostname contains any non-ASCII characters + * + * Since: 2.22 + **/ +gboolean +g_hostname_is_non_ascii (const gchar *hostname) +{ + return contains_non_ascii (hostname, -1); +} + +/* Punycode decoder, RFC 3492 section 6.2. As with punycode_encode(), + * read the RFC if you want to understand what this is actually doing. + */ +static gboolean +punycode_decode (const gchar *input, + gsize input_length, + GString *output) +{ + GArray *output_chars; + gunichar n; + guint i, bias; + guint oldi, w, k, digit, t; + const gchar *split; + + n = PUNYCODE_INITIAL_N; + i = 0; + bias = PUNYCODE_INITIAL_BIAS; + + split = input + input_length - 1; + while (split > input && *split != '-') + split--; + if (split > input) + { + output_chars = g_array_sized_new (FALSE, FALSE, sizeof (gunichar), + split - input); + input_length -= (split - input) + 1; + while (input < split) + { + gunichar ch = (gunichar)*input++; + if (!PUNYCODE_IS_BASIC (ch)) + goto fail; + g_array_append_val (output_chars, ch); + } + input++; + } + else + output_chars = g_array_new (FALSE, FALSE, sizeof (gunichar)); + + while (input_length) + { + oldi = i; + w = 1; + for (k = PUNYCODE_BASE; ; k += PUNYCODE_BASE) + { + if (!input_length--) + goto fail; + digit = decode_digit (*input++); + if (digit >= PUNYCODE_BASE) + goto fail; + if (digit > (G_MAXUINT - i) / w) + goto fail; + i += digit * w; + if (k <= bias) + t = PUNYCODE_TMIN; + else if (k >= bias + PUNYCODE_TMAX) + t = PUNYCODE_TMAX; + else + t = k - bias; + if (digit < t) + break; + if (w > G_MAXUINT / (PUNYCODE_BASE - t)) + goto fail; + w *= (PUNYCODE_BASE - t); + } + + bias = adapt (i - oldi, output_chars->len + 1, oldi == 0); + + if (i / (output_chars->len + 1) > G_MAXUINT - n) + goto fail; + n += i / (output_chars->len + 1); + i %= (output_chars->len + 1); + + g_array_insert_val (output_chars, i++, n); + } + + for (i = 0; i < output_chars->len; i++) + g_string_append_unichar (output, g_array_index (output_chars, gunichar, i)); + g_array_free (output_chars, TRUE); + return TRUE; + + fail: + g_array_free (output_chars, TRUE); + return FALSE; +} + +/** + * g_hostname_to_unicode: + * @hostname: a valid UTF-8 or ASCII hostname + * + * Converts @hostname to its canonical presentation form; a UTF-8 + * string in Unicode normalization form C, containing no uppercase + * letters, no forbidden characters, and no ASCII-encoded segments, + * and not ending with a trailing dot. + * + * Of course if @hostname is not an internationalized hostname, then + * the canonical presentation form will be entirely ASCII. + * + * Return value: a UTF-8 hostname, which must be freed, or %NULL if + * @hostname is in some way invalid. + * + * Since: 2.22 + **/ +gchar * +g_hostname_to_unicode (const gchar *hostname) +{ + GString *out; + gssize llen; + + out = g_string_new (NULL); + + do + { + llen = idna_end_of_label (hostname) - hostname; + if (!g_ascii_strncasecmp (hostname, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN)) + { + hostname += IDNA_ACE_PREFIX_LEN; + llen -= IDNA_ACE_PREFIX_LEN; + if (!punycode_decode (hostname, llen, out)) + { + g_string_free (out, TRUE); + return NULL; + } + } + else + { + gboolean unicode; + gchar *canonicalized = nameprep (hostname, llen, &unicode); + + if (!canonicalized) + { + g_string_free (out, TRUE); + return NULL; + } + g_string_append (out, canonicalized); + g_free (canonicalized); + } + + hostname += llen; + if (*hostname) + hostname = g_utf8_next_char (hostname); + if (*hostname) + g_string_append_c (out, '.'); + } + while (*hostname); + + return g_string_free (out, FALSE); +} + +/** + * g_hostname_is_ascii_encoded: + * @hostname: a hostname + * + * Tests if @hostname contains segments with an ASCII-compatible + * encoding of an Internationalized Domain Name. If this returns + * %TRUE, you should decode the hostname with g_hostname_to_unicode() + * before displaying it to the user. + * + * Note that a hostname might contain a mix of encoded and unencoded + * segments, and so it is possible for g_hostname_is_non_ascii() and + * g_hostname_is_ascii_encoded() to both return %TRUE for a name. + * + * Return value: %TRUE if @hostname contains any ASCII-encoded + * segments. + * + * Since: 2.22 + **/ +gboolean +g_hostname_is_ascii_encoded (const gchar *hostname) +{ + while (1) + { + if (!g_ascii_strncasecmp (hostname, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN)) + return TRUE; + hostname = idna_end_of_label (hostname); + if (*hostname) + hostname = g_utf8_next_char (hostname); + if (!*hostname) + return FALSE; + } +} + +/** + * g_hostname_is_ip_address: + * @hostname: a hostname (or IP address in string form) + * + * Tests if @hostname is the string form of an IPv4 or IPv6 address. + * (Eg, "192.168.0.1".) + * + * Return value: %TRUE if @hostname is an IP address + * + * Since: 2.22 + **/ +gboolean +g_hostname_is_ip_address (const gchar *hostname) +{ + gchar *p, *end; + gint nsegments, octet; + + /* On Linux we could implement this using inet_pton, but the Windows + * equivalent of that requires linking against winsock, so we just + * figure this out ourselves. Tested by tests/hostutils.c. + */ + + p = (char *)hostname; + + if (strchr (p, ':')) + { + gboolean skipped; + + /* If it contains a ':', it's an IPv6 address (assuming it's an + * IP address at all). This consists of eight ':'-separated + * segments, each containing a 1-4 digit hex number, except that + * optionally: (a) the last two segments can be replaced by an + * IPv4 address, and (b) a single span of 1 to 8 "0000" segments + * can be replaced with just "::". + */ + + nsegments = 0; + skipped = FALSE; + while (*p && nsegments < 8) + { + /* Each segment after the first must be preceded by a ':'. + * (We also handle half of the "string starts with ::" case + * here.) + */ + if (p != (char *)hostname || (p[0] == ':' && p[1] == ':')) + { + if (*p != ':') + return FALSE; + p++; + } + + /* If there's another ':', it means we're skipping some segments */ + if (*p == ':' && !skipped) + { + skipped = TRUE; + nsegments++; + + /* Handle the "string ends with ::" case */ + if (!p[1]) + p++; + + continue; + } + + /* Read the segment, make sure it's valid. */ + for (end = p; g_ascii_isxdigit (*end); end++) + ; + if (end == p || end > p + 4) + return FALSE; + + if (*end == '.') + { + if ((nsegments == 6 && !skipped) || (nsegments <= 6 && skipped)) + goto parse_ipv4; + else + return FALSE; + } + + nsegments++; + p = end; + } + + return !*p && (nsegments == 8 || skipped); + } + + parse_ipv4: + + /* Parse IPv4: N.N.N.N, where each N <= 255 and doesn't have leading 0s. */ + for (nsegments = 0; nsegments < 4; nsegments++) + { + if (nsegments != 0) + { + if (*p != '.') + return FALSE; + p++; + } + + /* Check the segment; a little tricker than the IPv6 case since + * we can't allow extra leading 0s, and we can't assume that all + * strings of valid length are within range. + */ + octet = 0; + if (*p == '0') + end = p + 1; + else + { + for (end = p; g_ascii_isdigit (*end); end++) + octet = 10 * octet + (*end - '0'); + } + if (end == p || end > p + 3 || octet > 255) + return FALSE; + + p = end; + } + + /* If there's nothing left to parse, then it's ok. */ + return !*p; +} diff --git a/glib/glib/ghostutils.h b/glib/glib/ghostutils.h new file mode 100644 index 0000000..0349da3 --- /dev/null +++ b/glib/glib/ghostutils.h @@ -0,0 +1,40 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_HOST_UTILS_H__ +#define __G_HOST_UTILS_H__ + +#include + +G_BEGIN_DECLS + +gboolean g_hostname_is_non_ascii (const gchar *hostname); +gboolean g_hostname_is_ascii_encoded (const gchar *hostname); +gboolean g_hostname_is_ip_address (const gchar *hostname); + +gchar *g_hostname_to_ascii (const gchar *hostname); +gchar *g_hostname_to_unicode (const gchar *hostname); + +G_END_DECLS + +#endif /* __G_HOST_UTILS_H__ */ diff --git a/glib/glib/gi18n-lib.h b/glib/glib/gi18n-lib.h new file mode 100644 index 0000000..ca002a7 --- /dev/null +++ b/glib/glib/gi18n-lib.h @@ -0,0 +1,38 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997, 2002 Peter Mattis, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_I18N_LIB_H__ +#define __G_I18N_LIB_H__ + +#include + +#include +#include + +#ifndef GETTEXT_PACKAGE +#error You must define GETTEXT_PACKAGE before including gi18n-lib.h. Did you forget to include config.h? +#endif + +#define _(String) ((char *) g_dgettext (GETTEXT_PACKAGE, String)) +#define Q_(String) g_dpgettext (GETTEXT_PACKAGE, String, 0) +#define N_(String) (String) +#define C_(Context,String) g_dpgettext (GETTEXT_PACKAGE, Context "\004" String, strlen (Context) + 1) +#define NC_(Context, String) (String) + +#endif /* __G_I18N_LIB_H__ */ diff --git a/glib/glib/gi18n.h b/glib/glib/gi18n.h new file mode 100644 index 0000000..c710046 --- /dev/null +++ b/glib/glib/gi18n.h @@ -0,0 +1,34 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997, 2002 Peter Mattis, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_I18N_H__ +#define __G_I18N_H__ + +#include + +#include +#include + +#define _(String) gettext (String) +#define Q_(String) g_dpgettext (NULL, String, 0) +#define N_(String) (String) +#define C_(Context,String) g_dpgettext (NULL, Context "\004" String, strlen (Context) + 1) +#define NC_(Context, String) (String) + +#endif /* __G_I18N_H__ */ diff --git a/glib/glib/giochannel.c b/glib/glib/giochannel.c new file mode 100644 index 0000000..f294701 --- /dev/null +++ b/glib/glib/giochannel.c @@ -0,0 +1,2587 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * giochannel.c: IO Channel abstraction + * Copyright 1998 Owen Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "giochannel.h" + +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "glibintl.h" + + +/** + * SECTION:iochannels + * @title: IO Channels + * @short_description: portable support for using files, pipes and + * sockets + * @see_also: + * g_io_add_watch(), g_io_add_watch_full(), + * g_source_remove() Convenience + * functions for creating #GIOChannel instances and adding + * them to the main + * event loop. + * + * + * The #GIOChannel data type aims to provide a portable method for + * using file descriptors, pipes, and sockets, and integrating them + * into the main event + * loop. Currently full support is available on UNIX platforms, + * support for Windows is only partially complete. + * + * To create a new #GIOChannel on UNIX systems use + * g_io_channel_unix_new(). This works for plain file descriptors, + * pipes and sockets. Alternatively, a channel can be created for a + * file in a system independent manner using g_io_channel_new_file(). + * + * Once a #GIOChannel has been created, it can be used in a generic + * manner with the functions g_io_channel_read_chars(), + * g_io_channel_write_chars(), g_io_channel_seek_position(), and + * g_io_channel_shutdown(). + * + * To add a #GIOChannel to the main event loop use + * g_io_add_watch() or g_io_add_watch_full(). Here you specify which + * events you are interested in on the #GIOChannel, and provide a + * function to be called whenever these events occur. + * + * #GIOChannel instances are created with an initial reference count of + * 1. g_io_channel_ref() and g_io_channel_unref() can be used to + * increment or decrement the reference count respectively. When the + * reference count falls to 0, the #GIOChannel is freed. (Though it + * isn't closed automatically, unless it was created using + * g_io_channel_new_file().) Using g_io_add_watch() or + * g_io_add_watch_full() increments a channel's reference count. + * + * The new functions g_io_channel_read_chars(), + * g_io_channel_read_line(), g_io_channel_read_line_string(), + * g_io_channel_read_to_end(), g_io_channel_write_chars(), + * g_io_channel_seek_position(), and g_io_channel_flush() should not be + * mixed with the deprecated functions g_io_channel_read(), + * g_io_channel_write(), and g_io_channel_seek() on the same channel. + **/ + +/** + * GIOChannel: + * + * A data structure representing an IO Channel. The fields should be + * considered private and should only be accessed with the following + * functions. + **/ + +/** + * GIOFuncs: + * @io_read: reads raw bytes from the channel. This is called from + * various functions such as g_io_channel_read_chars() to + * read raw bytes from the channel. Encoding and buffering + * issues are dealt with at a higher level. + * @io_write: writes raw bytes to the channel. This is called from + * various functions such as g_io_channel_write_chars() to + * write raw bytes to the channel. Encoding and buffering + * issues are dealt with at a higher level. + * @io_seek: (optional) seeks the channel. This is called from + * g_io_channel_seek() on channels that support it. + * @io_close: closes the channel. This is called from + * g_io_channel_close() after flushing the buffers. + * @io_create_watch: creates a watch on the channel. This call + * corresponds directly to g_io_create_watch(). + * @io_free: called from g_io_channel_unref() when the channel needs to + * be freed. This function must free the memory associated + * with the channel, including freeing the #GIOChannel + * structure itself. The channel buffers have been flushed + * and possibly @io_close has been called by the time this + * function is called. + * @io_set_flags: sets the #GIOFlags on the channel. This is called + * from g_io_channel_set_flags() with all flags except + * for %G_IO_FLAG_APPEND and %G_IO_FLAG_NONBLOCK masked + * out. + * @io_get_flags: gets the #GIOFlags for the channel. This function + * need only return the %G_IO_FLAG_APPEND and + * %G_IO_FLAG_NONBLOCK flags; g_io_channel_get_flags() + * automatically adds the others as appropriate. + * + * A table of functions used to handle different types of #GIOChannel + * in a generic way. + **/ + +/** + * GIOStatus: + * @G_IO_STATUS_ERROR: An error occurred. + * @G_IO_STATUS_NORMAL: Success. + * @G_IO_STATUS_EOF: End of file. + * @G_IO_STATUS_AGAIN: Resource temporarily unavailable. + * + * Stati returned by most of the #GIOFuncs functions. + **/ + +/** + * GIOError: + * @G_IO_ERROR_NONE: no error + * @G_IO_ERROR_AGAIN: an EAGAIN error occurred + * @G_IO_ERROR_INVAL: an EINVAL error occurred + * @G_IO_ERROR_UNKNOWN: another error occurred + * + * #GIOError is only used by the deprecated functions + * g_io_channel_read(), g_io_channel_write(), and g_io_channel_seek(). + **/ + +#define G_IO_NICE_BUF_SIZE 1024 + +/* This needs to be as wide as the largest character in any possible encoding */ +#define MAX_CHAR_SIZE 10 + +/* Some simplifying macros, which reduce the need to worry whether the + * buffers have been allocated. These also make USE_BUF () an lvalue, + * which is used in g_io_channel_read_to_end (). + */ +#define USE_BUF(channel) ((channel)->encoding ? (channel)->encoded_read_buf \ + : (channel)->read_buf) +#define BUF_LEN(string) ((string) ? (string)->len : 0) + +static GIOError g_io_error_get_from_g_error (GIOStatus status, + GError *err); +static void g_io_channel_purge (GIOChannel *channel); +static GIOStatus g_io_channel_fill_buffer (GIOChannel *channel, + GError **err); +static GIOStatus g_io_channel_read_line_backend (GIOChannel *channel, + gsize *length, + gsize *terminator_pos, + GError **error); + +/** + * g_io_channel_init: + * @channel: a #GIOChannel + * + * Initializes a #GIOChannel struct. + * + * This is called by each of the above functions when creating a + * #GIOChannel, and so is not often needed by the application + * programmer (unless you are creating a new type of #GIOChannel). + */ +void +g_io_channel_init (GIOChannel *channel) +{ + channel->ref_count = 1; + channel->encoding = g_strdup ("UTF-8"); + channel->line_term = NULL; + channel->line_term_len = 0; + channel->buf_size = G_IO_NICE_BUF_SIZE; + channel->read_cd = (GIConv) -1; + channel->write_cd = (GIConv) -1; + channel->read_buf = NULL; /* Lazy allocate buffers */ + channel->encoded_read_buf = NULL; + channel->write_buf = NULL; + channel->partial_write_buf[0] = '\0'; + channel->use_buffer = TRUE; + channel->do_encode = FALSE; + channel->close_on_unref = FALSE; +} + +/** + * g_io_channel_ref: + * @channel: a #GIOChannel + * + * Increments the reference count of a #GIOChannel. + * + * Returns: the @channel that was passed in (since 2.6) + */ +GIOChannel * +g_io_channel_ref (GIOChannel *channel) +{ + g_return_val_if_fail (channel != NULL, NULL); + + g_atomic_int_inc (&channel->ref_count); + + return channel; +} + +/** + * g_io_channel_unref: + * @channel: a #GIOChannel + * + * Decrements the reference count of a #GIOChannel. + */ +void +g_io_channel_unref (GIOChannel *channel) +{ + gboolean is_zero; + + g_return_if_fail (channel != NULL); + + is_zero = g_atomic_int_dec_and_test (&channel->ref_count); + + if (G_UNLIKELY (is_zero)) + { + if (channel->close_on_unref) + g_io_channel_shutdown (channel, TRUE, NULL); + else + g_io_channel_purge (channel); + g_free (channel->encoding); + if (channel->read_cd != (GIConv) -1) + g_iconv_close (channel->read_cd); + if (channel->write_cd != (GIConv) -1) + g_iconv_close (channel->write_cd); + g_free (channel->line_term); + if (channel->read_buf) + g_string_free (channel->read_buf, TRUE); + if (channel->write_buf) + g_string_free (channel->write_buf, TRUE); + if (channel->encoded_read_buf) + g_string_free (channel->encoded_read_buf, TRUE); + channel->funcs->io_free (channel); + } +} + +static GIOError +g_io_error_get_from_g_error (GIOStatus status, + GError *err) +{ + switch (status) + { + case G_IO_STATUS_NORMAL: + case G_IO_STATUS_EOF: + return G_IO_ERROR_NONE; + case G_IO_STATUS_AGAIN: + return G_IO_ERROR_AGAIN; + case G_IO_STATUS_ERROR: + g_return_val_if_fail (err != NULL, G_IO_ERROR_UNKNOWN); + + if (err->domain != G_IO_CHANNEL_ERROR) + return G_IO_ERROR_UNKNOWN; + switch (err->code) + { + case G_IO_CHANNEL_ERROR_INVAL: + return G_IO_ERROR_INVAL; + default: + return G_IO_ERROR_UNKNOWN; + } + default: + g_assert_not_reached (); + } +} + +/** + * g_io_channel_read: + * @channel: a #GIOChannel + * @buf: a buffer to read the data into (which should be at least + * count bytes long) + * @count: the number of bytes to read from the #GIOChannel + * @bytes_read: returns the number of bytes actually read + * + * Reads data from a #GIOChannel. + * + * Return value: %G_IO_ERROR_NONE if the operation was successful. + * + * Deprecated:2.2: Use g_io_channel_read_chars() instead. + **/ +GIOError +g_io_channel_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read) +{ + GError *err = NULL; + GIOError error; + GIOStatus status; + + g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); + g_return_val_if_fail (bytes_read != NULL, G_IO_ERROR_UNKNOWN); + + if (count == 0) + { + if (bytes_read) + *bytes_read = 0; + return G_IO_ERROR_NONE; + } + + g_return_val_if_fail (buf != NULL, G_IO_ERROR_UNKNOWN); + + status = channel->funcs->io_read (channel, buf, count, bytes_read, &err); + + error = g_io_error_get_from_g_error (status, err); + + if (err) + g_error_free (err); + + return error; +} + +/** + * g_io_channel_write: + * @channel: a #GIOChannel + * @buf: the buffer containing the data to write + * @count: the number of bytes to write + * @bytes_written: the number of bytes actually written + * + * Writes data to a #GIOChannel. + * + * Return value: %G_IO_ERROR_NONE if the operation was successful. + * + * Deprecated:2.2: Use g_io_channel_write_chars() instead. + **/ +GIOError +g_io_channel_write (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written) +{ + GError *err = NULL; + GIOError error; + GIOStatus status; + + g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); + g_return_val_if_fail (bytes_written != NULL, G_IO_ERROR_UNKNOWN); + + status = channel->funcs->io_write (channel, buf, count, bytes_written, &err); + + error = g_io_error_get_from_g_error (status, err); + + if (err) + g_error_free (err); + + return error; +} + +/** + * g_io_channel_seek: + * @channel: a #GIOChannel + * @offset: an offset, in bytes, which is added to the position specified + * by @type + * @type: the position in the file, which can be %G_SEEK_CUR (the current + * position), %G_SEEK_SET (the start of the file), or %G_SEEK_END + * (the end of the file) + * + * Sets the current position in the #GIOChannel, similar to the standard + * library function fseek(). + * + * Return value: %G_IO_ERROR_NONE if the operation was successful. + * + * Deprecated:2.2: Use g_io_channel_seek_position() instead. + **/ +GIOError +g_io_channel_seek (GIOChannel *channel, + gint64 offset, + GSeekType type) +{ + GError *err = NULL; + GIOError error; + GIOStatus status; + + g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN); + g_return_val_if_fail (channel->is_seekable, G_IO_ERROR_UNKNOWN); + + switch (type) + { + case G_SEEK_CUR: + case G_SEEK_SET: + case G_SEEK_END: + break; + default: + g_warning ("g_io_channel_seek: unknown seek type"); + return G_IO_ERROR_UNKNOWN; + } + + status = channel->funcs->io_seek (channel, offset, type, &err); + + error = g_io_error_get_from_g_error (status, err); + + if (err) + g_error_free (err); + + return error; +} + +/* The function g_io_channel_new_file() is prototyped in both + * giounix.c and giowin32.c, so we stick its documentation here. + */ + +/** + * g_io_channel_new_file: + * @filename: A string containing the name of a file + * @mode: One of "r", "w", "a", "r+", "w+", "a+". These have + * the same meaning as in fopen() + * @error: A location to return an error of type %G_FILE_ERROR + * + * Open a file @filename as a #GIOChannel using mode @mode. This + * channel will be closed when the last reference to it is dropped, + * so there is no need to call g_io_channel_close() (though doing + * so will not cause problems, as long as no attempt is made to + * access the channel after it is closed). + * + * Return value: A #GIOChannel on success, %NULL on failure. + **/ + +/** + * g_io_channel_close: + * @channel: A #GIOChannel + * + * Close an IO channel. Any pending data to be written will be + * flushed, ignoring errors. The channel will not be freed until the + * last reference is dropped using g_io_channel_unref(). + * + * Deprecated:2.2: Use g_io_channel_shutdown() instead. + **/ +void +g_io_channel_close (GIOChannel *channel) +{ + GError *err = NULL; + + g_return_if_fail (channel != NULL); + + g_io_channel_purge (channel); + + channel->funcs->io_close (channel, &err); + + if (err) + { /* No way to return the error */ + g_warning ("Error closing channel: %s", err->message); + g_error_free (err); + } + + channel->close_on_unref = FALSE; /* Because we already did */ + channel->is_readable = FALSE; + channel->is_writeable = FALSE; + channel->is_seekable = FALSE; +} + +/** + * g_io_channel_shutdown: + * @channel: a #GIOChannel + * @flush: if %TRUE, flush pending + * @err: location to store a #GIOChannelError + * + * Close an IO channel. Any pending data to be written will be + * flushed if @flush is %TRUE. The channel will not be freed until the + * last reference is dropped using g_io_channel_unref(). + * + * Return value: the status of the operation. + **/ +GIOStatus +g_io_channel_shutdown (GIOChannel *channel, + gboolean flush, + GError **err) +{ + GIOStatus status, result; + GError *tmperr = NULL; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail (err == NULL || *err == NULL, G_IO_STATUS_ERROR); + + if (channel->write_buf && channel->write_buf->len > 0) + { + if (flush) + { + GIOFlags flags; + + /* Set the channel to blocking, to avoid a busy loop + */ + flags = g_io_channel_get_flags (channel); + /* Ignore any errors here, they're irrelevant */ + g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL); + + result = g_io_channel_flush (channel, &tmperr); + } + else + result = G_IO_STATUS_NORMAL; + + g_string_truncate(channel->write_buf, 0); + } + else + result = G_IO_STATUS_NORMAL; + + if (channel->partial_write_buf[0] != '\0') + { + if (flush) + g_warning ("Partial character at end of write buffer not flushed.\n"); + channel->partial_write_buf[0] = '\0'; + } + + status = channel->funcs->io_close (channel, err); + + channel->close_on_unref = FALSE; /* Because we already did */ + channel->is_readable = FALSE; + channel->is_writeable = FALSE; + channel->is_seekable = FALSE; + + if (status != G_IO_STATUS_NORMAL) + { + g_clear_error (&tmperr); + return status; + } + else if (result != G_IO_STATUS_NORMAL) + { + g_propagate_error (err, tmperr); + return result; + } + else + return G_IO_STATUS_NORMAL; +} + +/* This function is used for the final flush on close or unref */ +static void +g_io_channel_purge (GIOChannel *channel) +{ + GError *err = NULL; + GIOStatus status G_GNUC_UNUSED; + + g_return_if_fail (channel != NULL); + + if (channel->write_buf && channel->write_buf->len > 0) + { + GIOFlags flags; + + /* Set the channel to blocking, to avoid a busy loop + */ + flags = g_io_channel_get_flags (channel); + g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL); + + status = g_io_channel_flush (channel, &err); + + if (err) + { /* No way to return the error */ + g_warning ("Error flushing string: %s", err->message); + g_error_free (err); + } + } + + /* Flush these in case anyone tries to close without unrefing */ + + if (channel->read_buf) + g_string_truncate (channel->read_buf, 0); + if (channel->write_buf) + g_string_truncate (channel->write_buf, 0); + if (channel->encoding) + { + if (channel->encoded_read_buf) + g_string_truncate (channel->encoded_read_buf, 0); + + if (channel->partial_write_buf[0] != '\0') + { + g_warning ("Partial character at end of write buffer not flushed.\n"); + channel->partial_write_buf[0] = '\0'; + } + } +} + +/** + * g_io_create_watch: + * @channel: a #GIOChannel to watch + * @condition: conditions to watch for + * + * Creates a #GSource that's dispatched when @condition is met for the + * given @channel. For example, if condition is #G_IO_IN, the source will + * be dispatched when there's data available for reading. + * + * g_io_add_watch() is a simpler interface to this same functionality, for + * the case where you want to add the source to the default main loop context + * at the default priority. + * + * On Windows, polling a #GSource created to watch a channel for a socket + * puts the socket in non-blocking mode. This is a side-effect of the + * implementation and unavoidable. + * + * Returns: a new #GSource + */ +GSource * +g_io_create_watch (GIOChannel *channel, + GIOCondition condition) +{ + g_return_val_if_fail (channel != NULL, NULL); + + return channel->funcs->io_create_watch (channel, condition); +} + +/** + * g_io_add_watch_full: + * @channel: a #GIOChannel + * @priority: the priority of the #GIOChannel source + * @condition: the condition to watch for + * @func: the function to call when the condition is satisfied + * @user_data: user data to pass to @func + * @notify: the function to call when the source is removed + * + * Adds the #GIOChannel into the default main loop context + * with the given priority. + * + * This internally creates a main loop source using g_io_create_watch() + * and attaches it to the main loop context with g_source_attach(). + * You can do these steps manually if you need greater control. + * + * Returns: the event source id + * Rename to: g_io_add_watch + */ +guint +g_io_add_watch_full (GIOChannel *channel, + gint priority, + GIOCondition condition, + GIOFunc func, + gpointer user_data, + GDestroyNotify notify) +{ + GSource *source; + guint id; + + g_return_val_if_fail (channel != NULL, 0); + + source = g_io_create_watch (channel, condition); + + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority (source, priority); + g_source_set_callback (source, (GSourceFunc)func, user_data, notify); + + id = g_source_attach (source, NULL); + g_source_unref (source); + + return id; +} + +/** + * g_io_add_watch: + * @channel: a #GIOChannel + * @condition: the condition to watch for + * @func: the function to call when the condition is satisfied + * @user_data: user data to pass to @func + * + * Adds the #GIOChannel into the default main loop context + * with the default priority. + * + * Returns: the event source id + */ +/** + * GIOFunc: + * @source: the #GIOChannel event source + * @condition: the condition which has been satisfied + * @data: user data set in g_io_add_watch() or g_io_add_watch_full() + * @Returns: the function should return %FALSE if the event source + * should be removed + * + * Specifies the type of function passed to g_io_add_watch() or + * g_io_add_watch_full(), which is called when the requested condition + * on a #GIOChannel is satisfied. + **/ +/** + * GIOCondition: + * @G_IO_IN: There is data to read. + * @G_IO_OUT: Data can be written (without blocking). + * @G_IO_PRI: There is urgent data to read. + * @G_IO_ERR: Error condition. + * @G_IO_HUP: Hung up (the connection has been broken, usually for + * pipes and sockets). + * @G_IO_NVAL: Invalid request. The file descriptor is not open. + * + * A bitwise combination representing a condition to watch for on an + * event source. + **/ +guint +g_io_add_watch (GIOChannel *channel, + GIOCondition condition, + GIOFunc func, + gpointer user_data) +{ + return g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, condition, func, user_data, NULL); +} + +/** + * g_io_channel_get_buffer_condition: + * @channel: A #GIOChannel + * + * This function returns a #GIOCondition depending on whether there + * is data to be read/space to write data in the internal buffers in + * the #GIOChannel. Only the flags %G_IO_IN and %G_IO_OUT may be set. + * + * Return value: A #GIOCondition + **/ +GIOCondition +g_io_channel_get_buffer_condition (GIOChannel *channel) +{ + GIOCondition condition = 0; + + if (channel->encoding) + { + if (channel->encoded_read_buf && (channel->encoded_read_buf->len > 0)) + condition |= G_IO_IN; /* Only return if we have full characters */ + } + else + { + if (channel->read_buf && (channel->read_buf->len > 0)) + condition |= G_IO_IN; + } + + if (channel->write_buf && (channel->write_buf->len < channel->buf_size)) + condition |= G_IO_OUT; + + return condition; +} + +/** + * g_io_channel_error_from_errno: + * @en: an errno error number, e.g. EINVAL + * + * Converts an errno error number to a #GIOChannelError. + * + * Return value: a #GIOChannelError error number, e.g. + * %G_IO_CHANNEL_ERROR_INVAL. + **/ +GIOChannelError +g_io_channel_error_from_errno (gint en) +{ +#ifdef EAGAIN + g_return_val_if_fail (en != EAGAIN, G_IO_CHANNEL_ERROR_FAILED); +#endif + + switch (en) + { +#ifdef EBADF + case EBADF: + g_warning("Invalid file descriptor.\n"); + return G_IO_CHANNEL_ERROR_FAILED; +#endif + +#ifdef EFAULT + case EFAULT: + g_warning("Buffer outside valid address space.\n"); + return G_IO_CHANNEL_ERROR_FAILED; +#endif + +#ifdef EFBIG + case EFBIG: + return G_IO_CHANNEL_ERROR_FBIG; +#endif + +#ifdef EINTR + /* In general, we should catch EINTR before we get here, + * but close() is allowed to return EINTR by POSIX, so + * we need to catch it here; EINTR from close() is + * unrecoverable, because it's undefined whether + * the fd was actually closed or not, so we just return + * a generic error code. + */ + case EINTR: + return G_IO_CHANNEL_ERROR_FAILED; +#endif + +#ifdef EINVAL + case EINVAL: + return G_IO_CHANNEL_ERROR_INVAL; +#endif + +#ifdef EIO + case EIO: + return G_IO_CHANNEL_ERROR_IO; +#endif + +#ifdef EISDIR + case EISDIR: + return G_IO_CHANNEL_ERROR_ISDIR; +#endif + +#ifdef ENOSPC + case ENOSPC: + return G_IO_CHANNEL_ERROR_NOSPC; +#endif + +#ifdef ENXIO + case ENXIO: + return G_IO_CHANNEL_ERROR_NXIO; +#endif + +#ifdef EOVERFLOW + case EOVERFLOW: + return G_IO_CHANNEL_ERROR_OVERFLOW; +#endif + +#ifdef EPIPE + case EPIPE: + return G_IO_CHANNEL_ERROR_PIPE; +#endif + + default: + return G_IO_CHANNEL_ERROR_FAILED; + } +} + +/** + * g_io_channel_set_buffer_size: + * @channel: a #GIOChannel + * @size: the size of the buffer, or 0 to let GLib pick a good size + * + * Sets the buffer size. + **/ +void +g_io_channel_set_buffer_size (GIOChannel *channel, + gsize size) +{ + g_return_if_fail (channel != NULL); + + if (size == 0) + size = G_IO_NICE_BUF_SIZE; + + if (size < MAX_CHAR_SIZE) + size = MAX_CHAR_SIZE; + + channel->buf_size = size; +} + +/** + * g_io_channel_get_buffer_size: + * @channel: a #GIOChannel + * + * Gets the buffer size. + * + * Return value: the size of the buffer. + **/ +gsize +g_io_channel_get_buffer_size (GIOChannel *channel) +{ + g_return_val_if_fail (channel != NULL, 0); + + return channel->buf_size; +} + +/** + * g_io_channel_set_line_term: + * @channel: a #GIOChannel + * @line_term: The line termination string. Use %NULL for autodetect. + * Autodetection breaks on "\n", "\r\n", "\r", "\0", and + * the Unicode paragraph separator. Autodetection should + * not be used for anything other than file-based channels. + * @length: The length of the termination string. If -1 is passed, the + * string is assumed to be nul-terminated. This option allows + * termination strings with embedded nuls. + * + * This sets the string that #GIOChannel uses to determine + * where in the file a line break occurs. + **/ +void +g_io_channel_set_line_term (GIOChannel *channel, + const gchar *line_term, + gint length) +{ + g_return_if_fail (channel != NULL); + g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */ + + if (line_term == NULL) + length = 0; + else if (length < 0) + length = strlen (line_term); + + g_free (channel->line_term); + channel->line_term = line_term ? g_memdup (line_term, length) : NULL; + channel->line_term_len = length; +} + +/** + * g_io_channel_get_line_term: + * @channel: a #GIOChannel + * @length: a location to return the length of the line terminator + * + * This returns the string that #GIOChannel uses to determine + * where in the file a line break occurs. A value of %NULL + * indicates autodetection. + * + * Return value: The line termination string. This value + * is owned by GLib and must not be freed. + **/ +const gchar * +g_io_channel_get_line_term (GIOChannel *channel, + gint *length) +{ + g_return_val_if_fail (channel != NULL, NULL); + + if (length) + *length = channel->line_term_len; + + return channel->line_term; +} + +/** + * g_io_channel_set_flags: + * @channel: a #GIOChannel + * @flags: the flags to set on the IO channel + * @error: A location to return an error of type #GIOChannelError + * + * Sets the (writeable) flags in @channel to (@flags & %G_IO_FLAG_SET_MASK). + * + * Return value: the status of the operation. + **/ +/** + * GIOFlags: + * @G_IO_FLAG_APPEND: turns on append mode, corresponds to O_APPEND + * (see the documentation of the UNIX open() + * syscall). + * @G_IO_FLAG_NONBLOCK: turns on nonblocking mode, corresponds to + * O_NONBLOCK/O_NDELAY + * (see the documentation of the UNIX open() syscall). + * @G_IO_FLAG_IS_READABLE: indicates that the io channel is readable. + * This flag cannot be changed. + * @G_IO_FLAG_IS_WRITABLE: indicates that the io channel is writable. + * This flag cannot be changed. + * @G_IO_FLAG_IS_SEEKABLE: indicates that the io channel is seekable, + * i.e. that g_io_channel_seek_position() can + * be used on it. This flag cannot be changed. + * @G_IO_FLAG_MASK: the mask that specifies all the valid flags. + * @G_IO_FLAG_GET_MASK: the mask of the flags that are returned from + * g_io_channel_get_flags(). + * @G_IO_FLAG_SET_MASK: the mask of the flags that the user can modify + * with g_io_channel_set_flags(). + * + * Specifies properties of a #GIOChannel. Some of the flags can only be + * read with g_io_channel_get_flags(), but not changed with + * g_io_channel_set_flags(). + **/ +/** + * G_IO_FLAG_IS_WRITEABLE: + * + * This is a misspelled version of G_IO_FLAG_IS_WRITABLE that existed + * before the spelling was fixed in GLib 2.30. It is kept here for + * compatibility reasons. + * + * Deprecated:2.30:Use G_IO_FLAG_IS_WRITABLE instead. + **/ +GIOStatus +g_io_channel_set_flags (GIOChannel *channel, + GIOFlags flags, + GError **error) +{ + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + + return (*channel->funcs->io_set_flags) (channel, + flags & G_IO_FLAG_SET_MASK, + error); +} + +/** + * g_io_channel_get_flags: + * @channel: a #GIOChannel + * + * Gets the current flags for a #GIOChannel, including read-only + * flags such as %G_IO_FLAG_IS_READABLE. + * + * The values of the flags %G_IO_FLAG_IS_READABLE and %G_IO_FLAG_IS_WRITABLE + * are cached for internal use by the channel when it is created. + * If they should change at some later point (e.g. partial shutdown + * of a socket with the UNIX shutdown() function), the user + * should immediately call g_io_channel_get_flags() to update + * the internal values of these flags. + * + * Return value: the flags which are set on the channel + **/ +GIOFlags +g_io_channel_get_flags (GIOChannel *channel) +{ + GIOFlags flags; + + g_return_val_if_fail (channel != NULL, 0); + + flags = (* channel->funcs->io_get_flags) (channel); + + /* Cross implementation code */ + + if (channel->is_seekable) + flags |= G_IO_FLAG_IS_SEEKABLE; + if (channel->is_readable) + flags |= G_IO_FLAG_IS_READABLE; + if (channel->is_writeable) + flags |= G_IO_FLAG_IS_WRITABLE; + + return flags; +} + +/** + * g_io_channel_set_close_on_unref: + * @channel: a #GIOChannel + * @do_close: Whether to close the channel on the final unref of + * the GIOChannel data structure. The default value of + * this is %TRUE for channels created by g_io_channel_new_file (), + * and %FALSE for all other channels. + * + * Setting this flag to %TRUE for a channel you have already closed + * can cause problems. + **/ +void +g_io_channel_set_close_on_unref (GIOChannel *channel, + gboolean do_close) +{ + g_return_if_fail (channel != NULL); + + channel->close_on_unref = do_close; +} + +/** + * g_io_channel_get_close_on_unref: + * @channel: a #GIOChannel. + * + * Returns whether the file/socket/whatever associated with @channel + * will be closed when @channel receives its final unref and is + * destroyed. The default value of this is %TRUE for channels created + * by g_io_channel_new_file (), and %FALSE for all other channels. + * + * Return value: Whether the channel will be closed on the final unref of + * the GIOChannel data structure. + **/ +gboolean +g_io_channel_get_close_on_unref (GIOChannel *channel) +{ + g_return_val_if_fail (channel != NULL, FALSE); + + return channel->close_on_unref; +} + +/** + * g_io_channel_seek_position: + * @channel: a #GIOChannel + * @offset: The offset in bytes from the position specified by @type + * @type: a #GSeekType. The type %G_SEEK_CUR is only allowed in those + * cases where a call to g_io_channel_set_encoding () + * is allowed. See the documentation for + * g_io_channel_set_encoding () for details. + * @error: A location to return an error of type #GIOChannelError + * + * Replacement for g_io_channel_seek() with the new API. + * + * Return value: the status of the operation. + **/ +/** + * GSeekType: + * @G_SEEK_CUR: the current position in the file. + * @G_SEEK_SET: the start of the file. + * @G_SEEK_END: the end of the file. + * + * An enumeration specifying the base position for a + * g_io_channel_seek_position() operation. + **/ +GIOStatus +g_io_channel_seek_position (GIOChannel *channel, + gint64 offset, + GSeekType type, + GError **error) +{ + GIOStatus status; + + /* For files, only one of the read and write buffers can contain data. + * For sockets, both can contain data. + */ + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_seekable, G_IO_STATUS_ERROR); + + switch (type) + { + case G_SEEK_CUR: /* The user is seeking relative to the head of the buffer */ + if (channel->use_buffer) + { + if (channel->do_encode && channel->encoded_read_buf + && channel->encoded_read_buf->len > 0) + { + g_warning ("Seek type G_SEEK_CUR not allowed for this" + " channel's encoding.\n"); + return G_IO_STATUS_ERROR; + } + if (channel->read_buf) + offset -= channel->read_buf->len; + if (channel->encoded_read_buf) + { + g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode); + + /* If there's anything here, it's because the encoding is UTF-8, + * so we can just subtract the buffer length, the same as for + * the unencoded data. + */ + + offset -= channel->encoded_read_buf->len; + } + } + break; + case G_SEEK_SET: + case G_SEEK_END: + break; + default: + g_warning ("g_io_channel_seek_position: unknown seek type"); + return G_IO_STATUS_ERROR; + } + + if (channel->use_buffer) + { + status = g_io_channel_flush (channel, error); + if (status != G_IO_STATUS_NORMAL) + return status; + } + + status = channel->funcs->io_seek (channel, offset, type, error); + + if ((status == G_IO_STATUS_NORMAL) && (channel->use_buffer)) + { + if (channel->read_buf) + g_string_truncate (channel->read_buf, 0); + + /* Conversion state no longer matches position in file */ + if (channel->read_cd != (GIConv) -1) + g_iconv (channel->read_cd, NULL, NULL, NULL, NULL); + if (channel->write_cd != (GIConv) -1) + g_iconv (channel->write_cd, NULL, NULL, NULL, NULL); + + if (channel->encoded_read_buf) + { + g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode); + g_string_truncate (channel->encoded_read_buf, 0); + } + + if (channel->partial_write_buf[0] != '\0') + { + g_warning ("Partial character at end of write buffer not flushed.\n"); + channel->partial_write_buf[0] = '\0'; + } + } + + return status; +} + +/** + * g_io_channel_flush: + * @channel: a #GIOChannel + * @error: location to store an error of type #GIOChannelError + * + * Flushes the write buffer for the GIOChannel. + * + * Return value: the status of the operation: One of + * #G_IO_STATUS_NORMAL, #G_IO_STATUS_AGAIN, or + * #G_IO_STATUS_ERROR. + **/ +GIOStatus +g_io_channel_flush (GIOChannel *channel, + GError **error) +{ + GIOStatus status; + gsize this_time = 1, bytes_written = 0; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); + + if (channel->write_buf == NULL || channel->write_buf->len == 0) + return G_IO_STATUS_NORMAL; + + do + { + g_assert (this_time > 0); + + status = channel->funcs->io_write (channel, + channel->write_buf->str + bytes_written, + channel->write_buf->len - bytes_written, + &this_time, error); + bytes_written += this_time; + } + while ((bytes_written < channel->write_buf->len) + && (status == G_IO_STATUS_NORMAL)); + + g_string_erase (channel->write_buf, 0, bytes_written); + + return status; +} + +/** + * g_io_channel_set_buffered: + * @channel: a #GIOChannel + * @buffered: whether to set the channel buffered or unbuffered + * + * The buffering state can only be set if the channel's encoding + * is %NULL. For any other encoding, the channel must be buffered. + * + * A buffered channel can only be set unbuffered if the channel's + * internal buffers have been flushed. Newly created channels or + * channels which have returned %G_IO_STATUS_EOF + * not require such a flush. For write-only channels, a call to + * g_io_channel_flush () is sufficient. For all other channels, + * the buffers may be flushed by a call to g_io_channel_seek_position (). + * This includes the possibility of seeking with seek type %G_SEEK_CUR + * and an offset of zero. Note that this means that socket-based + * channels cannot be set unbuffered once they have had data + * read from them. + * + * On unbuffered channels, it is safe to mix read and write + * calls from the new and old APIs, if this is necessary for + * maintaining old code. + * + * The default state of the channel is buffered. + **/ +void +g_io_channel_set_buffered (GIOChannel *channel, + gboolean buffered) +{ + g_return_if_fail (channel != NULL); + + if (channel->encoding != NULL) + { + g_warning ("Need to have NULL encoding to set the buffering state of the " + "channel.\n"); + return; + } + + g_return_if_fail (!channel->read_buf || channel->read_buf->len == 0); + g_return_if_fail (!channel->write_buf || channel->write_buf->len == 0); + + channel->use_buffer = buffered; +} + +/** + * g_io_channel_get_buffered: + * @channel: a #GIOChannel + * + * Returns whether @channel is buffered. + * + * Return Value: %TRUE if the @channel is buffered. + **/ +gboolean +g_io_channel_get_buffered (GIOChannel *channel) +{ + g_return_val_if_fail (channel != NULL, FALSE); + + return channel->use_buffer; +} + +/** + * g_io_channel_set_encoding: + * @channel: a #GIOChannel + * @encoding: the encoding type + * @error: location to store an error of type #GConvertError + * + * Sets the encoding for the input/output of the channel. + * The internal encoding is always UTF-8. The default encoding + * for the external file is UTF-8. + * + * The encoding %NULL is safe to use with binary data. + * + * The encoding can only be set if one of the following conditions + * is true: + * + * + * The channel was just created, and has not been written to or read + * from yet. + * + * + * The channel is write-only. + * + * + * The channel is a file, and the file pointer was just + * repositioned by a call to g_io_channel_seek_position(). + * (This flushes all the internal buffers.) + * + * + * The current encoding is %NULL or UTF-8. + * + * + * One of the (new API) read functions has just returned %G_IO_STATUS_EOF + * (or, in the case of g_io_channel_read_to_end(), %G_IO_STATUS_NORMAL). + * + * + * One of the functions g_io_channel_read_chars() or + * g_io_channel_read_unichar() has returned %G_IO_STATUS_AGAIN or + * %G_IO_STATUS_ERROR. This may be useful in the case of + * %G_CONVERT_ERROR_ILLEGAL_SEQUENCE. + * Returning one of these statuses from g_io_channel_read_line(), + * g_io_channel_read_line_string(), or g_io_channel_read_to_end() + * does not guarantee that the encoding can + * be changed. + * + * + * Channels which do not meet one of the above conditions cannot call + * g_io_channel_seek_position() with an offset of %G_SEEK_CUR, and, if + * they are "seekable", cannot call g_io_channel_write_chars() after + * calling one of the API "read" functions. + * + * Return Value: %G_IO_STATUS_NORMAL if the encoding was successfully set. + **/ +GIOStatus +g_io_channel_set_encoding (GIOChannel *channel, + const gchar *encoding, + GError **error) +{ + GIConv read_cd, write_cd; + gboolean did_encode; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); + + /* Make sure the encoded buffers are empty */ + + g_return_val_if_fail (!channel->do_encode || !channel->encoded_read_buf || + channel->encoded_read_buf->len == 0, G_IO_STATUS_ERROR); + + if (!channel->use_buffer) + { + g_warning ("Need to set the channel buffered before setting the encoding.\n"); + g_warning ("Assuming this is what you meant and acting accordingly.\n"); + + channel->use_buffer = TRUE; + } + + if (channel->partial_write_buf[0] != '\0') + { + g_warning ("Partial character at end of write buffer not flushed.\n"); + channel->partial_write_buf[0] = '\0'; + } + + did_encode = channel->do_encode; + + if (!encoding || strcmp (encoding, "UTF8") == 0 || strcmp (encoding, "UTF-8") == 0) + { + channel->do_encode = FALSE; + read_cd = write_cd = (GIConv) -1; + } + else + { + gint err = 0; + const gchar *from_enc = NULL, *to_enc = NULL; + + if (channel->is_readable) + { + read_cd = g_iconv_open ("UTF-8", encoding); + + if (read_cd == (GIConv) -1) + { + err = errno; + from_enc = encoding; + to_enc = "UTF-8"; + } + } + else + read_cd = (GIConv) -1; + + if (channel->is_writeable && err == 0) + { + write_cd = g_iconv_open (encoding, "UTF-8"); + + if (write_cd == (GIConv) -1) + { + err = errno; + from_enc = "UTF-8"; + to_enc = encoding; + } + } + else + write_cd = (GIConv) -1; + + if (err != 0) + { + g_assert (from_enc); + g_assert (to_enc); + + if (err == EINVAL) + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION, + _("Conversion from character set '%s' to '%s' is not supported"), + from_enc, to_enc); + else + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Could not open converter from '%s' to '%s': %s"), + from_enc, to_enc, g_strerror (err)); + + if (read_cd != (GIConv) -1) + g_iconv_close (read_cd); + if (write_cd != (GIConv) -1) + g_iconv_close (write_cd); + + return G_IO_STATUS_ERROR; + } + + channel->do_encode = TRUE; + } + + /* The encoding is ok, so set the fields in channel */ + + if (channel->read_cd != (GIConv) -1) + g_iconv_close (channel->read_cd); + if (channel->write_cd != (GIConv) -1) + g_iconv_close (channel->write_cd); + + if (channel->encoded_read_buf && channel->encoded_read_buf->len > 0) + { + g_assert (!did_encode); /* Encoding UTF-8, NULL doesn't use encoded_read_buf */ + + /* This is just validated UTF-8, so we can copy it back into read_buf + * so it can be encoded in whatever the new encoding is. + */ + + g_string_prepend_len (channel->read_buf, channel->encoded_read_buf->str, + channel->encoded_read_buf->len); + g_string_truncate (channel->encoded_read_buf, 0); + } + + channel->read_cd = read_cd; + channel->write_cd = write_cd; + + g_free (channel->encoding); + channel->encoding = g_strdup (encoding); + + return G_IO_STATUS_NORMAL; +} + +/** + * g_io_channel_get_encoding: + * @channel: a #GIOChannel + * + * Gets the encoding for the input/output of the channel. + * The internal encoding is always UTF-8. The encoding %NULL + * makes the channel safe for binary data. + * + * Return value: A string containing the encoding, this string is + * owned by GLib and must not be freed. + **/ +const gchar * +g_io_channel_get_encoding (GIOChannel *channel) +{ + g_return_val_if_fail (channel != NULL, NULL); + + return channel->encoding; +} + +static GIOStatus +g_io_channel_fill_buffer (GIOChannel *channel, + GError **err) +{ + gsize read_size, cur_len, oldlen; + GIOStatus status; + + if (channel->is_seekable && channel->write_buf && channel->write_buf->len > 0) + { + status = g_io_channel_flush (channel, err); + if (status != G_IO_STATUS_NORMAL) + return status; + } + if (channel->is_seekable && channel->partial_write_buf[0] != '\0') + { + g_warning ("Partial character at end of write buffer not flushed.\n"); + channel->partial_write_buf[0] = '\0'; + } + + if (!channel->read_buf) + channel->read_buf = g_string_sized_new (channel->buf_size); + + cur_len = channel->read_buf->len; + + g_string_set_size (channel->read_buf, channel->read_buf->len + channel->buf_size); + + status = channel->funcs->io_read (channel, channel->read_buf->str + cur_len, + channel->buf_size, &read_size, err); + + g_assert ((status == G_IO_STATUS_NORMAL) || (read_size == 0)); + + g_string_truncate (channel->read_buf, read_size + cur_len); + + if ((status != G_IO_STATUS_NORMAL) && + ((status != G_IO_STATUS_EOF) || (channel->read_buf->len == 0))) + return status; + + g_assert (channel->read_buf->len > 0); + + if (channel->encoded_read_buf) + oldlen = channel->encoded_read_buf->len; + else + { + oldlen = 0; + if (channel->encoding) + channel->encoded_read_buf = g_string_sized_new (channel->buf_size); + } + + if (channel->do_encode) + { + gsize errnum, inbytes_left, outbytes_left; + gchar *inbuf, *outbuf; + int errval; + + g_assert (channel->encoded_read_buf); + +reencode: + + inbytes_left = channel->read_buf->len; + outbytes_left = MAX (channel->read_buf->len, + channel->encoded_read_buf->allocated_len + - channel->encoded_read_buf->len - 1); /* 1 for NULL */ + outbytes_left = MAX (outbytes_left, 6); + + inbuf = channel->read_buf->str; + g_string_set_size (channel->encoded_read_buf, + channel->encoded_read_buf->len + outbytes_left); + outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len + - outbytes_left; + + errnum = g_iconv (channel->read_cd, &inbuf, &inbytes_left, + &outbuf, &outbytes_left); + errval = errno; + + g_assert (inbuf + inbytes_left == channel->read_buf->str + + channel->read_buf->len); + g_assert (outbuf + outbytes_left == channel->encoded_read_buf->str + + channel->encoded_read_buf->len); + + g_string_erase (channel->read_buf, 0, + channel->read_buf->len - inbytes_left); + g_string_truncate (channel->encoded_read_buf, + channel->encoded_read_buf->len - outbytes_left); + + if (errnum == (gsize) -1) + { + switch (errval) + { + case EINVAL: + if ((oldlen == channel->encoded_read_buf->len) + && (status == G_IO_STATUS_EOF)) + status = G_IO_STATUS_EOF; + else + status = G_IO_STATUS_NORMAL; + break; + case E2BIG: + /* Buffer size at least 6, wrote at least on character */ + g_assert (inbuf != channel->read_buf->str); + goto reencode; + case EILSEQ: + if (oldlen < channel->encoded_read_buf->len) + status = G_IO_STATUS_NORMAL; + else + { + g_set_error_literal (err, G_CONVERT_ERROR, + G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + return G_IO_STATUS_ERROR; + } + break; + default: + g_assert (errval != EBADF); /* The converter should be open */ + g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Error during conversion: %s"), g_strerror (errval)); + return G_IO_STATUS_ERROR; + } + } + g_assert ((status != G_IO_STATUS_NORMAL) + || (channel->encoded_read_buf->len > 0)); + } + else if (channel->encoding) /* UTF-8 */ + { + gchar *nextchar, *lastchar; + + g_assert (channel->encoded_read_buf); + + nextchar = channel->read_buf->str; + lastchar = channel->read_buf->str + channel->read_buf->len; + + while (nextchar < lastchar) + { + gunichar val_char; + + val_char = g_utf8_get_char_validated (nextchar, lastchar - nextchar); + + switch (val_char) + { + case -2: + /* stop, leave partial character in buffer */ + lastchar = nextchar; + break; + case -1: + if (oldlen < channel->encoded_read_buf->len) + status = G_IO_STATUS_NORMAL; + else + { + g_set_error_literal (err, G_CONVERT_ERROR, + G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + status = G_IO_STATUS_ERROR; + } + lastchar = nextchar; + break; + default: + nextchar = g_utf8_next_char (nextchar); + break; + } + } + + if (lastchar > channel->read_buf->str) + { + gint copy_len = lastchar - channel->read_buf->str; + + g_string_append_len (channel->encoded_read_buf, channel->read_buf->str, + copy_len); + g_string_erase (channel->read_buf, 0, copy_len); + } + } + + return status; +} + +/** + * g_io_channel_read_line: + * @channel: a #GIOChannel + * @str_return: The line read from the #GIOChannel, including the + * line terminator. This data should be freed with g_free() + * when no longer needed. This is a nul-terminated string. + * If a @length of zero is returned, this will be %NULL instead. + * @length: location to store length of the read data, or %NULL + * @terminator_pos: location to store position of line terminator, or %NULL + * @error: A location to return an error of type #GConvertError + * or #GIOChannelError + * + * Reads a line, including the terminating character(s), + * from a #GIOChannel into a newly-allocated string. + * @str_return will contain allocated memory if the return + * is %G_IO_STATUS_NORMAL. + * + * Return value: the status of the operation. + **/ +GIOStatus +g_io_channel_read_line (GIOChannel *channel, + gchar **str_return, + gsize *length, + gsize *terminator_pos, + GError **error) +{ + GIOStatus status; + gsize got_length; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail (str_return != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); + + status = g_io_channel_read_line_backend (channel, &got_length, terminator_pos, error); + + if (length) + *length = got_length; + + if (status == G_IO_STATUS_NORMAL) + { + g_assert (USE_BUF (channel)); + *str_return = g_strndup (USE_BUF (channel)->str, got_length); + g_string_erase (USE_BUF (channel), 0, got_length); + } + else + *str_return = NULL; + + return status; +} + +/** + * g_io_channel_read_line_string: + * @channel: a #GIOChannel + * @buffer: a #GString into which the line will be written. + * If @buffer already contains data, the old data will + * be overwritten. + * @terminator_pos: location to store position of line terminator, or %NULL + * @error: a location to store an error of type #GConvertError + * or #GIOChannelError + * + * Reads a line from a #GIOChannel, using a #GString as a buffer. + * + * Return value: the status of the operation. + **/ +GIOStatus +g_io_channel_read_line_string (GIOChannel *channel, + GString *buffer, + gsize *terminator_pos, + GError **error) +{ + gsize length; + GIOStatus status; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail (buffer != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); + + if (buffer->len > 0) + g_string_truncate (buffer, 0); /* clear out the buffer */ + + status = g_io_channel_read_line_backend (channel, &length, terminator_pos, error); + + if (status == G_IO_STATUS_NORMAL) + { + g_assert (USE_BUF (channel)); + g_string_append_len (buffer, USE_BUF (channel)->str, length); + g_string_erase (USE_BUF (channel), 0, length); + } + + return status; +} + + +static GIOStatus +g_io_channel_read_line_backend (GIOChannel *channel, + gsize *length, + gsize *terminator_pos, + GError **error) +{ + GIOStatus status; + gsize checked_to, line_term_len, line_length, got_term_len; + gboolean first_time = TRUE; + + if (!channel->use_buffer) + { + /* Can't do a raw read in read_line */ + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Can't do a raw read in g_io_channel_read_line_string")); + return G_IO_STATUS_ERROR; + } + + status = G_IO_STATUS_NORMAL; + + if (channel->line_term) + line_term_len = channel->line_term_len; + else + line_term_len = 3; + /* This value used for setting checked_to, it's the longest of the four + * we autodetect for. + */ + + checked_to = 0; + + while (TRUE) + { + gchar *nextchar, *lastchar; + GString *use_buf; + + if (!first_time || (BUF_LEN (USE_BUF (channel)) == 0)) + { +read_again: + status = g_io_channel_fill_buffer (channel, error); + switch (status) + { + case G_IO_STATUS_NORMAL: + if (BUF_LEN (USE_BUF (channel)) == 0) + /* Can happen when using conversion and only read + * part of a character + */ + { + first_time = FALSE; + continue; + } + break; + case G_IO_STATUS_EOF: + if (BUF_LEN (USE_BUF (channel)) == 0) + { + if (length) + *length = 0; + + if (channel->encoding && channel->read_buf->len != 0) + { + g_set_error_literal (error, G_CONVERT_ERROR, + G_CONVERT_ERROR_PARTIAL_INPUT, + _("Leftover unconverted data in " + "read buffer")); + return G_IO_STATUS_ERROR; + } + else + return G_IO_STATUS_EOF; + } + break; + default: + if (length) + *length = 0; + return status; + } + } + + g_assert (BUF_LEN (USE_BUF (channel)) != 0); + + use_buf = USE_BUF (channel); /* The buffer has been created by this point */ + + first_time = FALSE; + + lastchar = use_buf->str + use_buf->len; + + for (nextchar = use_buf->str + checked_to; nextchar < lastchar; + channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++) + { + if (channel->line_term) + { + if (memcmp (channel->line_term, nextchar, line_term_len) == 0) + { + line_length = nextchar - use_buf->str; + got_term_len = line_term_len; + goto done; + } + } + else /* auto detect */ + { + switch (*nextchar) + { + case '\n': /* unix */ + line_length = nextchar - use_buf->str; + got_term_len = 1; + goto done; + case '\r': /* Warning: do not use with sockets */ + line_length = nextchar - use_buf->str; + if ((nextchar == lastchar - 1) && (status != G_IO_STATUS_EOF) + && (lastchar == use_buf->str + use_buf->len)) + goto read_again; /* Try to read more data */ + if ((nextchar < lastchar - 1) && (*(nextchar + 1) == '\n')) /* dos */ + got_term_len = 2; + else /* mac */ + got_term_len = 1; + goto done; + case '\xe2': /* Unicode paragraph separator */ + if (strncmp ("\xe2\x80\xa9", nextchar, 3) == 0) + { + line_length = nextchar - use_buf->str; + got_term_len = 3; + goto done; + } + break; + case '\0': /* Embeded null in input */ + line_length = nextchar - use_buf->str; + got_term_len = 1; + goto done; + default: /* no match */ + break; + } + } + } + + /* If encoding != NULL, valid UTF-8, didn't overshoot */ + g_assert (nextchar == lastchar); + + /* Check for EOF */ + + if (status == G_IO_STATUS_EOF) + { + if (channel->encoding && channel->read_buf->len > 0) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + _("Channel terminates in a partial character")); + return G_IO_STATUS_ERROR; + } + line_length = use_buf->len; + got_term_len = 0; + break; + } + + if (use_buf->len > line_term_len - 1) + checked_to = use_buf->len - (line_term_len - 1); + else + checked_to = 0; + } + +done: + + if (terminator_pos) + *terminator_pos = line_length; + + if (length) + *length = line_length + got_term_len; + + return G_IO_STATUS_NORMAL; +} + +/** + * g_io_channel_read_to_end: + * @channel: a #GIOChannel + * @str_return: Location to store a pointer to a string holding + * the remaining data in the #GIOChannel. This data should + * be freed with g_free() when no longer needed. This + * data is terminated by an extra nul character, but there + * may be other nuls in the intervening data. + * @length: location to store length of the data + * @error: location to return an error of type #GConvertError + * or #GIOChannelError + * + * Reads all the remaining data from the file. + * + * Return value: %G_IO_STATUS_NORMAL on success. + * This function never returns %G_IO_STATUS_EOF. + **/ +GIOStatus +g_io_channel_read_to_end (GIOChannel *channel, + gchar **str_return, + gsize *length, + GError **error) +{ + GIOStatus status; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); + + if (str_return) + *str_return = NULL; + if (length) + *length = 0; + + if (!channel->use_buffer) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Can't do a raw read in g_io_channel_read_to_end")); + return G_IO_STATUS_ERROR; + } + + do + status = g_io_channel_fill_buffer (channel, error); + while (status == G_IO_STATUS_NORMAL); + + if (status != G_IO_STATUS_EOF) + return status; + + if (channel->encoding && channel->read_buf->len > 0) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + _("Channel terminates in a partial character")); + return G_IO_STATUS_ERROR; + } + + if (USE_BUF (channel) == NULL) + { + /* length is already set to zero */ + if (str_return) + *str_return = g_strdup (""); + } + else + { + if (length) + *length = USE_BUF (channel)->len; + + if (str_return) + *str_return = g_string_free (USE_BUF (channel), FALSE); + else + g_string_free (USE_BUF (channel), TRUE); + + if (channel->encoding) + channel->encoded_read_buf = NULL; + else + channel->read_buf = NULL; + } + + return G_IO_STATUS_NORMAL; +} + +/** + * g_io_channel_read_chars: + * @channel: a #GIOChannel + * @buf: a buffer to read data into + * @count: the size of the buffer. Note that the buffer may not be + * complelely filled even if there is data in the buffer if the + * remaining data is not a complete character. + * @bytes_read: (allow-none): The number of bytes read. This may be + * zero even on success if count < 6 and the channel's encoding + * is non-%NULL. This indicates that the next UTF-8 character is + * too wide for the buffer. + * @error: a location to return an error of type #GConvertError + * or #GIOChannelError. + * + * Replacement for g_io_channel_read() with the new API. + * + * Return value: the status of the operation. + */ +GIOStatus +g_io_channel_read_chars (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read, + GError **error) +{ + GIOStatus status; + gsize got_bytes; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); + + if (count == 0) + { + if (bytes_read) + *bytes_read = 0; + return G_IO_STATUS_NORMAL; + } + g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR); + + if (!channel->use_buffer) + { + gsize tmp_bytes; + + g_assert (!channel->read_buf || channel->read_buf->len == 0); + + status = channel->funcs->io_read (channel, buf, count, &tmp_bytes, error); + + if (bytes_read) + *bytes_read = tmp_bytes; + + return status; + } + + status = G_IO_STATUS_NORMAL; + + while (BUF_LEN (USE_BUF (channel)) < count && status == G_IO_STATUS_NORMAL) + status = g_io_channel_fill_buffer (channel, error); + + /* Only return an error if we have no data */ + + if (BUF_LEN (USE_BUF (channel)) == 0) + { + g_assert (status != G_IO_STATUS_NORMAL); + + if (status == G_IO_STATUS_EOF && channel->encoding + && BUF_LEN (channel->read_buf) > 0) + { + g_set_error_literal (error, G_CONVERT_ERROR, + G_CONVERT_ERROR_PARTIAL_INPUT, + _("Leftover unconverted data in read buffer")); + status = G_IO_STATUS_ERROR; + } + + if (bytes_read) + *bytes_read = 0; + + return status; + } + + if (status == G_IO_STATUS_ERROR) + g_clear_error (error); + + got_bytes = MIN (count, BUF_LEN (USE_BUF (channel))); + + g_assert (got_bytes > 0); + + if (channel->encoding) + /* Don't validate for NULL encoding, binary safe */ + { + gchar *nextchar, *prevchar; + + g_assert (USE_BUF (channel) == channel->encoded_read_buf); + + nextchar = channel->encoded_read_buf->str; + + do + { + prevchar = nextchar; + nextchar = g_utf8_next_char (nextchar); + g_assert (nextchar != prevchar); /* Possible for *prevchar of -1 or -2 */ + } + while (nextchar < channel->encoded_read_buf->str + got_bytes); + + if (nextchar > channel->encoded_read_buf->str + got_bytes) + got_bytes = prevchar - channel->encoded_read_buf->str; + + g_assert (got_bytes > 0 || count < 6); + } + + memcpy (buf, USE_BUF (channel)->str, got_bytes); + g_string_erase (USE_BUF (channel), 0, got_bytes); + + if (bytes_read) + *bytes_read = got_bytes; + + return G_IO_STATUS_NORMAL; +} + +/** + * g_io_channel_read_unichar: + * @channel: a #GIOChannel + * @thechar: a location to return a character + * @error: a location to return an error of type #GConvertError + * or #GIOChannelError + * + * Reads a Unicode character from @channel. + * This function cannot be called on a channel with %NULL encoding. + * + * Return value: a #GIOStatus + **/ +GIOStatus +g_io_channel_read_unichar (GIOChannel *channel, + gunichar *thechar, + GError **error) +{ + GIOStatus status = G_IO_STATUS_NORMAL; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR); + + while (BUF_LEN (channel->encoded_read_buf) == 0 && status == G_IO_STATUS_NORMAL) + status = g_io_channel_fill_buffer (channel, error); + + /* Only return an error if we have no data */ + + if (BUF_LEN (USE_BUF (channel)) == 0) + { + g_assert (status != G_IO_STATUS_NORMAL); + + if (status == G_IO_STATUS_EOF && BUF_LEN (channel->read_buf) > 0) + { + g_set_error_literal (error, G_CONVERT_ERROR, + G_CONVERT_ERROR_PARTIAL_INPUT, + _("Leftover unconverted data in read buffer")); + status = G_IO_STATUS_ERROR; + } + + if (thechar) + *thechar = (gunichar) -1; + + return status; + } + + if (status == G_IO_STATUS_ERROR) + g_clear_error (error); + + if (thechar) + *thechar = g_utf8_get_char (channel->encoded_read_buf->str); + + g_string_erase (channel->encoded_read_buf, 0, + g_utf8_next_char (channel->encoded_read_buf->str) + - channel->encoded_read_buf->str); + + return G_IO_STATUS_NORMAL; +} + +/** + * g_io_channel_write_chars: + * @channel: a #GIOChannel + * @buf: a buffer to write data from + * @count: the size of the buffer. If -1, the buffer + * is taken to be a nul-terminated string. + * @bytes_written: The number of bytes written. This can be nonzero + * even if the return value is not %G_IO_STATUS_NORMAL. + * If the return value is %G_IO_STATUS_NORMAL and the + * channel is blocking, this will always be equal + * to @count if @count >= 0. + * @error: a location to return an error of type #GConvertError + * or #GIOChannelError + * + * Replacement for g_io_channel_write() with the new API. + * + * On seekable channels with encodings other than %NULL or UTF-8, generic + * mixing of reading and writing is not allowed. A call to g_io_channel_write_chars () + * may only be made on a channel from which data has been read in the + * cases described in the documentation for g_io_channel_set_encoding (). + * + * Return value: the status of the operation. + **/ +GIOStatus +g_io_channel_write_chars (GIOChannel *channel, + const gchar *buf, + gssize count, + gsize *bytes_written, + GError **error) +{ + GIOStatus status; + gssize wrote_bytes = 0; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR); + + if ((count < 0) && buf) + count = strlen (buf); + + if (count == 0) + { + if (bytes_written) + *bytes_written = 0; + return G_IO_STATUS_NORMAL; + } + + g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail (count > 0, G_IO_STATUS_ERROR); + + /* Raw write case */ + + if (!channel->use_buffer) + { + gsize tmp_bytes; + + g_assert (!channel->write_buf || channel->write_buf->len == 0); + g_assert (channel->partial_write_buf[0] == '\0'); + + status = channel->funcs->io_write (channel, buf, count, &tmp_bytes, error); + + if (bytes_written) + *bytes_written = tmp_bytes; + + return status; + } + + /* General case */ + + if (channel->is_seekable && (( BUF_LEN (channel->read_buf) > 0) + || (BUF_LEN (channel->encoded_read_buf) > 0))) + { + if (channel->do_encode && BUF_LEN (channel->encoded_read_buf) > 0) + { + g_warning("Mixed reading and writing not allowed on encoded files"); + return G_IO_STATUS_ERROR; + } + status = g_io_channel_seek_position (channel, 0, G_SEEK_CUR, error); + if (status != G_IO_STATUS_NORMAL) + { + if (bytes_written) + *bytes_written = 0; + return status; + } + } + + if (!channel->write_buf) + channel->write_buf = g_string_sized_new (channel->buf_size); + + while (wrote_bytes < count) + { + gsize space_in_buf; + + /* If the buffer is full, try a write immediately. In + * the nonblocking case, this prevents the user from + * writing just a little bit to the buffer every time + * and never receiving an EAGAIN. + */ + + if (channel->write_buf->len >= channel->buf_size - MAX_CHAR_SIZE) + { + gsize did_write = 0, this_time; + + do + { + status = channel->funcs->io_write (channel, channel->write_buf->str + + did_write, channel->write_buf->len + - did_write, &this_time, error); + did_write += this_time; + } + while (status == G_IO_STATUS_NORMAL && + did_write < MIN (channel->write_buf->len, MAX_CHAR_SIZE)); + + g_string_erase (channel->write_buf, 0, did_write); + + if (status != G_IO_STATUS_NORMAL) + { + if (status == G_IO_STATUS_AGAIN && wrote_bytes > 0) + status = G_IO_STATUS_NORMAL; + if (bytes_written) + *bytes_written = wrote_bytes; + return status; + } + } + + space_in_buf = MAX (channel->buf_size, channel->write_buf->allocated_len - 1) + - channel->write_buf->len; /* 1 for NULL */ + + /* This is only true because g_io_channel_set_buffer_size () + * ensures that channel->buf_size >= MAX_CHAR_SIZE. + */ + g_assert (space_in_buf >= MAX_CHAR_SIZE); + + if (!channel->encoding) + { + gssize write_this = MIN (space_in_buf, count - wrote_bytes); + + g_string_append_len (channel->write_buf, buf, write_this); + buf += write_this; + wrote_bytes += write_this; + } + else + { + const gchar *from_buf; + gsize from_buf_len, from_buf_old_len, left_len; + gsize err; + gint errnum; + + if (channel->partial_write_buf[0] != '\0') + { + g_assert (wrote_bytes == 0); + + from_buf = channel->partial_write_buf; + from_buf_old_len = strlen (channel->partial_write_buf); + g_assert (from_buf_old_len > 0); + from_buf_len = MIN (6, from_buf_old_len + count); + + memcpy (channel->partial_write_buf + from_buf_old_len, buf, + from_buf_len - from_buf_old_len); + } + else + { + from_buf = buf; + from_buf_len = count - wrote_bytes; + from_buf_old_len = 0; + } + +reconvert: + + if (!channel->do_encode) /* UTF-8 encoding */ + { + const gchar *badchar; + gsize try_len = MIN (from_buf_len, space_in_buf); + + /* UTF-8, just validate, emulate g_iconv */ + + if (!g_utf8_validate (from_buf, try_len, &badchar)) + { + gunichar try_char; + gsize incomplete_len = from_buf + try_len - badchar; + + left_len = from_buf + from_buf_len - badchar; + + try_char = g_utf8_get_char_validated (badchar, incomplete_len); + + switch (try_char) + { + case -2: + g_assert (incomplete_len < 6); + if (try_len == from_buf_len) + { + errnum = EINVAL; + err = (gsize) -1; + } + else + { + errnum = 0; + err = (gsize) 0; + } + break; + case -1: + g_warning ("Invalid UTF-8 passed to g_io_channel_write_chars()."); + /* FIXME bail here? */ + errnum = EILSEQ; + err = (gsize) -1; + break; + default: + g_assert_not_reached (); + err = (gsize) -1; + errnum = 0; /* Don't confunse the compiler */ + } + } + else + { + err = (gsize) 0; + errnum = 0; + left_len = from_buf_len - try_len; + } + + g_string_append_len (channel->write_buf, from_buf, + from_buf_len - left_len); + from_buf += from_buf_len - left_len; + } + else + { + gchar *outbuf; + + left_len = from_buf_len; + g_string_set_size (channel->write_buf, channel->write_buf->len + + space_in_buf); + outbuf = channel->write_buf->str + channel->write_buf->len + - space_in_buf; + err = g_iconv (channel->write_cd, (gchar **) &from_buf, &left_len, + &outbuf, &space_in_buf); + errnum = errno; + g_string_truncate (channel->write_buf, channel->write_buf->len + - space_in_buf); + } + + if (err == (gsize) -1) + { + switch (errnum) + { + case EINVAL: + g_assert (left_len < 6); + + if (from_buf_old_len == 0) + { + /* Not from partial_write_buf */ + + memcpy (channel->partial_write_buf, from_buf, left_len); + channel->partial_write_buf[left_len] = '\0'; + if (bytes_written) + *bytes_written = count; + return G_IO_STATUS_NORMAL; + } + + /* Working in partial_write_buf */ + + if (left_len == from_buf_len) + { + /* Didn't convert anything, must still have + * less than a full character + */ + + g_assert (count == from_buf_len - from_buf_old_len); + + channel->partial_write_buf[from_buf_len] = '\0'; + + if (bytes_written) + *bytes_written = count; + + return G_IO_STATUS_NORMAL; + } + + g_assert (from_buf_len - left_len >= from_buf_old_len); + + /* We converted all the old data. This is fine */ + + break; + case E2BIG: + if (from_buf_len == left_len) + { + /* Nothing was written, add enough space for + * at least one character. + */ + space_in_buf += MAX_CHAR_SIZE; + goto reconvert; + } + break; + case EILSEQ: + g_set_error_literal (error, G_CONVERT_ERROR, + G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + if (from_buf_old_len > 0 && from_buf_len == left_len) + g_warning ("Illegal sequence due to partial character " + "at the end of a previous write.\n"); + else + wrote_bytes += from_buf_len - left_len - from_buf_old_len; + if (bytes_written) + *bytes_written = wrote_bytes; + channel->partial_write_buf[0] = '\0'; + return G_IO_STATUS_ERROR; + default: + g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED, + _("Error during conversion: %s"), g_strerror (errnum)); + if (from_buf_len >= left_len + from_buf_old_len) + wrote_bytes += from_buf_len - left_len - from_buf_old_len; + if (bytes_written) + *bytes_written = wrote_bytes; + channel->partial_write_buf[0] = '\0'; + return G_IO_STATUS_ERROR; + } + } + + g_assert (from_buf_len - left_len >= from_buf_old_len); + + wrote_bytes += from_buf_len - left_len - from_buf_old_len; + + if (from_buf_old_len > 0) + { + /* We were working in partial_write_buf */ + + buf += from_buf_len - left_len - from_buf_old_len; + channel->partial_write_buf[0] = '\0'; + } + else + buf = from_buf; + } + } + + if (bytes_written) + *bytes_written = count; + + return G_IO_STATUS_NORMAL; +} + +/** + * g_io_channel_write_unichar: + * @channel: a #GIOChannel + * @thechar: a character + * @error: location to return an error of type #GConvertError + * or #GIOChannelError + * + * Writes a Unicode character to @channel. + * This function cannot be called on a channel with %NULL encoding. + * + * Return value: a #GIOStatus + **/ +GIOStatus +g_io_channel_write_unichar (GIOChannel *channel, + gunichar thechar, + GError **error) +{ + GIOStatus status; + gchar static_buf[6]; + gsize char_len, wrote_len; + + g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR); + g_return_val_if_fail ((error == NULL) || (*error == NULL), + G_IO_STATUS_ERROR); + g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR); + + char_len = g_unichar_to_utf8 (thechar, static_buf); + + if (channel->partial_write_buf[0] != '\0') + { + g_warning ("Partial charater written before writing unichar.\n"); + channel->partial_write_buf[0] = '\0'; + } + + status = g_io_channel_write_chars (channel, static_buf, + char_len, &wrote_len, error); + + /* We validate UTF-8, so we can't get a partial write */ + + g_assert (wrote_len == char_len || status != G_IO_STATUS_NORMAL); + + return status; +} + +/** + * g_io_channel_error_quark: + * + * Return value: the quark used as %G_IO_CHANNEL_ERROR + **/ +/** + * G_IO_CHANNEL_ERROR: + * + * Error domain for #GIOChannel operations. Errors in this domain will + * be from the #GIOChannelError enumeration. See #GError for + * information on error domains. + **/ +/** + * GIOChannelError: + * @G_IO_CHANNEL_ERROR_FBIG: File too large. + * @G_IO_CHANNEL_ERROR_INVAL: Invalid argument. + * @G_IO_CHANNEL_ERROR_IO: IO error. + * @G_IO_CHANNEL_ERROR_ISDIR: File is a directory. + * @G_IO_CHANNEL_ERROR_NOSPC: No space left on device. + * @G_IO_CHANNEL_ERROR_NXIO: No such device or address. + * @G_IO_CHANNEL_ERROR_OVERFLOW: Value too large for defined datatype. + * @G_IO_CHANNEL_ERROR_PIPE: Broken pipe. + * @G_IO_CHANNEL_ERROR_FAILED: Some other error. + * + * Error codes returned by #GIOChannel operations. + **/ +GQuark +g_io_channel_error_quark (void) +{ + return g_quark_from_static_string ("g-io-channel-error-quark"); +} diff --git a/glib/glib/giochannel.h b/glib/glib/giochannel.h new file mode 100644 index 0000000..8d3f2d7 --- /dev/null +++ b/glib/glib/giochannel.h @@ -0,0 +1,374 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_IOCHANNEL_H__ +#define __G_IOCHANNEL_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +/* GIOChannel + */ + +typedef struct _GIOChannel GIOChannel; +typedef struct _GIOFuncs GIOFuncs; + +typedef enum +{ + G_IO_ERROR_NONE, + G_IO_ERROR_AGAIN, + G_IO_ERROR_INVAL, + G_IO_ERROR_UNKNOWN +} GIOError; + +#define G_IO_CHANNEL_ERROR g_io_channel_error_quark() + +typedef enum +{ + /* Derived from errno */ + G_IO_CHANNEL_ERROR_FBIG, + G_IO_CHANNEL_ERROR_INVAL, + G_IO_CHANNEL_ERROR_IO, + G_IO_CHANNEL_ERROR_ISDIR, + G_IO_CHANNEL_ERROR_NOSPC, + G_IO_CHANNEL_ERROR_NXIO, + G_IO_CHANNEL_ERROR_OVERFLOW, + G_IO_CHANNEL_ERROR_PIPE, + /* Other */ + G_IO_CHANNEL_ERROR_FAILED +} GIOChannelError; + +typedef enum +{ + G_IO_STATUS_ERROR, + G_IO_STATUS_NORMAL, + G_IO_STATUS_EOF, + G_IO_STATUS_AGAIN +} GIOStatus; + +typedef enum +{ + G_SEEK_CUR, + G_SEEK_SET, + G_SEEK_END +} GSeekType; + +typedef enum /*< flags >*/ +{ + G_IO_IN GLIB_SYSDEF_POLLIN, + G_IO_OUT GLIB_SYSDEF_POLLOUT, + G_IO_PRI GLIB_SYSDEF_POLLPRI, + G_IO_ERR GLIB_SYSDEF_POLLERR, + G_IO_HUP GLIB_SYSDEF_POLLHUP, + G_IO_NVAL GLIB_SYSDEF_POLLNVAL +} GIOCondition; + +typedef enum +{ + G_IO_FLAG_APPEND = 1 << 0, + G_IO_FLAG_NONBLOCK = 1 << 1, + G_IO_FLAG_IS_READABLE = 1 << 2, /* Read only flag */ + G_IO_FLAG_IS_WRITABLE = 1 << 3, /* Read only flag */ + G_IO_FLAG_IS_SEEKABLE = 1 << 4, /* Read only flag */ + G_IO_FLAG_MASK = (1 << 5) - 1, + G_IO_FLAG_GET_MASK = G_IO_FLAG_MASK, + G_IO_FLAG_SET_MASK = G_IO_FLAG_APPEND | G_IO_FLAG_NONBLOCK +} GIOFlags; + +/* Misspelling in enum in 2.29.10 and earlier */ +#define G_IO_FLAG_IS_WRITEABLE (G_IO_FLAG_IS_WRITABLE) + +struct _GIOChannel +{ + /*< private >*/ + gint ref_count; + GIOFuncs *funcs; + + gchar *encoding; + GIConv read_cd; + GIConv write_cd; + gchar *line_term; /* String which indicates the end of a line of text */ + guint line_term_len; /* So we can have null in the line term */ + + gsize buf_size; + GString *read_buf; /* Raw data from the channel */ + GString *encoded_read_buf; /* Channel data converted to UTF-8 */ + GString *write_buf; /* Data ready to be written to the file */ + gchar partial_write_buf[6]; /* UTF-8 partial characters, null terminated */ + + /* Group the flags together, immediately after partial_write_buf, to save memory */ + + guint use_buffer : 1; /* The encoding uses the buffers */ + guint do_encode : 1; /* The encoding uses the GIConv coverters */ + guint close_on_unref : 1; /* Close the channel on final unref */ + guint is_readable : 1; /* Cached GIOFlag */ + guint is_writeable : 1; /* ditto */ + guint is_seekable : 1; /* ditto */ + + gpointer reserved1; + gpointer reserved2; +}; + +typedef gboolean (*GIOFunc) (GIOChannel *source, + GIOCondition condition, + gpointer data); +struct _GIOFuncs +{ + GIOStatus (*io_read) (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read, + GError **err); + GIOStatus (*io_write) (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written, + GError **err); + GIOStatus (*io_seek) (GIOChannel *channel, + gint64 offset, + GSeekType type, + GError **err); + GIOStatus (*io_close) (GIOChannel *channel, + GError **err); + GSource* (*io_create_watch) (GIOChannel *channel, + GIOCondition condition); + void (*io_free) (GIOChannel *channel); + GIOStatus (*io_set_flags) (GIOChannel *channel, + GIOFlags flags, + GError **err); + GIOFlags (*io_get_flags) (GIOChannel *channel); +}; + +void g_io_channel_init (GIOChannel *channel); +GIOChannel *g_io_channel_ref (GIOChannel *channel); +void g_io_channel_unref (GIOChannel *channel); + +GLIB_DEPRECATED_FOR(g_io_channel_read_for) +GIOError g_io_channel_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read); + +GLIB_DEPRECATED_FOR(g_io_channel_write_chars) +GIOError g_io_channel_write (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written); + +GLIB_DEPRECATED_FOR(g_io_channel_seek_position) +GIOError g_io_channel_seek (GIOChannel *channel, + gint64 offset, + GSeekType type); + +GLIB_DEPRECATED_FOR(g_io_channel_shutdown) +void g_io_channel_close (GIOChannel *channel); + +GIOStatus g_io_channel_shutdown (GIOChannel *channel, + gboolean flush, + GError **err); +guint g_io_add_watch_full (GIOChannel *channel, + gint priority, + GIOCondition condition, + GIOFunc func, + gpointer user_data, + GDestroyNotify notify); +GSource * g_io_create_watch (GIOChannel *channel, + GIOCondition condition); +guint g_io_add_watch (GIOChannel *channel, + GIOCondition condition, + GIOFunc func, + gpointer user_data); + +/* character encoding conversion involved functions. + */ + +void g_io_channel_set_buffer_size (GIOChannel *channel, + gsize size); +gsize g_io_channel_get_buffer_size (GIOChannel *channel); +GIOCondition g_io_channel_get_buffer_condition (GIOChannel *channel); +GIOStatus g_io_channel_set_flags (GIOChannel *channel, + GIOFlags flags, + GError **error); +GIOFlags g_io_channel_get_flags (GIOChannel *channel); +void g_io_channel_set_line_term (GIOChannel *channel, + const gchar *line_term, + gint length); +const gchar * g_io_channel_get_line_term (GIOChannel *channel, + gint *length); +void g_io_channel_set_buffered (GIOChannel *channel, + gboolean buffered); +gboolean g_io_channel_get_buffered (GIOChannel *channel); +GIOStatus g_io_channel_set_encoding (GIOChannel *channel, + const gchar *encoding, + GError **error); +const gchar * g_io_channel_get_encoding (GIOChannel *channel); +void g_io_channel_set_close_on_unref (GIOChannel *channel, + gboolean do_close); +gboolean g_io_channel_get_close_on_unref (GIOChannel *channel); + + +GIOStatus g_io_channel_flush (GIOChannel *channel, + GError **error); +GIOStatus g_io_channel_read_line (GIOChannel *channel, + gchar **str_return, + gsize *length, + gsize *terminator_pos, + GError **error); +GIOStatus g_io_channel_read_line_string (GIOChannel *channel, + GString *buffer, + gsize *terminator_pos, + GError **error); +GIOStatus g_io_channel_read_to_end (GIOChannel *channel, + gchar **str_return, + gsize *length, + GError **error); +GIOStatus g_io_channel_read_chars (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read, + GError **error); +GIOStatus g_io_channel_read_unichar (GIOChannel *channel, + gunichar *thechar, + GError **error); +GIOStatus g_io_channel_write_chars (GIOChannel *channel, + const gchar *buf, + gssize count, + gsize *bytes_written, + GError **error); +GIOStatus g_io_channel_write_unichar (GIOChannel *channel, + gunichar thechar, + GError **error); +GIOStatus g_io_channel_seek_position (GIOChannel *channel, + gint64 offset, + GSeekType type, + GError **error); +#ifdef G_OS_WIN32 +#define g_io_channel_new_file g_io_channel_new_file_utf8 +#endif + +GIOChannel* g_io_channel_new_file (const gchar *filename, + const gchar *mode, + GError **error); + +/* Error handling */ + +GQuark g_io_channel_error_quark (void); +GIOChannelError g_io_channel_error_from_errno (gint en); + +/* On Unix, IO channels created with this function for any file + * descriptor or socket. + * + * On Win32, this can be used either for files opened with the MSVCRT + * (the Microsoft run-time C library) _open() or _pipe, including file + * descriptors 0, 1 and 2 (corresponding to stdin, stdout and stderr), + * or for Winsock SOCKETs. If the parameter is a legal file + * descriptor, it is assumed to be such, otherwise it should be a + * SOCKET. This relies on SOCKETs and file descriptors not + * overlapping. If you want to be certain, call either + * g_io_channel_win32_new_fd() or g_io_channel_win32_new_socket() + * instead as appropriate. + * + * The term file descriptor as used in the context of Win32 refers to + * the emulated Unix-like file descriptors MSVCRT provides. The native + * corresponding concept is file HANDLE. There isn't as of yet a way to + * get GIOChannels for Win32 file HANDLEs. + */ +GIOChannel* g_io_channel_unix_new (int fd); +gint g_io_channel_unix_get_fd (GIOChannel *channel); + + +/* Hook for GClosure / GSource integration. Don't touch */ +GLIB_VAR GSourceFuncs g_io_watch_funcs; + +#ifdef G_OS_WIN32 + +/* You can use this "pseudo file descriptor" in a GPollFD to add + * polling for Windows messages. GTK applications should not do that. + */ + +#define G_WIN32_MSG_HANDLE 19981206 + +/* Use this to get a GPollFD from a GIOChannel, so that you can call + * g_io_channel_win32_poll(). After calling this you should only use + * g_io_channel_read() to read from the GIOChannel, i.e. never read() + * from the underlying file descriptor. For SOCKETs, it is possible to call + * recv(). + */ +void g_io_channel_win32_make_pollfd (GIOChannel *channel, + GIOCondition condition, + GPollFD *fd); + +/* This can be used to wait a until at least one of the channels is readable. + * On Unix you would do a select() on the file descriptors of the channels. + */ +gint g_io_channel_win32_poll (GPollFD *fds, + gint n_fds, + gint timeout_); + +/* Create an IO channel for Windows messages for window handle hwnd. */ +#if GLIB_SIZEOF_VOID_P == 8 +/* We use gsize here so that it is still an integer type and not a + * pointer, like the guint in the traditional prototype. We can't use + * intptr_t as that is not portable enough. + */ +GIOChannel *g_io_channel_win32_new_messages (gsize hwnd); +#else +GIOChannel *g_io_channel_win32_new_messages (guint hwnd); +#endif + +/* Create an IO channel for C runtime (emulated Unix-like) file + * descriptors. After calling g_io_add_watch() on a IO channel + * returned by this function, you shouldn't call read() on the file + * descriptor. This is because adding polling for a file descriptor is + * implemented on Win32 by starting a thread that sits blocked in a + * read() from the file descriptor most of the time. All reads from + * the file descriptor should be done by this internal GLib + * thread. Your code should call only g_io_channel_read_chars(). + */ +GIOChannel* g_io_channel_win32_new_fd (gint fd); + +/* Get the C runtime file descriptor of a channel. */ +gint g_io_channel_win32_get_fd (GIOChannel *channel); + +/* Create an IO channel for a winsock socket. The parameter should be + * a SOCKET. Contrary to IO channels for file descriptors (on *Win32), + * you can use normal recv() or recvfrom() on sockets even if GLib + * is polling them. + */ +GIOChannel *g_io_channel_win32_new_socket (gint socket); + +#endif + +G_END_DECLS + +#endif /* __G_IOCHANNEL_H__ */ diff --git a/glib/glib/giounix.c b/glib/glib/giounix.c new file mode 100644 index 0000000..969c3cc --- /dev/null +++ b/glib/glib/giounix.c @@ -0,0 +1,658 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * giounix.c: IO Channels using unix file descriptors + * Copyright 1998 Owen Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#define _POSIX_SOURCE /* for SSIZE_MAX */ + +#include +#include +#include +#include +#include +#include +#include + +#include "giochannel.h" + +#include "gerror.h" +#include "gfileutils.h" +#include "gstrfuncs.h" +#include "gtestutils.h" + +/* + * Unix IO Channels + */ + +typedef struct _GIOUnixChannel GIOUnixChannel; +typedef struct _GIOUnixWatch GIOUnixWatch; + +struct _GIOUnixChannel +{ + GIOChannel channel; + gint fd; +}; + +struct _GIOUnixWatch +{ + GSource source; + GPollFD pollfd; + GIOChannel *channel; + GIOCondition condition; +}; + + +static GIOStatus g_io_unix_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read, + GError **err); +static GIOStatus g_io_unix_write (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written, + GError **err); +static GIOStatus g_io_unix_seek (GIOChannel *channel, + gint64 offset, + GSeekType type, + GError **err); +static GIOStatus g_io_unix_close (GIOChannel *channel, + GError **err); +static void g_io_unix_free (GIOChannel *channel); +static GSource* g_io_unix_create_watch (GIOChannel *channel, + GIOCondition condition); +static GIOStatus g_io_unix_set_flags (GIOChannel *channel, + GIOFlags flags, + GError **err); +static GIOFlags g_io_unix_get_flags (GIOChannel *channel); + +static gboolean g_io_unix_prepare (GSource *source, + gint *timeout); +static gboolean g_io_unix_check (GSource *source); +static gboolean g_io_unix_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data); +static void g_io_unix_finalize (GSource *source); + +GSourceFuncs g_io_watch_funcs = { + g_io_unix_prepare, + g_io_unix_check, + g_io_unix_dispatch, + g_io_unix_finalize +}; + +static GIOFuncs unix_channel_funcs = { + g_io_unix_read, + g_io_unix_write, + g_io_unix_seek, + g_io_unix_close, + g_io_unix_create_watch, + g_io_unix_free, + g_io_unix_set_flags, + g_io_unix_get_flags, +}; + +static gboolean +g_io_unix_prepare (GSource *source, + gint *timeout) +{ + GIOUnixWatch *watch = (GIOUnixWatch *)source; + GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel); + + *timeout = -1; + + /* Only return TRUE here if _all_ bits in watch->condition will be set + */ + return ((watch->condition & buffer_condition) == watch->condition); +} + +static gboolean +g_io_unix_check (GSource *source) +{ + GIOUnixWatch *watch = (GIOUnixWatch *)source; + GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel); + GIOCondition poll_condition = watch->pollfd.revents; + + return ((poll_condition | buffer_condition) & watch->condition); +} + +static gboolean +g_io_unix_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) + +{ + GIOFunc func = (GIOFunc)callback; + GIOUnixWatch *watch = (GIOUnixWatch *)source; + GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel); + + if (!func) + { + g_warning ("IO watch dispatched without callback\n" + "You must call g_source_connect()."); + return FALSE; + } + + return (*func) (watch->channel, + (watch->pollfd.revents | buffer_condition) & watch->condition, + user_data); +} + +static void +g_io_unix_finalize (GSource *source) +{ + GIOUnixWatch *watch = (GIOUnixWatch *)source; + + g_io_channel_unref (watch->channel); +} + +static GIOStatus +g_io_unix_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read, + GError **err) +{ + GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; + gssize result; + + if (count > SSIZE_MAX) /* At least according to the Debian manpage for read */ + count = SSIZE_MAX; + + retry: + result = read (unix_channel->fd, buf, count); + + if (result < 0) + { + int errsv = errno; + *bytes_read = 0; + + switch (errsv) + { +#ifdef EINTR + case EINTR: + goto retry; +#endif +#ifdef EAGAIN + case EAGAIN: + return G_IO_STATUS_AGAIN; +#endif + default: + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errsv), + g_strerror (errsv)); + return G_IO_STATUS_ERROR; + } + } + + *bytes_read = result; + + return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; +} + +static GIOStatus +g_io_unix_write (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written, + GError **err) +{ + GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; + gssize result; + + retry: + result = write (unix_channel->fd, buf, count); + + if (result < 0) + { + int errsv = errno; + *bytes_written = 0; + + switch (errsv) + { +#ifdef EINTR + case EINTR: + goto retry; +#endif +#ifdef EAGAIN + case EAGAIN: + return G_IO_STATUS_AGAIN; +#endif + default: + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errsv), + g_strerror (errsv)); + return G_IO_STATUS_ERROR; + } + } + + *bytes_written = result; + + return G_IO_STATUS_NORMAL; +} + +static GIOStatus +g_io_unix_seek (GIOChannel *channel, + gint64 offset, + GSeekType type, + GError **err) +{ + GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; + int whence; + off_t tmp_offset; + off_t result; + + switch (type) + { + case G_SEEK_SET: + whence = SEEK_SET; + break; + case G_SEEK_CUR: + whence = SEEK_CUR; + break; + case G_SEEK_END: + whence = SEEK_END; + break; + default: + whence = -1; /* Shut the compiler up */ + g_assert_not_reached (); + } + + tmp_offset = offset; + if (tmp_offset != offset) + { + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (EINVAL), + g_strerror (EINVAL)); + return G_IO_STATUS_ERROR; + } + + result = lseek (unix_channel->fd, tmp_offset, whence); + + if (result < 0) + { + int errsv = errno; + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errsv), + g_strerror (errsv)); + return G_IO_STATUS_ERROR; + } + + return G_IO_STATUS_NORMAL; +} + + +static GIOStatus +g_io_unix_close (GIOChannel *channel, + GError **err) +{ + GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; + + if (close (unix_channel->fd) < 0) + { + int errsv = errno; + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errsv), + g_strerror (errsv)); + return G_IO_STATUS_ERROR; + } + + return G_IO_STATUS_NORMAL; +} + +static void +g_io_unix_free (GIOChannel *channel) +{ + GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; + + g_free (unix_channel); +} + +static GSource * +g_io_unix_create_watch (GIOChannel *channel, + GIOCondition condition) +{ + GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; + GSource *source; + GIOUnixWatch *watch; + + + source = g_source_new (&g_io_watch_funcs, sizeof (GIOUnixWatch)); + g_source_set_name (source, "GIOChannel (Unix)"); + watch = (GIOUnixWatch *)source; + + watch->channel = channel; + g_io_channel_ref (channel); + + watch->condition = condition; + + watch->pollfd.fd = unix_channel->fd; + watch->pollfd.events = condition; + + g_source_add_poll (source, &watch->pollfd); + + return source; +} + +static GIOStatus +g_io_unix_set_flags (GIOChannel *channel, + GIOFlags flags, + GError **err) +{ + glong fcntl_flags; + GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel; + + fcntl_flags = 0; + + if (flags & G_IO_FLAG_APPEND) + fcntl_flags |= O_APPEND; + if (flags & G_IO_FLAG_NONBLOCK) +#ifdef O_NONBLOCK + fcntl_flags |= O_NONBLOCK; +#else + fcntl_flags |= O_NDELAY; +#endif + + if (fcntl (unix_channel->fd, F_SETFL, fcntl_flags) == -1) + { + int errsv = errno; + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errsv), + g_strerror (errsv)); + return G_IO_STATUS_ERROR; + } + + return G_IO_STATUS_NORMAL; +} + +static GIOFlags +g_io_unix_get_flags (GIOChannel *channel) +{ + GIOFlags flags = 0; + glong fcntl_flags; + GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel; + + fcntl_flags = fcntl (unix_channel->fd, F_GETFL); + + if (fcntl_flags == -1) + { + int err = errno; + g_warning (G_STRLOC "Error while getting flags for FD: %s (%d)\n", + g_strerror (err), err); + return 0; + } + + if (fcntl_flags & O_APPEND) + flags |= G_IO_FLAG_APPEND; +#ifdef O_NONBLOCK + if (fcntl_flags & O_NONBLOCK) +#else + if (fcntl_flags & O_NDELAY) +#endif + flags |= G_IO_FLAG_NONBLOCK; + + switch (fcntl_flags & (O_RDONLY | O_WRONLY | O_RDWR)) + { + case O_RDONLY: + channel->is_readable = TRUE; + channel->is_writeable = FALSE; + break; + case O_WRONLY: + channel->is_readable = FALSE; + channel->is_writeable = TRUE; + break; + case O_RDWR: + channel->is_readable = TRUE; + channel->is_writeable = TRUE; + break; + default: + g_assert_not_reached (); + } + + return flags; +} + +GIOChannel * +g_io_channel_new_file (const gchar *filename, + const gchar *mode, + GError **error) +{ + int fid, flags; + mode_t create_mode; + GIOChannel *channel; + enum { /* Cheesy hack */ + MODE_R = 1 << 0, + MODE_W = 1 << 1, + MODE_A = 1 << 2, + MODE_PLUS = 1 << 3, + MODE_R_PLUS = MODE_R | MODE_PLUS, + MODE_W_PLUS = MODE_W | MODE_PLUS, + MODE_A_PLUS = MODE_A | MODE_PLUS + } mode_num; + struct stat buffer; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (mode != NULL, NULL); + g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL); + + switch (mode[0]) + { + case 'r': + mode_num = MODE_R; + break; + case 'w': + mode_num = MODE_W; + break; + case 'a': + mode_num = MODE_A; + break; + default: + g_warning ("Invalid GIOFileMode %s.\n", mode); + return NULL; + } + + switch (mode[1]) + { + case '\0': + break; + case '+': + if (mode[2] == '\0') + { + mode_num |= MODE_PLUS; + break; + } + /* Fall through */ + default: + g_warning ("Invalid GIOFileMode %s.\n", mode); + return NULL; + } + + switch (mode_num) + { + case MODE_R: + flags = O_RDONLY; + break; + case MODE_W: + flags = O_WRONLY | O_TRUNC | O_CREAT; + break; + case MODE_A: + flags = O_WRONLY | O_APPEND | O_CREAT; + break; + case MODE_R_PLUS: + flags = O_RDWR; + break; + case MODE_W_PLUS: + flags = O_RDWR | O_TRUNC | O_CREAT; + break; + case MODE_A_PLUS: + flags = O_RDWR | O_APPEND | O_CREAT; + break; + case MODE_PLUS: + default: + g_assert_not_reached (); + flags = 0; + } + + create_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + + do + { + fid = open (filename, flags, create_mode); + } + while (fid == -1 && errno == EINTR); + + if (fid == -1) + { + int err = errno; + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (err), + g_strerror (err)); + return (GIOChannel *)NULL; + } + + if (fstat (fid, &buffer) == -1) /* In case someone opens a FIFO */ + { + int err = errno; + close (fid); + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (err), + g_strerror (err)); + return (GIOChannel *)NULL; + } + + channel = (GIOChannel *) g_new (GIOUnixChannel, 1); + + channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode) + || S_ISBLK (buffer.st_mode); + + switch (mode_num) + { + case MODE_R: + channel->is_readable = TRUE; + channel->is_writeable = FALSE; + break; + case MODE_W: + case MODE_A: + channel->is_readable = FALSE; + channel->is_writeable = TRUE; + break; + case MODE_R_PLUS: + case MODE_W_PLUS: + case MODE_A_PLUS: + channel->is_readable = TRUE; + channel->is_writeable = TRUE; + break; + case MODE_PLUS: + default: + g_assert_not_reached (); + } + + g_io_channel_init (channel); + channel->close_on_unref = TRUE; /* must be after g_io_channel_init () */ + channel->funcs = &unix_channel_funcs; + + ((GIOUnixChannel *) channel)->fd = fid; + return channel; +} + +/** + * g_io_channel_unix_new: + * @fd: a file descriptor. + * @Returns: a new #GIOChannel. + * + * Creates a new #GIOChannel given a file descriptor. On UNIX systems + * this works for plain files, pipes, and sockets. + * + * The returned #GIOChannel has a reference count of 1. + * + * The default encoding for #GIOChannel is UTF-8. If your application + * is reading output from a command using via pipe, you may need to set + * the encoding to the encoding of the current locale (see + * g_get_charset()) with the g_io_channel_set_encoding() function. + * + * If you want to read raw binary data without interpretation, then + * call the g_io_channel_set_encoding() function with %NULL for the + * encoding argument. + * + * This function is available in GLib on Windows, too, but you should + * avoid using it on Windows. The domain of file descriptors and + * sockets overlap. There is no way for GLib to know which one you mean + * in case the argument you pass to this function happens to be both a + * valid file descriptor and socket. If that happens a warning is + * issued, and GLib assumes that it is the file descriptor you mean. + **/ +GIOChannel * +g_io_channel_unix_new (gint fd) +{ + struct stat buffer; + GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1); + GIOChannel *channel = (GIOChannel *)unix_channel; + + g_io_channel_init (channel); + channel->funcs = &unix_channel_funcs; + + unix_channel->fd = fd; + + /* I'm not sure if fstat on a non-file (e.g., socket) works + * it should be safe to say if it fails, the fd isn't seekable. + */ + /* Newer UNIX versions support S_ISSOCK(), fstat() will probably + * succeed in most cases. + */ + if (fstat (unix_channel->fd, &buffer) == 0) + channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode) + || S_ISBLK (buffer.st_mode); + else /* Assume not seekable */ + channel->is_seekable = FALSE; + + g_io_unix_get_flags (channel); /* Sets is_readable, is_writeable */ + + return channel; +} + +/** + * g_io_channel_unix_get_fd: + * @channel: a #GIOChannel, created with g_io_channel_unix_new(). + * @Returns: the file descriptor of the #GIOChannel. + * + * Returns the file descriptor of the #GIOChannel. + * + * On Windows this function returns the file descriptor or socket of + * the #GIOChannel. + **/ +gint +g_io_channel_unix_get_fd (GIOChannel *channel) +{ + GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel; + return unix_channel->fd; +} diff --git a/glib/glib/giowin32.c b/glib/glib/giowin32.c new file mode 100644 index 0000000..d39a4b2 --- /dev/null +++ b/glib/glib/giowin32.c @@ -0,0 +1,2241 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * giowin32.c: IO Channels for Win32. + * Copyright 1998 Owen Taylor and Tor Lillqvist + * Copyright 1999-2000 Tor Lillqvist and Craig Setera + * Copyright 2001-2003 Andrew Lanoix + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * Bugs that are related to the code in this file: + * + * Bug 137968 - Sometimes a GIOFunc on Win32 is called with zero condition + * http://bugzilla.gnome.org/show_bug.cgi?id=137968 + * + * Bug 324234 - Using g_io_add_watch_full() to wait for connect() to return on a non-blocking socket returns prematurely + * http://bugzilla.gnome.org/show_bug.cgi?id=324234 + * + * Bug 331214 - g_io_channel async socket io stalls + * http://bugzilla.gnome.org/show_bug.cgi?id=331214 + * + * Bug 338943 - Multiple watches on the same socket + * http://bugzilla.gnome.org/show_bug.cgi?id=338943 + * + * Bug 357674 - 2 serious bugs in giowin32.c making glib iochannels useless + * http://bugzilla.gnome.org/show_bug.cgi?id=357674 + * + * Bug 425156 - GIOChannel deadlocks on a win32 socket + * http://bugzilla.gnome.org/show_bug.cgi?id=425156 + * + * Bug 468910 - giofunc condition=0 + * http://bugzilla.gnome.org/show_bug.cgi?id=468910 + * + * Bug 500246 - Bug fixes for giowin32 + * http://bugzilla.gnome.org/show_bug.cgi?id=500246 + * + * Bug 548278 - Async GETs connections are always terminated unexpectedly on windows + * http://bugzilla.gnome.org/show_bug.cgi?id=548278 + * + * Bug 548536 - giowin32 problem when adding and removing watches + * http://bugzilla.gnome.org/show_bug.cgi?id=548536 + * + * When fixing bugs related to the code in this file, either the above + * bugs or others, make sure that the test programs attached to the + * above bugs continue to work. + */ + +#include "config.h" + +#include "glib.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gstdio.h" +#include "glibintl.h" + + +typedef struct _GIOWin32Channel GIOWin32Channel; +typedef struct _GIOWin32Watch GIOWin32Watch; + +#define BUFFER_SIZE 4096 + +typedef enum { + G_IO_WIN32_WINDOWS_MESSAGES, /* Windows messages */ + + G_IO_WIN32_FILE_DESC, /* Unix-like file descriptors from + * _open() or _pipe(), except for + * console IO. Separate thread to read + * or write. + */ + + G_IO_WIN32_CONSOLE, /* Console IO (usually stdin, stdout, stderr) */ + + G_IO_WIN32_SOCKET /* Sockets. No separate thread. */ +} GIOWin32ChannelType; + +struct _GIOWin32Channel { + GIOChannel channel; + gint fd; /* Either a Unix-like file handle as provided + * by the Microsoft C runtime, or a SOCKET + * as provided by WinSock. + */ + GIOWin32ChannelType type; + + gboolean debug; + + /* Field used by G_IO_WIN32_WINDOWS_MESSAGES channels */ + HWND hwnd; /* Handle of window, or NULL */ + + /* Fields used by G_IO_WIN32_FILE_DESC channels. */ + CRITICAL_SECTION mutex; + + int direction; /* 0 means we read from it, + * 1 means we write to it. + */ + + gboolean running; /* Is reader or writer thread + * running. FALSE if EOF has been + * reached by the reader thread. + */ + + gboolean needs_close; /* If the channel has been closed while + * the reader thread was still running. + */ + + guint thread_id; /* If non-NULL the channel has or has + * had a reader or writer thread. + */ + HANDLE data_avail_event; + + gushort revents; + + /* Data is kept in a circular buffer. To be able to distinguish between + * empty and full buffers, we cannot fill it completely, but have to + * leave a one character gap. + * + * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE). + * + * Empty: wrp == rdp + * Full: (wrp + 1) % BUFFER_SIZE == rdp + * Partial: otherwise + */ + guchar *buffer; /* (Circular) buffer */ + gint wrp, rdp; /* Buffer indices for writing and reading */ + HANDLE space_avail_event; + + /* Fields used by G_IO_WIN32_SOCKET channels */ + int event_mask; + int last_events; + HANDLE event; + gboolean write_would_have_blocked; + gboolean ever_writable; +}; + +struct _GIOWin32Watch { + GSource source; + GPollFD pollfd; + GIOChannel *channel; + GIOCondition condition; +}; + +static void +g_win32_print_access_mode (int flags) +{ + g_print ("%s%s%s%s%s%s%s%s%s%s", + ((flags & 0x3) == _O_RDWR ? "O_RDWR" : + ((flags & 0x3) == _O_RDONLY ? "O_RDONLY" : + ((flags & 0x3) == _O_WRONLY ? "O_WRONLY" : "0"))), + (flags & _O_APPEND ? "|O_APPEND" : ""), + (flags & _O_RANDOM ? "|O_RANDOM" : ""), + (flags & _O_SEQUENTIAL ? "|O_SEQUENTIAL" : ""), + (flags & _O_TEMPORARY ? "|O_TEMPORARY" : ""), + (flags & _O_CREAT ? "|O_CREAT" : ""), + (flags & _O_TRUNC ? "|O_TRUNC" : ""), + (flags & _O_EXCL ? "|O_EXCL" : ""), + (flags & _O_TEXT ? "|O_TEXT" : ""), + (flags & _O_BINARY ? "|O_BINARY" : "")); +} + +static void +g_win32_print_gioflags (GIOFlags flags) +{ + char *bar = ""; + + if (flags & G_IO_FLAG_APPEND) + bar = "|", g_print ("APPEND"); + if (flags & G_IO_FLAG_NONBLOCK) + g_print ("%sNONBLOCK", bar), bar = "|"; + if (flags & G_IO_FLAG_IS_READABLE) + g_print ("%sREADABLE", bar), bar = "|"; + if (flags & G_IO_FLAG_IS_WRITABLE) + g_print ("%sWRITABLE", bar), bar = "|"; + if (flags & G_IO_FLAG_IS_SEEKABLE) + g_print ("%sSEEKABLE", bar), bar = "|"; +} + +static const char * +event_mask_to_string (int mask) +{ + char buf[100]; + int checked_bits = 0; + char *bufp = buf; + + if (mask == 0) + return ""; + +#define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : "")) + + BIT (READ); + BIT (WRITE); + BIT (OOB); + BIT (ACCEPT); + BIT (CONNECT); + BIT (CLOSE); + BIT (QOS); + BIT (GROUP_QOS); + BIT (ROUTING_INTERFACE_CHANGE); + BIT (ADDRESS_LIST_CHANGE); + +#undef BIT + + if ((mask & ~checked_bits) != 0) + bufp += sprintf (bufp, "|%#x", mask & ~checked_bits); + + return g_quark_to_string (g_quark_from_string (buf)); +} + +static const char * +condition_to_string (GIOCondition condition) +{ + char buf[100]; + int checked_bits = 0; + char *bufp = buf; + + if (condition == 0) + return ""; + +#define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : "")) + + BIT (IN); + BIT (OUT); + BIT (PRI); + BIT (ERR); + BIT (HUP); + BIT (NVAL); + +#undef BIT + + if ((condition & ~checked_bits) != 0) + bufp += sprintf (bufp, "|%#x", condition & ~checked_bits); + + return g_quark_to_string (g_quark_from_string (buf)); +} + +static gboolean +g_io_win32_get_debug_flag (void) +{ + return (getenv ("G_IO_WIN32_DEBUG") != NULL); +} + +static void +g_io_channel_win32_init (GIOWin32Channel *channel) +{ + channel->debug = g_io_win32_get_debug_flag (); + + InitializeCriticalSection (&channel->mutex); + channel->running = FALSE; + channel->needs_close = FALSE; + channel->thread_id = 0; + channel->data_avail_event = NULL; + channel->revents = 0; + channel->buffer = NULL; + channel->space_avail_event = NULL; + + channel->event_mask = 0; + channel->last_events = 0; + channel->event = NULL; + channel->write_would_have_blocked = FALSE; + channel->ever_writable = FALSE; +} + +static void +create_events (GIOWin32Channel *channel) +{ + SECURITY_ATTRIBUTES sec_attrs; + + sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES); + sec_attrs.lpSecurityDescriptor = NULL; + sec_attrs.bInheritHandle = FALSE; + + /* The data available event is manual reset, the space available event + * is automatic reset. + */ + if (!(channel->data_avail_event = CreateEvent (&sec_attrs, TRUE, FALSE, NULL)) + || !(channel->space_avail_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL))) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + + g_error ("Error creating event: %s", emsg); + g_free (emsg); + } +} + +static unsigned __stdcall +read_thread (void *parameter) +{ + GIOWin32Channel *channel = parameter; + guchar *buffer; + gint nbytes; + + g_io_channel_ref ((GIOChannel *)channel); + + if (channel->debug) + g_print ("read_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n", + channel->thread_id, + channel->fd, + channel->data_avail_event, + channel->space_avail_event); + + channel->direction = 0; + channel->buffer = g_malloc (BUFFER_SIZE); + channel->rdp = channel->wrp = 0; + channel->running = TRUE; + + SetEvent (channel->space_avail_event); + + EnterCriticalSection (&channel->mutex); + while (channel->running) + { + if (channel->debug) + g_print ("read_thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); + if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp) + { + /* Buffer is full */ + if (channel->debug) + g_print ("read_thread %#x: resetting space_avail\n", + channel->thread_id); + ResetEvent (channel->space_avail_event); + if (channel->debug) + g_print ("read_thread %#x: waiting for space\n", + channel->thread_id); + LeaveCriticalSection (&channel->mutex); + WaitForSingleObject (channel->space_avail_event, INFINITE); + EnterCriticalSection (&channel->mutex); + if (channel->debug) + g_print ("read_thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); + } + + buffer = channel->buffer + channel->wrp; + + /* Always leave at least one byte unused gap to be able to + * distinguish between the full and empty condition... + */ + nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE, + BUFFER_SIZE - channel->wrp); + + if (channel->debug) + g_print ("read_thread %#x: calling read() for %d bytes\n", + channel->thread_id, nbytes); + + LeaveCriticalSection (&channel->mutex); + + nbytes = read (channel->fd, buffer, nbytes); + + EnterCriticalSection (&channel->mutex); + + channel->revents = G_IO_IN; + if (nbytes == 0) + channel->revents |= G_IO_HUP; + else if (nbytes < 0) + channel->revents |= G_IO_ERR; + + if (channel->debug) + g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n", + channel->thread_id, nbytes, channel->rdp, channel->wrp); + + if (nbytes <= 0) + break; + + channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE; + if (channel->debug) + g_print ("read_thread %#x: rdp=%d, wrp=%d, setting data_avail\n", + channel->thread_id, channel->rdp, channel->wrp); + SetEvent (channel->data_avail_event); + } + + channel->running = FALSE; + if (channel->needs_close) + { + if (channel->debug) + g_print ("read_thread %#x: channel fd %d needs closing\n", + channel->thread_id, channel->fd); + close (channel->fd); + channel->fd = -1; + } + + if (channel->debug) + g_print ("read_thread %#x: EOF, rdp=%d, wrp=%d, setting data_avail\n", + channel->thread_id, channel->rdp, channel->wrp); + SetEvent (channel->data_avail_event); + LeaveCriticalSection (&channel->mutex); + + g_io_channel_unref ((GIOChannel *)channel); + + /* No need to call _endthreadex(), the actual thread starter routine + * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls + * _endthreadex() for us. + */ + + return 0; +} + +static unsigned __stdcall +write_thread (void *parameter) +{ + GIOWin32Channel *channel = parameter; + guchar *buffer; + gint nbytes; + + g_io_channel_ref ((GIOChannel *)channel); + + if (channel->debug) + g_print ("write_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n", + channel->thread_id, + channel->fd, + channel->data_avail_event, + channel->space_avail_event); + + channel->direction = 1; + channel->buffer = g_malloc (BUFFER_SIZE); + channel->rdp = channel->wrp = 0; + channel->running = TRUE; + + SetEvent (channel->space_avail_event); + + /* We use the same event objects as for a reader thread, but with + * reversed meaning. So, space_avail is used if data is available + * for writing, and data_avail is used if space is available in the + * write buffer. + */ + + EnterCriticalSection (&channel->mutex); + while (channel->running || channel->rdp != channel->wrp) + { + if (channel->debug) + g_print ("write_thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); + if (channel->wrp == channel->rdp) + { + /* Buffer is empty. */ + if (channel->debug) + g_print ("write_thread %#x: resetting space_avail\n", + channel->thread_id); + ResetEvent (channel->space_avail_event); + if (channel->debug) + g_print ("write_thread %#x: waiting for data\n", + channel->thread_id); + channel->revents = G_IO_OUT; + SetEvent (channel->data_avail_event); + LeaveCriticalSection (&channel->mutex); + WaitForSingleObject (channel->space_avail_event, INFINITE); + + EnterCriticalSection (&channel->mutex); + if (channel->rdp == channel->wrp) + break; + + if (channel->debug) + g_print ("write_thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); + } + + buffer = channel->buffer + channel->rdp; + if (channel->rdp < channel->wrp) + nbytes = channel->wrp - channel->rdp; + else + nbytes = BUFFER_SIZE - channel->rdp; + + if (channel->debug) + g_print ("write_thread %#x: calling write() for %d bytes\n", + channel->thread_id, nbytes); + + LeaveCriticalSection (&channel->mutex); + nbytes = write (channel->fd, buffer, nbytes); + EnterCriticalSection (&channel->mutex); + + if (channel->debug) + g_print ("write_thread %#x: write(%i) returned %d, rdp=%d, wrp=%d\n", + channel->thread_id, channel->fd, nbytes, channel->rdp, channel->wrp); + + channel->revents = 0; + if (nbytes > 0) + channel->revents |= G_IO_OUT; + else if (nbytes <= 0) + channel->revents |= G_IO_ERR; + + channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE; + + if (nbytes <= 0) + break; + + if (channel->debug) + g_print ("write_thread: setting data_avail for thread %#x\n", + channel->thread_id); + SetEvent (channel->data_avail_event); + } + + channel->running = FALSE; + if (channel->needs_close) + { + if (channel->debug) + g_print ("write_thread %#x: channel fd %d needs closing\n", + channel->thread_id, channel->fd); + close (channel->fd); + channel->fd = -1; + } + + LeaveCriticalSection (&channel->mutex); + + g_io_channel_unref ((GIOChannel *)channel); + + return 0; +} + +static void +create_thread (GIOWin32Channel *channel, + GIOCondition condition, + unsigned (__stdcall *thread) (void *parameter)) +{ + HANDLE thread_handle; + + thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0, + &channel->thread_id); + if (thread_handle == 0) + g_warning ("Error creating thread: %s.", + g_strerror (errno)); + else if (!CloseHandle (thread_handle)) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + + g_warning ("Error closing thread handle: %s.", emsg); + g_free (emsg); + } + + WaitForSingleObject (channel->space_avail_event, INFINITE); +} + +static GIOStatus +buffer_read (GIOWin32Channel *channel, + gchar *dest, + gsize count, + gsize *bytes_read, + GError **err) +{ + guint nbytes; + guint left = count; + + EnterCriticalSection (&channel->mutex); + if (channel->debug) + g_print ("reading from thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n", + channel->thread_id, count, channel->rdp, channel->wrp); + + if (channel->wrp == channel->rdp) + { + LeaveCriticalSection (&channel->mutex); + if (channel->debug) + g_print ("waiting for data from thread %#x\n", channel->thread_id); + WaitForSingleObject (channel->data_avail_event, INFINITE); + if (channel->debug) + g_print ("done waiting for data from thread %#x\n", channel->thread_id); + EnterCriticalSection (&channel->mutex); + if (channel->wrp == channel->rdp && !channel->running) + { + if (channel->debug) + g_print ("wrp==rdp, !running\n"); + LeaveCriticalSection (&channel->mutex); + *bytes_read = 0; + return G_IO_STATUS_EOF; + } + } + + if (channel->rdp < channel->wrp) + nbytes = channel->wrp - channel->rdp; + else + nbytes = BUFFER_SIZE - channel->rdp; + LeaveCriticalSection (&channel->mutex); + nbytes = MIN (left, nbytes); + if (channel->debug) + g_print ("moving %d bytes from thread %#x\n", + nbytes, channel->thread_id); + memcpy (dest, channel->buffer + channel->rdp, nbytes); + dest += nbytes; + left -= nbytes; + EnterCriticalSection (&channel->mutex); + channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE; + if (channel->debug) + g_print ("setting space_avail for thread %#x\n", channel->thread_id); + SetEvent (channel->space_avail_event); + if (channel->debug) + g_print ("for thread %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); + if (channel->running && channel->wrp == channel->rdp) + { + if (channel->debug) + g_print ("resetting data_avail of thread %#x\n", + channel->thread_id); + ResetEvent (channel->data_avail_event); + }; + LeaveCriticalSection (&channel->mutex); + + /* We have no way to indicate any errors form the actual + * read() or recv() call in the reader thread. Should we have? + */ + *bytes_read = count - left; + return (*bytes_read > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; +} + + +static GIOStatus +buffer_write (GIOWin32Channel *channel, + const gchar *dest, + gsize count, + gsize *bytes_written, + GError **err) +{ + guint nbytes; + guint left = count; + + EnterCriticalSection (&channel->mutex); + if (channel->debug) + g_print ("buffer_write: writing to thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n", + channel->thread_id, count, channel->rdp, channel->wrp); + + if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp) + { + /* Buffer is full */ + if (channel->debug) + g_print ("buffer_write: tid %#x: resetting data_avail\n", + channel->thread_id); + ResetEvent (channel->data_avail_event); + if (channel->debug) + g_print ("buffer_write: tid %#x: waiting for space\n", + channel->thread_id); + LeaveCriticalSection (&channel->mutex); + WaitForSingleObject (channel->data_avail_event, INFINITE); + EnterCriticalSection (&channel->mutex); + if (channel->debug) + g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d\n", + channel->thread_id, channel->rdp, channel->wrp); + } + + nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE, + BUFFER_SIZE - channel->wrp); + + LeaveCriticalSection (&channel->mutex); + nbytes = MIN (left, nbytes); + if (channel->debug) + g_print ("buffer_write: tid %#x: writing %d bytes\n", + channel->thread_id, nbytes); + memcpy (channel->buffer + channel->wrp, dest, nbytes); + dest += nbytes; + left -= nbytes; + EnterCriticalSection (&channel->mutex); + + channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE; + if (channel->debug) + g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d, setting space_avail\n", + channel->thread_id, channel->rdp, channel->wrp); + SetEvent (channel->space_avail_event); + + if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp) + { + /* Buffer is full */ + if (channel->debug) + g_print ("buffer_write: tid %#x: resetting data_avail\n", + channel->thread_id); + ResetEvent (channel->data_avail_event); + } + + LeaveCriticalSection (&channel->mutex); + + /* We have no way to indicate any errors form the actual + * write() call in the writer thread. Should we have? + */ + *bytes_written = count - left; + return (*bytes_written > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; +} + + +static gboolean +g_io_win32_prepare (GSource *source, + gint *timeout) +{ + GIOWin32Watch *watch = (GIOWin32Watch *)source; + GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel); + GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel; + int event_mask; + + *timeout = -1; + + if (channel->debug) + g_print ("g_io_win32_prepare: source=%p channel=%p", source, channel); + + switch (channel->type) + { + case G_IO_WIN32_WINDOWS_MESSAGES: + if (channel->debug) + g_print (" MSG"); + break; + + case G_IO_WIN32_CONSOLE: + if (channel->debug) + g_print (" CON"); + break; + + case G_IO_WIN32_FILE_DESC: + if (channel->debug) + g_print (" FD thread=%#x buffer_condition:{%s}" + "\n watch->pollfd.events:{%s} watch->pollfd.revents:{%s} channel->revents:{%s}", + channel->thread_id, condition_to_string (buffer_condition), + condition_to_string (watch->pollfd.events), + condition_to_string (watch->pollfd.revents), + condition_to_string (channel->revents)); + + EnterCriticalSection (&channel->mutex); + if (channel->running) + { + if (channel->direction == 0 && channel->wrp == channel->rdp) + { + if (channel->debug) + g_print ("\n setting revents=0"); + channel->revents = 0; + } + } + else + { + if (channel->direction == 1 + && (channel->wrp + 1) % BUFFER_SIZE == channel->rdp) + { + if (channel->debug) + g_print ("\n setting revents=0"); + channel->revents = 0; + } + } + LeaveCriticalSection (&channel->mutex); + break; + + case G_IO_WIN32_SOCKET: + if (channel->debug) + g_print (" SOCK"); + event_mask = 0; + if (watch->condition & G_IO_IN) + event_mask |= (FD_READ | FD_ACCEPT); + if (watch->condition & G_IO_OUT) + event_mask |= (FD_WRITE | FD_CONNECT); + event_mask |= FD_CLOSE; + + if (channel->event_mask != event_mask) + { + if (channel->debug) + g_print ("\n WSAEventSelect(%d,%p,{%s})", + channel->fd, (HANDLE) watch->pollfd.fd, + event_mask_to_string (event_mask)); + if (WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd, + event_mask) == SOCKET_ERROR) + if (channel->debug) + { + gchar *emsg = g_win32_error_message (WSAGetLastError ()); + + g_print (" failed: %s", emsg); + g_free (emsg); + } + channel->event_mask = event_mask; + + if (channel->debug) + g_print ("\n setting last_events=0"); + channel->last_events = 0; + + if ((event_mask & FD_WRITE) && + channel->ever_writable && + !channel->write_would_have_blocked) + { + if (channel->debug) + g_print (" WSASetEvent(%p)", (WSAEVENT) watch->pollfd.fd); + WSASetEvent ((WSAEVENT) watch->pollfd.fd); + } + } + break; + + default: + g_assert_not_reached (); + abort (); + } + if (channel->debug) + g_print ("\n"); + + return ((watch->condition & buffer_condition) == watch->condition); +} + +static gboolean +g_io_win32_check (GSource *source) +{ + MSG msg; + GIOWin32Watch *watch = (GIOWin32Watch *)source; + GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel; + GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel); + WSANETWORKEVENTS events; + + if (channel->debug) + g_print ("g_io_win32_check: source=%p channel=%p", source, channel); + + switch (channel->type) + { + case G_IO_WIN32_WINDOWS_MESSAGES: + if (channel->debug) + g_print (" MSG\n"); + return (PeekMessage (&msg, channel->hwnd, 0, 0, PM_NOREMOVE)); + + case G_IO_WIN32_FILE_DESC: + if (channel->debug) + g_print (" FD thread=%#x buffer_condition=%s\n" + " watch->pollfd.events={%s} watch->pollfd.revents={%s} channel->revents={%s}\n", + channel->thread_id, condition_to_string (buffer_condition), + condition_to_string (watch->pollfd.events), + condition_to_string (watch->pollfd.revents), + condition_to_string (channel->revents)); + + watch->pollfd.revents = (watch->pollfd.events & channel->revents); + + return ((watch->pollfd.revents | buffer_condition) & watch->condition); + + case G_IO_WIN32_CONSOLE: + if (channel->debug) + g_print (" CON\n"); + if (watch->channel->is_writeable) + return TRUE; + else if (watch->channel->is_readable) + { + INPUT_RECORD buffer; + DWORD n; + if (PeekConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n) && + n == 1) + { + /* _kbhit() does quite complex processing to find out + * whether at least one of the key events pending corresponds + * to a "real" character that can be read. + */ + if (_kbhit ()) + return TRUE; + + /* Discard all other kinds of events */ + ReadConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n); + } + } + return FALSE; + + case G_IO_WIN32_SOCKET: + if (channel->debug) + g_print (" SOCK"); + if (channel->last_events & FD_WRITE) + { + if (channel->debug) + g_print (" sock=%d event=%p last_events has FD_WRITE", + channel->fd, (HANDLE) watch->pollfd.fd); + } + else + { + WSAEnumNetworkEvents (channel->fd, 0, &events); + + if (channel->debug) + g_print ("\n revents={%s} condition={%s}" + "\n WSAEnumNetworkEvents(%d,0) sets events={%s}", + condition_to_string (watch->pollfd.revents), + condition_to_string (watch->condition), + channel->fd, + event_mask_to_string (events.lNetworkEvents)); + + if (watch->pollfd.revents != 0 && + events.lNetworkEvents == 0 && + !(channel->event_mask & FD_WRITE)) + { + channel->event_mask = 0; + if (channel->debug) + g_print ("\n WSAEventSelect(%d,%p,{})", + channel->fd, (HANDLE) watch->pollfd.fd); + WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd, 0); + if (channel->debug) + g_print (" ResetEvent(%p)", + (HANDLE) watch->pollfd.fd); + ResetEvent ((HANDLE) watch->pollfd.fd); + } + else if (events.lNetworkEvents & FD_WRITE) + channel->ever_writable = TRUE; + channel->last_events = events.lNetworkEvents; + } + + watch->pollfd.revents = 0; + if (channel->last_events & (FD_READ | FD_ACCEPT)) + watch->pollfd.revents |= G_IO_IN; + + if (channel->last_events & FD_WRITE) + watch->pollfd.revents |= G_IO_OUT; + else + { + /* We have called WSAEnumNetworkEvents() above but it didn't + * set FD_WRITE. + */ + if (events.lNetworkEvents & FD_CONNECT) + { + if (events.iErrorCode[FD_CONNECT_BIT] == 0) + watch->pollfd.revents |= G_IO_OUT; + else + watch->pollfd.revents |= (G_IO_HUP | G_IO_ERR); + } + if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE))) + watch->pollfd.revents |= G_IO_HUP; + } + + /* Regardless of WSAEnumNetworkEvents() result, if watching for + * writability, and if we have ever got a FD_WRITE event, and + * unless last write would have blocked, set G_IO_OUT. But never + * set both G_IO_OUT and G_IO_HUP. + */ + if (!(watch->pollfd.revents & G_IO_HUP) && + channel->ever_writable && + !channel->write_would_have_blocked && + (channel->event_mask & FD_WRITE)) + watch->pollfd.revents |= G_IO_OUT; + + if (channel->debug) + g_print ("\n revents={%s} retval={%s}\n", + condition_to_string (watch->pollfd.revents), + condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition)); + + return ((watch->pollfd.revents | buffer_condition) & watch->condition); + + default: + g_assert_not_reached (); + abort (); + } +} + +static gboolean +g_io_win32_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GIOFunc func = (GIOFunc)callback; + GIOWin32Watch *watch = (GIOWin32Watch *)source; + GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel; + GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel); + + if (!func) + { + g_warning ("IO Watch dispatched without callback\n" + "You must call g_source_connect()."); + return FALSE; + } + + if (channel->debug) + g_print ("g_io_win32_dispatch: pollfd.revents=%s condition=%s result=%s\n", + condition_to_string (watch->pollfd.revents), + condition_to_string (watch->condition), + condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition)); + + return (*func) (watch->channel, + (watch->pollfd.revents | buffer_condition) & watch->condition, + user_data); +} + +static void +g_io_win32_finalize (GSource *source) +{ + GIOWin32Watch *watch = (GIOWin32Watch *)source; + GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel; + + if (channel->debug) + g_print ("g_io_win32_finalize: source=%p channel=%p", source, channel); + + switch (channel->type) + { + case G_IO_WIN32_WINDOWS_MESSAGES: + if (channel->debug) + g_print (" MSG"); + break; + + case G_IO_WIN32_CONSOLE: + if (channel->debug) + g_print (" CON"); + break; + + case G_IO_WIN32_FILE_DESC: + if (channel->debug) + g_print (" FD thread=%#x", channel->thread_id); + break; + + case G_IO_WIN32_SOCKET: + if (channel->debug) + g_print (" SOCK sock=%d", channel->fd); + break; + + default: + g_assert_not_reached (); + abort (); + } + if (channel->debug) + g_print ("\n"); + g_io_channel_unref (watch->channel); +} + +GSourceFuncs g_io_watch_funcs = { + g_io_win32_prepare, + g_io_win32_check, + g_io_win32_dispatch, + g_io_win32_finalize +}; + +static GIOStatus +g_io_win32_msg_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + MSG msg; /* In case of alignment problems */ + + if (count < sizeof (MSG)) + { + g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL, + "Incorrect message size"); /* Informative enough error message? */ + return G_IO_STATUS_ERROR; + } + + if (win32_channel->debug) + g_print ("g_io_win32_msg_read: channel=%p hwnd=%p\n", + channel, win32_channel->hwnd); + if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE)) + return G_IO_STATUS_AGAIN; + + memmove (buf, &msg, sizeof (MSG)); + *bytes_read = sizeof (MSG); + + return G_IO_STATUS_NORMAL; +} + +static GIOStatus +g_io_win32_msg_write (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + MSG msg; + + if (count != sizeof (MSG)) + { + g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL, + "Incorrect message size"); /* Informative enough error message? */ + return G_IO_STATUS_ERROR; + } + + /* In case of alignment problems */ + memmove (&msg, buf, sizeof (MSG)); + if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam)) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + + g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, emsg); + g_free (emsg); + + return G_IO_STATUS_ERROR; + } + + *bytes_written = sizeof (MSG); + + return G_IO_STATUS_NORMAL; +} + +static GIOStatus +g_io_win32_msg_close (GIOChannel *channel, + GError **err) +{ + /* Nothing to be done. Or should we set hwnd to some invalid value? */ + + return G_IO_STATUS_NORMAL; +} + +static void +g_io_win32_free (GIOChannel *channel) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + if (win32_channel->debug) + g_print ("g_io_win32_free channel=%p fd=%d\n", channel, win32_channel->fd); + + DeleteCriticalSection (&win32_channel->mutex); + + if (win32_channel->data_avail_event) + if (!CloseHandle (win32_channel->data_avail_event)) + if (win32_channel->debug) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + + g_print (" CloseHandle(%p) failed: %s\n", + win32_channel->data_avail_event, emsg); + g_free (emsg); + } + + g_free (win32_channel->buffer); + + if (win32_channel->space_avail_event) + if (!CloseHandle (win32_channel->space_avail_event)) + if (win32_channel->debug) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + + g_print (" CloseHandle(%p) failed: %s\n", + win32_channel->space_avail_event, emsg); + g_free (emsg); + } + + if (win32_channel->type == G_IO_WIN32_SOCKET && + win32_channel->fd != -1) + if (WSAEventSelect (win32_channel->fd, NULL, 0) == SOCKET_ERROR) + if (win32_channel->debug) + { + gchar *emsg = g_win32_error_message (WSAGetLastError ()); + + g_print (" WSAEventSelect(%d,NULL,{}) failed: %s\n", + win32_channel->fd, emsg); + g_free (emsg); + } + + if (win32_channel->event) + if (!WSACloseEvent (win32_channel->event)) + if (win32_channel->debug) + { + gchar *emsg = g_win32_error_message (WSAGetLastError ()); + + g_print (" WSACloseEvent(%p) failed: %s\n", + win32_channel->event, emsg); + g_free (emsg); + } + + g_free (win32_channel); +} + +static GSource * +g_io_win32_msg_create_watch (GIOChannel *channel, + GIOCondition condition) +{ + GIOWin32Watch *watch; + GSource *source; + + source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch)); + g_source_set_name (source, "GIOChannel (Win32)"); + watch = (GIOWin32Watch *)source; + + watch->channel = channel; + g_io_channel_ref (channel); + + watch->condition = condition; + + watch->pollfd.fd = (gintptr) G_WIN32_MSG_HANDLE; + watch->pollfd.events = condition; + + g_source_add_poll (source, &watch->pollfd); + + return source; +} + +static GIOStatus +g_io_win32_fd_and_console_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + gint result; + + if (win32_channel->debug) + g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT "\n", + win32_channel->fd, count); + + if (win32_channel->thread_id) + { + return buffer_read (win32_channel, buf, count, bytes_read, err); + } + + result = read (win32_channel->fd, buf, count); + + if (win32_channel->debug) + g_print ("g_io_win32_fd_read: read() => %d\n", result); + + if (result < 0) + { + *bytes_read = 0; + + switch (errno) + { +#ifdef EAGAIN + case EAGAIN: + return G_IO_STATUS_AGAIN; +#endif + default: + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errno), + g_strerror (errno)); + return G_IO_STATUS_ERROR; + } + } + + *bytes_read = result; + + return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF; +} + +static GIOStatus +g_io_win32_fd_and_console_write (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + gint result; + + if (win32_channel->thread_id) + { + return buffer_write (win32_channel, buf, count, bytes_written, err); + } + + result = write (win32_channel->fd, buf, count); + if (win32_channel->debug) + g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT " => %d\n", + win32_channel->fd, count, result); + + if (result < 0) + { + *bytes_written = 0; + + switch (errno) + { +#ifdef EAGAIN + case EAGAIN: + return G_IO_STATUS_AGAIN; +#endif + default: + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errno), + g_strerror (errno)); + return G_IO_STATUS_ERROR; + } + } + + *bytes_written = result; + + return G_IO_STATUS_NORMAL; +} + +static GIOStatus +g_io_win32_fd_seek (GIOChannel *channel, + gint64 offset, + GSeekType type, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + int whence; + off_t tmp_offset; + off_t result; + + switch (type) + { + case G_SEEK_SET: + whence = SEEK_SET; + break; + case G_SEEK_CUR: + whence = SEEK_CUR; + break; + case G_SEEK_END: + whence = SEEK_END; + break; + default: + whence = -1; /* Keep the compiler quiet */ + g_assert_not_reached (); + abort (); + } + + tmp_offset = offset; + if (tmp_offset != offset) + { + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (EINVAL), + g_strerror (EINVAL)); + return G_IO_STATUS_ERROR; + } + + result = lseek (win32_channel->fd, tmp_offset, whence); + + if (result < 0) + { + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errno), + g_strerror (errno)); + return G_IO_STATUS_ERROR; + } + + return G_IO_STATUS_NORMAL; +} + +static GIOStatus +g_io_win32_fd_close (GIOChannel *channel, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + if (win32_channel->debug) + g_print ("g_io_win32_fd_close: thread=%#x: fd=%d\n", + win32_channel->thread_id, + win32_channel->fd); + EnterCriticalSection (&win32_channel->mutex); + if (win32_channel->running) + { + if (win32_channel->debug) + g_print ("thread %#x: running, marking fd %d for later close\n", + win32_channel->thread_id, win32_channel->fd); + win32_channel->running = FALSE; + win32_channel->needs_close = TRUE; + if (win32_channel->direction == 0) + SetEvent (win32_channel->data_avail_event); + else + SetEvent (win32_channel->space_avail_event); + } + else + { + if (win32_channel->debug) + g_print ("closing fd %d\n", win32_channel->fd); + close (win32_channel->fd); + if (win32_channel->debug) + g_print ("closed fd %d, setting to -1\n", + win32_channel->fd); + win32_channel->fd = -1; + } + LeaveCriticalSection (&win32_channel->mutex); + + /* FIXME error detection? */ + + return G_IO_STATUS_NORMAL; +} + +static GSource * +g_io_win32_fd_create_watch (GIOChannel *channel, + GIOCondition condition) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch)); + GIOWin32Watch *watch = (GIOWin32Watch *)source; + + watch->channel = channel; + g_io_channel_ref (channel); + + watch->condition = condition; + + if (win32_channel->data_avail_event == NULL) + create_events (win32_channel); + + watch->pollfd.fd = (gintptr) win32_channel->data_avail_event; + watch->pollfd.events = condition; + + if (win32_channel->debug) + g_print ("g_io_win32_fd_create_watch: channel=%p fd=%d condition={%s} event=%p\n", + channel, win32_channel->fd, + condition_to_string (condition), (HANDLE) watch->pollfd.fd); + + EnterCriticalSection (&win32_channel->mutex); + if (win32_channel->thread_id == 0) + { + if (condition & G_IO_IN) + create_thread (win32_channel, condition, read_thread); + else if (condition & G_IO_OUT) + create_thread (win32_channel, condition, write_thread); + } + + g_source_add_poll (source, &watch->pollfd); + LeaveCriticalSection (&win32_channel->mutex); + + return source; +} + +static GIOStatus +g_io_win32_console_close (GIOChannel *channel, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + if (close (win32_channel->fd) < 0) + { + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + g_io_channel_error_from_errno (errno), + g_strerror (errno)); + return G_IO_STATUS_ERROR; + } + + return G_IO_STATUS_NORMAL; +} + +static GSource * +g_io_win32_console_create_watch (GIOChannel *channel, + GIOCondition condition) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch)); + GIOWin32Watch *watch = (GIOWin32Watch *)source; + + watch->channel = channel; + g_io_channel_ref (channel); + + watch->condition = condition; + + watch->pollfd.fd = _get_osfhandle (win32_channel->fd); + watch->pollfd.events = condition; + + g_source_add_poll (source, &watch->pollfd); + + return source; +} + +static GIOStatus +g_io_win32_sock_read (GIOChannel *channel, + gchar *buf, + gsize count, + gsize *bytes_read, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + gint result; + GIOChannelError error; + int winsock_error; + + if (win32_channel->debug) + g_print ("g_io_win32_sock_read: channel=%p sock=%d count=%" G_GSIZE_FORMAT, + channel, win32_channel->fd, count); + + result = recv (win32_channel->fd, buf, count, 0); + if (result == SOCKET_ERROR) + winsock_error = WSAGetLastError (); + + if (win32_channel->debug) + g_print (" recv=%d", result); + + if (result == SOCKET_ERROR) + { + gchar *emsg = g_win32_error_message (winsock_error); + + if (win32_channel->debug) + g_print (" %s\n", emsg); + + *bytes_read = 0; + + switch (winsock_error) + { + case WSAEINVAL: + error = G_IO_CHANNEL_ERROR_INVAL; + break; + case WSAEWOULDBLOCK: + g_free (emsg); + return G_IO_STATUS_AGAIN; + default: + error = G_IO_CHANNEL_ERROR_FAILED; + break; + } + g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg); + g_free (emsg); + + return G_IO_STATUS_ERROR; + } + else + { + if (win32_channel->debug) + g_print ("\n"); + *bytes_read = result; + if (result == 0) + return G_IO_STATUS_EOF; + else + return G_IO_STATUS_NORMAL; + } +} + +static GIOStatus +g_io_win32_sock_write (GIOChannel *channel, + const gchar *buf, + gsize count, + gsize *bytes_written, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + gint result; + GIOChannelError error; + int winsock_error; + + if (win32_channel->debug) + g_print ("g_io_win32_sock_write: channel=%p sock=%d count=%" G_GSIZE_FORMAT, + channel, win32_channel->fd, count); + + result = send (win32_channel->fd, buf, count, 0); + if (result == SOCKET_ERROR) + winsock_error = WSAGetLastError (); + + if (win32_channel->debug) + g_print (" send=%d", result); + + if (result == SOCKET_ERROR) + { + gchar *emsg = g_win32_error_message (winsock_error); + + if (win32_channel->debug) + g_print (" %s\n", emsg); + + *bytes_written = 0; + + switch (winsock_error) + { + case WSAEINVAL: + error = G_IO_CHANNEL_ERROR_INVAL; + break; + case WSAEWOULDBLOCK: + win32_channel->write_would_have_blocked = TRUE; + win32_channel->last_events = 0; + g_free (emsg); + return G_IO_STATUS_AGAIN; + default: + error = G_IO_CHANNEL_ERROR_FAILED; + break; + } + g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg); + g_free (emsg); + + return G_IO_STATUS_ERROR; + } + else + { + if (win32_channel->debug) + g_print ("\n"); + *bytes_written = result; + win32_channel->write_would_have_blocked = FALSE; + + return G_IO_STATUS_NORMAL; + } +} + +static GIOStatus +g_io_win32_sock_close (GIOChannel *channel, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + if (win32_channel->fd != -1) + { + if (win32_channel->debug) + g_print ("g_io_win32_sock_close: channel=%p sock=%d\n", + channel, win32_channel->fd); + + closesocket (win32_channel->fd); + win32_channel->fd = -1; + } + + /* FIXME error detection? */ + + return G_IO_STATUS_NORMAL; +} + +static GSource * +g_io_win32_sock_create_watch (GIOChannel *channel, + GIOCondition condition) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch)); + GIOWin32Watch *watch = (GIOWin32Watch *)source; + + watch->channel = channel; + g_io_channel_ref (channel); + + watch->condition = condition; + + if (win32_channel->event == 0) + win32_channel->event = WSACreateEvent (); + + watch->pollfd.fd = (gintptr) win32_channel->event; + watch->pollfd.events = condition; + + if (win32_channel->debug) + g_print ("g_io_win32_sock_create_watch: channel=%p sock=%d event=%p condition={%s}\n", + channel, win32_channel->fd, (HANDLE) watch->pollfd.fd, + condition_to_string (watch->condition)); + + g_source_add_poll (source, &watch->pollfd); + + return source; +} + +GIOChannel * +g_io_channel_new_file (const gchar *filename, + const gchar *mode, + GError **error) +{ + int fid, flags, pmode; + GIOChannel *channel; + + enum { /* Cheesy hack */ + MODE_R = 1 << 0, + MODE_W = 1 << 1, + MODE_A = 1 << 2, + MODE_PLUS = 1 << 3, + } mode_num; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (mode != NULL, NULL); + g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL); + + switch (mode[0]) + { + case 'r': + mode_num = MODE_R; + break; + case 'w': + mode_num = MODE_W; + break; + case 'a': + mode_num = MODE_A; + break; + default: + g_warning ("Invalid GIOFileMode %s.", mode); + return NULL; + } + + switch (mode[1]) + { + case '\0': + break; + case '+': + if (mode[2] == '\0') + { + mode_num |= MODE_PLUS; + break; + } + /* Fall through */ + default: + g_warning ("Invalid GIOFileMode %s.", mode); + return NULL; + } + + switch (mode_num) + { + case MODE_R: + flags = O_RDONLY; + pmode = _S_IREAD; + break; + case MODE_W: + flags = O_WRONLY | O_TRUNC | O_CREAT; + pmode = _S_IWRITE; + break; + case MODE_A: + flags = O_WRONLY | O_APPEND | O_CREAT; + pmode = _S_IWRITE; + break; + case MODE_R | MODE_PLUS: + flags = O_RDWR; + pmode = _S_IREAD | _S_IWRITE; + break; + case MODE_W | MODE_PLUS: + flags = O_RDWR | O_TRUNC | O_CREAT; + pmode = _S_IREAD | _S_IWRITE; + break; + case MODE_A | MODE_PLUS: + flags = O_RDWR | O_APPEND | O_CREAT; + pmode = _S_IREAD | _S_IWRITE; + break; + default: + g_assert_not_reached (); + abort (); + } + + /* always open 'untranslated' */ + fid = g_open (filename, flags | _O_BINARY, pmode); + + if (g_io_win32_get_debug_flag ()) + { + g_print ("g_io_channel_win32_new_file: open(\"%s\",", filename); + g_win32_print_access_mode (flags|_O_BINARY); + g_print (",%#o)=%d\n", pmode, fid); + } + + if (fid < 0) + { + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errno), + g_strerror (errno)); + return (GIOChannel *)NULL; + } + + channel = g_io_channel_win32_new_fd (fid); + + /* XXX: move this to g_io_channel_win32_new_fd () */ + channel->close_on_unref = TRUE; + channel->is_seekable = TRUE; + + /* g_io_channel_win32_new_fd sets is_readable and is_writeable to + * correspond to actual readability/writeability. Set to FALSE those + * that mode doesn't allow + */ + switch (mode_num) + { + case MODE_R: + channel->is_writeable = FALSE; + break; + case MODE_W: + case MODE_A: + channel->is_readable = FALSE; + break; + case MODE_R | MODE_PLUS: + case MODE_W | MODE_PLUS: + case MODE_A | MODE_PLUS: + break; + default: + g_assert_not_reached (); + abort (); + } + + return channel; +} + +#if !defined (_WIN64) + +#undef g_io_channel_new_file + +/* Binary compatibility version. Not for newly compiled code. */ + +GIOChannel * +g_io_channel_new_file (const gchar *filename, + const gchar *mode, + GError **error) +{ + gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error); + GIOChannel *retval; + + if (utf8_filename == NULL) + return NULL; + + retval = g_io_channel_new_file_utf8 (utf8_filename, mode, error); + + g_free (utf8_filename); + + return retval; +} + +#endif + +static GIOStatus +g_io_win32_unimpl_set_flags (GIOChannel *channel, + GIOFlags flags, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + if (win32_channel->debug) + { + g_print ("g_io_win32_unimpl_set_flags: "); + g_win32_print_gioflags (flags); + g_print ("\n"); + } + + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + G_IO_CHANNEL_ERROR_FAILED, + "Not implemented on Win32"); + + return G_IO_STATUS_ERROR; +} + +static GIOFlags +g_io_win32_fd_get_flags_internal (GIOChannel *channel, + struct _stati64 *st) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel; + gchar c; + DWORD count; + + if (st->st_mode & _S_IFIFO) + { + channel->is_readable = + (PeekNamedPipe ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL, NULL) != 0) || GetLastError () == ERROR_BROKEN_PIPE; + channel->is_writeable = + (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0); + channel->is_seekable = FALSE; + } + else + { + channel->is_readable = + (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0); + channel->is_writeable = + (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0); + channel->is_seekable = TRUE; + } + + /* XXX: G_IO_FLAG_APPEND */ + /* XXX: G_IO_FLAG_NONBLOCK */ + + return 0; +} + +static GIOFlags +g_io_win32_fd_get_flags (GIOChannel *channel) +{ + struct _stati64 st; + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + g_return_val_if_fail (win32_channel != NULL, 0); + g_return_val_if_fail (win32_channel->type == G_IO_WIN32_FILE_DESC, 0); + + if (0 == _fstati64 (win32_channel->fd, &st)) + return g_io_win32_fd_get_flags_internal (channel, &st); + else + return 0; +} + +static GIOFlags +g_io_win32_console_get_flags_internal (GIOChannel *channel) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel; + HANDLE handle = (HANDLE) _get_osfhandle (win32_channel->fd); + gchar c; + DWORD count; + INPUT_RECORD record; + + channel->is_readable = PeekConsoleInput (handle, &record, 1, &count); + channel->is_writeable = WriteFile (handle, &c, 0, &count, NULL); + channel->is_seekable = FALSE; + + return 0; +} + +static GIOFlags +g_io_win32_console_get_flags (GIOChannel *channel) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + g_return_val_if_fail (win32_channel != NULL, 0); + g_return_val_if_fail (win32_channel->type == G_IO_WIN32_CONSOLE, 0); + + return g_io_win32_console_get_flags_internal (channel); +} + +static GIOFlags +g_io_win32_msg_get_flags (GIOChannel *channel) +{ + return 0; +} + +static GIOStatus +g_io_win32_sock_set_flags (GIOChannel *channel, + GIOFlags flags, + GError **err) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + u_long arg; + + if (win32_channel->debug) + { + g_print ("g_io_win32_sock_set_flags: "); + g_win32_print_gioflags (flags); + g_print ("\n"); + } + + if (flags & G_IO_FLAG_NONBLOCK) + { + arg = 1; + if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR) + { + gchar *emsg = g_win32_error_message (WSAGetLastError ()); + + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + G_IO_CHANNEL_ERROR_FAILED, + emsg); + g_free (emsg); + + return G_IO_STATUS_ERROR; + } + } + else + { + arg = 0; + if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR) + { + gchar *emsg = g_win32_error_message (WSAGetLastError ()); + + g_set_error_literal (err, G_IO_CHANNEL_ERROR, + G_IO_CHANNEL_ERROR_FAILED, + emsg); + g_free (emsg); + + return G_IO_STATUS_ERROR; + } + } + + return G_IO_STATUS_NORMAL; +} + +static GIOFlags +g_io_win32_sock_get_flags (GIOChannel *channel) +{ + /* Could we do something here? */ + return 0; +} + +static GIOFuncs win32_channel_msg_funcs = { + g_io_win32_msg_read, + g_io_win32_msg_write, + NULL, + g_io_win32_msg_close, + g_io_win32_msg_create_watch, + g_io_win32_free, + g_io_win32_unimpl_set_flags, + g_io_win32_msg_get_flags, +}; + +static GIOFuncs win32_channel_fd_funcs = { + g_io_win32_fd_and_console_read, + g_io_win32_fd_and_console_write, + g_io_win32_fd_seek, + g_io_win32_fd_close, + g_io_win32_fd_create_watch, + g_io_win32_free, + g_io_win32_unimpl_set_flags, + g_io_win32_fd_get_flags, +}; + +static GIOFuncs win32_channel_console_funcs = { + g_io_win32_fd_and_console_read, + g_io_win32_fd_and_console_write, + NULL, + g_io_win32_console_close, + g_io_win32_console_create_watch, + g_io_win32_free, + g_io_win32_unimpl_set_flags, + g_io_win32_console_get_flags, +}; + +static GIOFuncs win32_channel_sock_funcs = { + g_io_win32_sock_read, + g_io_win32_sock_write, + NULL, + g_io_win32_sock_close, + g_io_win32_sock_create_watch, + g_io_win32_free, + g_io_win32_sock_set_flags, + g_io_win32_sock_get_flags, +}; + +/** + * g_io_channel_win32_new_messages: + * @hwnd: a window handle. + * @Returns: a new #GIOChannel. + * + * Creates a new #GIOChannel given a window handle on Windows. + * + * This function creates a #GIOChannel that can be used to poll for + * Windows messages for the window in question. + **/ +GIOChannel * +#if GLIB_SIZEOF_VOID_P == 8 +g_io_channel_win32_new_messages (gsize hwnd) +#else +g_io_channel_win32_new_messages (guint hwnd) +#endif +{ + GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1); + GIOChannel *channel = (GIOChannel *)win32_channel; + + g_io_channel_init (channel); + g_io_channel_win32_init (win32_channel); + if (win32_channel->debug) + g_print ("g_io_channel_win32_new_messages: channel=%p hwnd=%p\n", + channel, (HWND) hwnd); + channel->funcs = &win32_channel_msg_funcs; + win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES; + win32_channel->hwnd = (HWND) hwnd; + + /* XXX: check this. */ + channel->is_readable = IsWindow (win32_channel->hwnd); + channel->is_writeable = IsWindow (win32_channel->hwnd); + + channel->is_seekable = FALSE; + + return channel; +} + +static GIOChannel * +g_io_channel_win32_new_fd_internal (gint fd, + struct _stati64 *st) +{ + GIOWin32Channel *win32_channel; + GIOChannel *channel; + + win32_channel = g_new (GIOWin32Channel, 1); + channel = (GIOChannel *)win32_channel; + + g_io_channel_init (channel); + g_io_channel_win32_init (win32_channel); + + win32_channel->fd = fd; + + if (win32_channel->debug) + g_print ("g_io_channel_win32_new_fd: channel=%p fd=%u\n", + channel, fd); + + if (st->st_mode & _S_IFCHR) /* console */ + { + channel->funcs = &win32_channel_console_funcs; + win32_channel->type = G_IO_WIN32_CONSOLE; + g_io_win32_console_get_flags_internal (channel); + } + else + { + channel->funcs = &win32_channel_fd_funcs; + win32_channel->type = G_IO_WIN32_FILE_DESC; + g_io_win32_fd_get_flags_internal (channel, st); + } + + return channel; +} + +/** + * g_io_channel_win32_new_fd: + * @fd: a C library file descriptor. + * @Returns: a new #GIOChannel. + * + * Creates a new #GIOChannel given a file descriptor on Windows. This + * works for file descriptors from the C runtime. + * + * This function works for file descriptors as returned by the open(), + * creat(), pipe() and fileno() calls in the Microsoft C runtime. In + * order to meaningfully use this function your code should use the + * same C runtime as GLib uses, which is msvcrt.dll. Note that in + * current Microsoft compilers it is near impossible to convince it to + * build code that would use msvcrt.dll. The last Microsoft compiler + * version that supported using msvcrt.dll as the C runtime was version + * 6. The GNU compiler and toolchain for Windows, also known as Mingw, + * fully supports msvcrt.dll. + * + * If you have created a #GIOChannel for a file descriptor and started + * watching (polling) it, you shouldn't call read() on the file + * descriptor. This is because adding polling for a file descriptor is + * implemented in GLib on Windows by starting a thread that sits + * blocked in a read() from the file descriptor most of the time. All + * reads from the file descriptor should be done by this internal GLib + * thread. Your code should call only g_io_channel_read(). + * + * This function is available only in GLib on Windows. + **/ +GIOChannel * +g_io_channel_win32_new_fd (gint fd) +{ + struct _stati64 st; + + if (_fstati64 (fd, &st) == -1) + { + g_warning ("g_io_channel_win32_new_fd: %d isn't an open file descriptor in the C library GLib uses.", fd); + return NULL; + } + + return g_io_channel_win32_new_fd_internal (fd, &st); +} + +gint +g_io_channel_win32_get_fd (GIOChannel *channel) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + return win32_channel->fd; +} + +/** + * g_io_channel_win32_new_socket: + * @socket: a Winsock socket + * @Returns: a new #GIOChannel + * + * Creates a new #GIOChannel given a socket on Windows. + * + * This function works for sockets created by Winsock. It's available + * only in GLib on Windows. + * + * Polling a #GSource created to watch a channel for a socket puts the + * socket in non-blocking mode. This is a side-effect of the + * implementation and unavoidable. + **/ +GIOChannel * +g_io_channel_win32_new_socket (int socket) +{ + GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1); + GIOChannel *channel = (GIOChannel *)win32_channel; + + g_io_channel_init (channel); + g_io_channel_win32_init (win32_channel); + if (win32_channel->debug) + g_print ("g_io_channel_win32_new_socket: channel=%p sock=%d\n", + channel, socket); + channel->funcs = &win32_channel_sock_funcs; + win32_channel->type = G_IO_WIN32_SOCKET; + win32_channel->fd = socket; + + channel->is_readable = TRUE; + channel->is_writeable = TRUE; + channel->is_seekable = FALSE; + + return channel; +} + +GIOChannel * +g_io_channel_unix_new (gint fd) +{ + gboolean is_fd, is_socket; + struct _stati64 st; + int optval, optlen; + + is_fd = (_fstati64 (fd, &st) == 0); + + optlen = sizeof (optval); + is_socket = (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) != SOCKET_ERROR); + + if (is_fd && is_socket) + g_warning ("g_io_channel_unix_new: %d is both a file descriptor and a socket. File descriptor interpretation assumed. To avoid ambiguity, call either g_io_channel_win32_new_fd() or g_io_channel_win32_new_socket() instead.", fd); + + if (is_fd) + return g_io_channel_win32_new_fd_internal (fd, &st); + + if (is_socket) + return g_io_channel_win32_new_socket(fd); + + g_warning ("g_io_channel_unix_new: %d is neither a file descriptor or a socket.", fd); + + return NULL; +} + +gint +g_io_channel_unix_get_fd (GIOChannel *channel) +{ + return g_io_channel_win32_get_fd (channel); +} + +void +g_io_channel_win32_set_debug (GIOChannel *channel, + gboolean flag) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + win32_channel->debug = flag; +} + +gint +g_io_channel_win32_poll (GPollFD *fds, + gint n_fds, + gint timeout) +{ + g_return_val_if_fail (n_fds >= 0, 0); + + return g_poll (fds, n_fds, timeout); +} + +void +g_io_channel_win32_make_pollfd (GIOChannel *channel, + GIOCondition condition, + GPollFD *fd) +{ + GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel; + + switch (win32_channel->type) + { + case G_IO_WIN32_FILE_DESC: + if (win32_channel->data_avail_event == NULL) + create_events (win32_channel); + + fd->fd = (gintptr) win32_channel->data_avail_event; + + if (win32_channel->thread_id == 0) + { + /* Is it meaningful for a file descriptor to be polled for + * both IN and OUT? For what kind of file descriptor would + * that be? Doesn't seem to make sense, in practise the file + * descriptors handled here are always read or write ends of + * pipes surely, and thus unidirectional. + */ + if (condition & G_IO_IN) + create_thread (win32_channel, condition, read_thread); + else if (condition & G_IO_OUT) + create_thread (win32_channel, condition, write_thread); + } + break; + + case G_IO_WIN32_CONSOLE: + fd->fd = _get_osfhandle (win32_channel->fd); + break; + + case G_IO_WIN32_SOCKET: + fd->fd = (gintptr) WSACreateEvent (); + break; + + case G_IO_WIN32_WINDOWS_MESSAGES: + fd->fd = G_WIN32_MSG_HANDLE; + break; + + default: + g_assert_not_reached (); + abort (); + } + + fd->events = condition; +} + +#ifndef _WIN64 + +/* Binary compatibility */ +GIOChannel * +g_io_channel_win32_new_stream_socket (int socket) +{ + return g_io_channel_win32_new_socket (socket); +} + +#endif diff --git a/glib/glib/gkeyfile.c b/glib/glib/gkeyfile.c new file mode 100644 index 0000000..62ad387 --- /dev/null +++ b/glib/glib/gkeyfile.c @@ -0,0 +1,4383 @@ +/* gkeyfile.c - key file parser + * + * Copyright 2004 Red Hat, Inc. + * Copyright 2009-2010 Collabora Ltd. + * Copyright 2009 Nokia Corporation + * + * Written by Ray Strode + * Matthias Clasen + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "gkeyfile.h" +#include "gutils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef G_OS_WIN32 +#include + +#define fstat(a,b) _fstati64(a,b) +#define stat _stati64 + +#ifndef S_ISREG +#define S_ISREG(mode) ((mode)&_S_IFREG) +#endif + +#endif /* G_OS_WIN23 */ + +#include "gconvert.h" +#include "gdataset.h" +#include "gerror.h" +#include "gfileutils.h" +#include "ghash.h" +#include "glibintl.h" +#include "glist.h" +#include "gslist.h" +#include "gmem.h" +#include "gmessages.h" +#include "gstdio.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "gutils.h" + + +/** + * SECTION:keyfile + * @title: Key-value file parser + * @short_description: parses .ini-like config files + * + * #GKeyFile lets you parse, edit or create files containing groups of + * key-value pairs, which we call key files for + * lack of a better name. Several freedesktop.org specifications use + * key files now, e.g the + * Desktop + * Entry Specification and the + * Icon + * Theme Specification. + * + * The syntax of key files is described in detail in the + * Desktop + * Entry Specification, here is a quick summary: Key files + * consists of groups of key-value pairs, interspersed with comments. + * + * |[ + * # this is just an example + * # there can be comments before the first group + * + * [First Group] + * + * Name=Key File Example\tthis value shows\nescaping + * + * # localized strings are stored in multiple key-value pairs + * Welcome=Hello + * Welcome[de]=Hallo + * Welcome[fr_FR]=Bonjour + * Welcome[it]=Ciao + * Welcome[be@latin]=Hello + * + * [Another Group] + * + * Numbers=2;20;-200;0 + * + * Booleans=true;false;true;true + * ]| + * + * Lines beginning with a '#' and blank lines are considered comments. + * + * Groups are started by a header line containing the group name enclosed + * in '[' and ']', and ended implicitly by the start of the next group or + * the end of the file. Each key-value pair must be contained in a group. + * + * Key-value pairs generally have the form key=value, + * with the exception of localized strings, which have the form + * key[locale]=value, with a locale identifier of the + * form lang_COUNTRY@MODIFIER where + * COUNTRY and MODIFIER are optional. + * Space before and after the '=' character are ignored. Newline, tab, + * carriage return and backslash characters in value are escaped as \n, + * \t, \r, and \\, respectively. To preserve leading spaces in values, + * these can also be escaped as \s. + * + * Key files can store strings (possibly with localized variants), integers, + * booleans and lists of these. Lists are separated by a separator character, + * typically ';' or ','. To use the list separator character in a value in + * a list, it has to be escaped by prefixing it with a backslash. + * + * This syntax is obviously inspired by the .ini files commonly met + * on Windows, but there are some important differences: + * + * .ini files use the ';' character to begin comments, + * key files use the '#' character. + * Key files do not allow for ungrouped keys meaning only + * comments can precede the first group. + * Key files are always encoded in UTF-8. + * Key and Group names are case-sensitive. For example, a + * group called [GROUP] is a different from + * [group]. + * .ini files don't have a strongly typed boolean entry type, + * they only have GetProfileInt(). In key files, only + * true and false (in lower case) + * are allowed. + * + * + * Note that in contrast to the + * Desktop + * Entry Specification, groups in key files may contain the same + * key multiple times; the last entry wins. Key files may also contain + * multiple groups with the same name; they are merged together. + * Another difference is that keys and group names in key files are not + * restricted to ASCII characters. + */ + +/** + * G_KEY_FILE_ERROR: + * + * Error domain for key file parsing. Errors in this domain will + * be from the #GKeyFileError enumeration. + * + * See #GError for information on error domains. + */ + +/** + * GKeyFileError: + * @G_KEY_FILE_ERROR_UNKNOWN_ENCODING: the text being parsed was in + * an unknown encoding + * @G_KEY_FILE_ERROR_PARSE: document was ill-formed + * @G_KEY_FILE_ERROR_NOT_FOUND: the file was not found + * @G_KEY_FILE_ERROR_KEY_NOT_FOUND: a requested key was not found + * @G_KEY_FILE_ERROR_GROUP_NOT_FOUND: a requested group was not found + * @G_KEY_FILE_ERROR_INVALID_VALUE: a value could not be parsed + * + * Error codes returned by key file parsing. + */ + +/** + * GKeyFileFlags: + * @G_KEY_FILE_NONE: No flags, default behaviour + * @G_KEY_FILE_KEEP_COMMENTS: Use this flag if you plan to write the + * (possibly modified) contents of the key file back to a file; + * otherwise all comments will be lost when the key file is + * written back. + * @G_KEY_FILE_KEEP_TRANSLATIONS: Use this flag if you plan to write the + * (possibly modified) contents of the key file back to a file; + * otherwise only the translations for the current language will be + * written back. + * + * Flags which influence the parsing. + */ + +/** + * G_KEY_FILE_DESKTOP_GROUP: + * + * The name of the main group of a desktop entry file, as defined in the + * Desktop + * Entry Specification. Consult the specification for more + * details about the meanings of the keys below. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TYPE: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the type of the desktop entry. Usually + * #G_KEY_FILE_DESKTOP_TYPE_APPLICATION, + * #G_KEY_FILE_DESKTOP_TYPE_LINK, or + * #G_KEY_FILE_DESKTOP_TYPE_DIRECTORY. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_VERSION: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the version of the Desktop Entry Specification used for + * the desktop entry file. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NAME: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the specific name of the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the generic name of the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the desktop entry should be shown in menus. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_COMMENT: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the tooltip for the desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_ICON: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a localized + * string giving the name of the icon to be displayed for the desktop + * entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_HIDDEN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the desktop entry has been deleted by the user. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of + * strings identifying the environments that should display the + * desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list of + * strings identifying the environments that should not display the + * desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TRY_EXEC: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the file name of a binary on disk used to determine if the + * program is actually installed. It is only valid for desktop entries + * with the Application type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_EXEC: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the command line to execute. It is only valid for desktop + * entries with the Application type. + * + * Since: 2.14 + */ + + /** + * G_KEY_FILE_DESKTOP_KEY_PATH: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * containing the working directory to run the program in. It is only + * valid for desktop entries with the Application type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_TERMINAL: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the program should be run in a terminal window. + * It is only valid for desktop entries with the + * Application type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_MIME_TYPE: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list + * of strings giving the MIME types supported by this desktop entry. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_CATEGORIES: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a list + * of strings giving the categories in which the desktop entry + * should be shown in a menu. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a boolean + * stating whether the application supports the Startup + * Notification Protocol Specification. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS: + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is string + * identifying the WM class or name hint of a window that the application + * will create, which can be used to emulate Startup Notification with + * older applications. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_KEY_URL : + * + * A key under #G_KEY_FILE_DESKTOP_GROUP, whose value is a string + * giving the URL to access. It is only valid for desktop entries + * with the Link type. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_APPLICATION: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing applications. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_LINK: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing links to documents. + * + * Since: 2.14 + */ + +/** + * G_KEY_FILE_DESKTOP_TYPE_DIRECTORY: + * + * The value of the #G_KEY_FILE_DESKTOP_KEY_TYPE, key for desktop + * entries representing directories. + * + * Since: 2.14 + */ + +typedef struct _GKeyFileGroup GKeyFileGroup; + +/** + * GKeyFile: + * + * The GKeyFile struct contains only private data + * and should not be accessed directly. + */ +struct _GKeyFile +{ + GList *groups; + GHashTable *group_hash; + + GKeyFileGroup *start_group; + GKeyFileGroup *current_group; + + GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */ + + gchar list_separator; + + GKeyFileFlags flags; + + gchar **locales; + + volatile gint ref_count; +}; + +typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair; + +struct _GKeyFileGroup +{ + const gchar *name; /* NULL for above first group (which will be comments) */ + + GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */ + gboolean has_trailing_blank_line; + + GList *key_value_pairs; + + /* Used in parallel with key_value_pairs for + * increased lookup performance + */ + GHashTable *lookup_map; +}; + +struct _GKeyFileKeyValuePair +{ + gchar *key; /* NULL for comments */ + gchar *value; +}; + +static gint find_file_in_data_dirs (const gchar *file, + const gchar **data_dirs, + gchar **output_file, + GError **error); +static gboolean g_key_file_load_from_fd (GKeyFile *key_file, + gint fd, + GKeyFileFlags flags, + GError **error); +static GList *g_key_file_lookup_group_node (GKeyFile *key_file, + const gchar *group_name); +static GKeyFileGroup *g_key_file_lookup_group (GKeyFile *key_file, + const gchar *group_name); + +static GList *g_key_file_lookup_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key); +static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key); + +static void g_key_file_remove_group_node (GKeyFile *key_file, + GList *group_node); +static void g_key_file_remove_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + GList *pair_node); + +static void g_key_file_add_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + GKeyFileKeyValuePair *pair); +static void g_key_file_add_key (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key, + const gchar *value); +static void g_key_file_add_group (GKeyFile *key_file, + const gchar *group_name); +static gboolean g_key_file_is_group_name (const gchar *name); +static gboolean g_key_file_is_key_name (const gchar *name); +static void g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair); +static gboolean g_key_file_line_is_comment (const gchar *line); +static gboolean g_key_file_line_is_group (const gchar *line); +static gboolean g_key_file_line_is_key_value_pair (const gchar *line); +static gchar *g_key_file_parse_value_as_string (GKeyFile *key_file, + const gchar *value, + GSList **separators, + GError **error); +static gchar *g_key_file_parse_string_as_value (GKeyFile *key_file, + const gchar *string, + gboolean escape_separator); +static gint g_key_file_parse_value_as_integer (GKeyFile *key_file, + const gchar *value, + GError **error); +static gchar *g_key_file_parse_integer_as_value (GKeyFile *key_file, + gint value); +static gdouble g_key_file_parse_value_as_double (GKeyFile *key_file, + const gchar *value, + GError **error); +static gboolean g_key_file_parse_value_as_boolean (GKeyFile *key_file, + const gchar *value, + GError **error); +static gchar *g_key_file_parse_boolean_as_value (GKeyFile *key_file, + gboolean value); +static gchar *g_key_file_parse_value_as_comment (GKeyFile *key_file, + const gchar *value); +static gchar *g_key_file_parse_comment_as_value (GKeyFile *key_file, + const gchar *comment); +static void g_key_file_parse_key_value_pair (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static void g_key_file_parse_comment (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static void g_key_file_parse_group (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error); +static gchar *key_get_locale (const gchar *key); +static void g_key_file_parse_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GError **error); +static void g_key_file_flush_parse_buffer (GKeyFile *key_file, + GError **error); + + +GQuark +g_key_file_error_quark (void) +{ + return g_quark_from_static_string ("g-key-file-error-quark"); +} + +static void +g_key_file_init (GKeyFile *key_file) +{ + key_file->current_group = g_slice_new0 (GKeyFileGroup); + key_file->groups = g_list_prepend (NULL, key_file->current_group); + key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal); + key_file->start_group = NULL; + key_file->parse_buffer = g_string_sized_new (128); + key_file->list_separator = ';'; + key_file->flags = 0; + key_file->locales = g_strdupv ((gchar **)g_get_language_names ()); +} + +static void +g_key_file_clear (GKeyFile *key_file) +{ + GList *tmp, *group_node; + + if (key_file->locales) + { + g_strfreev (key_file->locales); + key_file->locales = NULL; + } + + if (key_file->parse_buffer) + { + g_string_free (key_file->parse_buffer, TRUE); + key_file->parse_buffer = NULL; + } + + tmp = key_file->groups; + while (tmp != NULL) + { + group_node = tmp; + tmp = tmp->next; + g_key_file_remove_group_node (key_file, group_node); + } + + if (key_file->group_hash != NULL) + { + g_hash_table_destroy (key_file->group_hash); + key_file->group_hash = NULL; + } + + g_warn_if_fail (key_file->groups == NULL); +} + + +/** + * g_key_file_new: + * + * Creates a new empty #GKeyFile object. Use + * g_key_file_load_from_file(), g_key_file_load_from_data(), + * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to + * read an existing key file. + * + * Return value: (transfer full): an empty #GKeyFile. + * + * Since: 2.6 + **/ +GKeyFile * +g_key_file_new (void) +{ + GKeyFile *key_file; + + key_file = g_slice_new0 (GKeyFile); + key_file->ref_count = 1; + g_key_file_init (key_file); + + return key_file; +} + +/** + * g_key_file_set_list_separator: + * @key_file: a #GKeyFile + * @separator: the separator + * + * Sets the character which is used to separate + * values in lists. Typically ';' or ',' are used + * as separators. The default list separator is ';'. + * + * Since: 2.6 + */ +void +g_key_file_set_list_separator (GKeyFile *key_file, + gchar separator) +{ + g_return_if_fail (key_file != NULL); + + key_file->list_separator = separator; +} + + +/* Iterates through all the directories in *dirs trying to + * open file. When it successfully locates and opens a file it + * returns the file descriptor to the open file. It also + * outputs the absolute path of the file in output_file. + */ +static gint +find_file_in_data_dirs (const gchar *file, + const gchar **dirs, + gchar **output_file, + GError **error) +{ + const gchar **data_dirs, *data_dir; + gchar *path; + gint fd; + + path = NULL; + fd = -1; + + if (dirs == NULL) + return fd; + + data_dirs = dirs; + + while (data_dirs && (data_dir = *data_dirs) && fd == -1) + { + gchar *candidate_file, *sub_dir; + + candidate_file = (gchar *) file; + sub_dir = g_strdup (""); + while (candidate_file != NULL && fd == -1) + { + gchar *p; + + path = g_build_filename (data_dir, sub_dir, + candidate_file, NULL); + + fd = g_open (path, O_RDONLY, 0); + + if (fd == -1) + { + g_free (path); + path = NULL; + } + + candidate_file = strchr (candidate_file, '-'); + + if (candidate_file == NULL) + break; + + candidate_file++; + + g_free (sub_dir); + sub_dir = g_strndup (file, candidate_file - file - 1); + + for (p = sub_dir; *p != '\0'; p++) + { + if (*p == '-') + *p = G_DIR_SEPARATOR; + } + } + g_free (sub_dir); + data_dirs++; + } + + if (fd == -1) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_NOT_FOUND, + _("Valid key file could not be " + "found in search dirs")); + } + + if (output_file != NULL && fd > 0) + *output_file = g_strdup (path); + + g_free (path); + + return fd; +} + +static gboolean +g_key_file_load_from_fd (GKeyFile *key_file, + gint fd, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gssize bytes_read; + struct stat stat_buf; + gchar read_buf[4096]; + gchar list_separator; + + if (fstat (fd, &stat_buf) < 0) + { + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errno), + g_strerror (errno)); + return FALSE; + } + + if (!S_ISREG (stat_buf.st_mode)) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Not a regular file")); + return FALSE; + } + + list_separator = key_file->list_separator; + g_key_file_clear (key_file); + g_key_file_init (key_file); + key_file->list_separator = list_separator; + key_file->flags = flags; + + do + { + bytes_read = read (fd, read_buf, 4096); + + if (bytes_read == 0) /* End of File */ + break; + + if (bytes_read < 0) + { + if (errno == EINTR || errno == EAGAIN) + continue; + + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errno), + g_strerror (errno)); + return FALSE; + } + + g_key_file_parse_data (key_file, + read_buf, bytes_read, + &key_file_error); + } + while (!key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + g_key_file_flush_parse_buffer (key_file, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + return TRUE; +} + +/** + * g_key_file_load_from_file: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): the path of a filename to load, in the GLib filename encoding + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * Loads a key file into an empty #GKeyFile structure. + * If the file could not be loaded then @error is set to + * either a #GFileError or #GKeyFileError. + * + * Return value: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_file (GKeyFile *key_file, + const gchar *file, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gint fd; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (file != NULL, FALSE); + + fd = g_open (file, O_RDONLY, 0); + + if (fd == -1) + { + g_set_error_literal (error, G_FILE_ERROR, + g_file_error_from_errno (errno), + g_strerror (errno)); + return FALSE; + } + + g_key_file_load_from_fd (key_file, fd, flags, &key_file_error); + close (fd); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + return TRUE; +} + +/** + * g_key_file_load_from_data: + * @key_file: an empty #GKeyFile struct + * @data: key file loaded in memory + * @length: the length of @data in bytes (or -1 if data is nul-terminated) + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * Loads a key file from memory into an empty #GKeyFile structure. + * If the object cannot be created then %error is set to a #GKeyFileError. + * + * Return value: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + gchar list_separator; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (data != NULL || length == 0, FALSE); + + if (length == (gsize)-1) + length = strlen (data); + + list_separator = key_file->list_separator; + g_key_file_clear (key_file); + g_key_file_init (key_file); + key_file->list_separator = list_separator; + key_file->flags = flags; + + g_key_file_parse_data (key_file, data, length, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + g_key_file_flush_parse_buffer (key_file, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + return TRUE; +} + +/** + * g_key_file_load_from_dirs: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): a relative path to a filename to open and parse + * @search_dirs: (array zero-terminated=1) (element-type filename): %NULL-terminated array of directories to search + * @full_path: (out) (type filename): return location for a string containing the full path + * of the file, or %NULL + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * This function looks for a key file named @file in the paths + * specified in @search_dirs, loads the file into @key_file and + * returns the file's full path in @full_path. If the file could not + * be loaded then an %error is set to either a #GFileError or + * #GKeyFileError. + * + * Return value: %TRUE if a key file could be loaded, %FALSE otherwise + * + * Since: 2.14 + **/ +gboolean +g_key_file_load_from_dirs (GKeyFile *key_file, + const gchar *file, + const gchar **search_dirs, + gchar **full_path, + GKeyFileFlags flags, + GError **error) +{ + GError *key_file_error = NULL; + const gchar **data_dirs; + gchar *output_path; + gint fd; + gboolean found_file; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (!g_path_is_absolute (file), FALSE); + g_return_val_if_fail (search_dirs != NULL, FALSE); + + found_file = FALSE; + data_dirs = search_dirs; + output_path = NULL; + while (*data_dirs != NULL && !found_file) + { + g_free (output_path); + + fd = find_file_in_data_dirs (file, data_dirs, &output_path, + &key_file_error); + + if (fd == -1) + { + if (key_file_error) + g_propagate_error (error, key_file_error); + break; + } + + found_file = g_key_file_load_from_fd (key_file, fd, flags, + &key_file_error); + close (fd); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + break; + } + } + + if (found_file && full_path) + *full_path = output_path; + else + g_free (output_path); + + return found_file; +} + +/** + * g_key_file_load_from_data_dirs: + * @key_file: an empty #GKeyFile struct + * @file: (type filename): a relative path to a filename to open and parse + * @full_path: (out) (type filename): return location for a string containing the full path + * of the file, or %NULL + * @flags: flags from #GKeyFileFlags + * @error: return location for a #GError, or %NULL + * + * This function looks for a key file named @file in the paths + * returned from g_get_user_data_dir() and g_get_system_data_dirs(), + * loads the file into @key_file and returns the file's full path in + * @full_path. If the file could not be loaded then an %error is + * set to either a #GFileError or #GKeyFileError. + * + * Return value: %TRUE if a key file could be loaded, %FALSE othewise + * Since: 2.6 + **/ +gboolean +g_key_file_load_from_data_dirs (GKeyFile *key_file, + const gchar *file, + gchar **full_path, + GKeyFileFlags flags, + GError **error) +{ + gchar **all_data_dirs; + const gchar * user_data_dir; + const gchar * const * system_data_dirs; + gsize i, j; + gboolean found_file; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (!g_path_is_absolute (file), FALSE); + + user_data_dir = g_get_user_data_dir (); + system_data_dirs = g_get_system_data_dirs (); + all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2); + + i = 0; + all_data_dirs[i++] = g_strdup (user_data_dir); + + j = 0; + while (system_data_dirs[j] != NULL) + all_data_dirs[i++] = g_strdup (system_data_dirs[j++]); + all_data_dirs[i] = NULL; + + found_file = g_key_file_load_from_dirs (key_file, + file, + (const gchar **)all_data_dirs, + full_path, + flags, + error); + + g_strfreev (all_data_dirs); + + return found_file; +} + +/** + * g_key_file_ref: (skip) + * @key_file: a #GKeyFile + * + * Increases the reference count of @key_file. + * + * Returns: the same @key_file. + * + * Since: 2.32 + **/ +GKeyFile * +g_key_file_ref (GKeyFile *key_file) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + g_atomic_int_inc (&key_file->ref_count); + + return key_file; +} + +/** + * g_key_file_free: (skip) + * @key_file: a #GKeyFile + * + * Clears all keys and groups from @key_file, and decreases the + * reference count by 1. If the reference count reaches zero, + * frees the key file and all its allocated memory. + * + * Since: 2.6 + **/ +void +g_key_file_free (GKeyFile *key_file) +{ + g_return_if_fail (key_file != NULL); + + g_key_file_clear (key_file); + g_key_file_unref (key_file); +} + +/** + * g_key_file_unref: + * @key_file: a #GKeyFile + * + * Decreases the reference count of @key_file by 1. If the reference count + * reaches zero, frees the key file and all its allocated memory. + * + * Since: 2.32 + **/ +void +g_key_file_unref (GKeyFile *key_file) +{ + g_return_if_fail (key_file != NULL); + + if (g_atomic_int_dec_and_test (&key_file->ref_count)) + { + g_key_file_clear (key_file); + g_slice_free (GKeyFile, key_file); + } +} + +/* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns + * true for locales that match those in g_get_language_names(). + */ +static gboolean +g_key_file_locale_is_interesting (GKeyFile *key_file, + const gchar *locale) +{ + gsize i; + + if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS) + return TRUE; + + for (i = 0; key_file->locales[i] != NULL; i++) + { + if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0) + return TRUE; + } + + return FALSE; +} + +static void +g_key_file_parse_line (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + GError *parse_error = NULL; + gchar *line_start; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (line != NULL); + + line_start = (gchar *) line; + while (g_ascii_isspace (*line_start)) + line_start++; + + if (g_key_file_line_is_comment (line_start)) + g_key_file_parse_comment (key_file, line, length, &parse_error); + else if (g_key_file_line_is_group (line_start)) + g_key_file_parse_group (key_file, line_start, + length - (line_start - line), + &parse_error); + else if (g_key_file_line_is_key_value_pair (line_start)) + g_key_file_parse_key_value_pair (key_file, line_start, + length - (line_start - line), + &parse_error); + else + { + gchar *line_utf8 = _g_utf8_make_valid (line); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Key file contains line '%s' which is not " + "a key-value pair, group, or comment"), + line_utf8); + g_free (line_utf8); + + return; + } + + if (parse_error) + g_propagate_error (error, parse_error); +} + +static void +g_key_file_parse_comment (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + GKeyFileKeyValuePair *pair; + + if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS)) + return; + + g_warn_if_fail (key_file->current_group != NULL); + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_strndup (line, length); + + key_file->current_group->key_value_pairs = + g_list_prepend (key_file->current_group->key_value_pairs, pair); + + if (length == 0 || line[0] != '#') + key_file->current_group->has_trailing_blank_line = TRUE; +} + +static void +g_key_file_parse_group (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + gchar *group_name; + const gchar *group_name_start, *group_name_end; + + /* advance past opening '[' + */ + group_name_start = line + 1; + group_name_end = line + length - 1; + + while (*group_name_end != ']') + group_name_end--; + + group_name = g_strndup (group_name_start, + group_name_end - group_name_start); + + if (!g_key_file_is_group_name (group_name)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Invalid group name: %s"), group_name); + g_free (group_name); + return; + } + + g_key_file_add_group (key_file, group_name); + g_free (group_name); +} + +static void +g_key_file_parse_key_value_pair (GKeyFile *key_file, + const gchar *line, + gsize length, + GError **error) +{ + gchar *key, *value, *key_end, *value_start, *locale; + gsize key_len, value_len; + + if (key_file->current_group == NULL || key_file->current_group->name == NULL) + { + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not start with a group")); + return; + } + + key_end = value_start = strchr (line, '='); + + g_warn_if_fail (key_end != NULL); + + key_end--; + value_start++; + + /* Pull the key name from the line (chomping trailing whitespace) + */ + while (g_ascii_isspace (*key_end)) + key_end--; + + key_len = key_end - line + 2; + + g_warn_if_fail (key_len <= length); + + key = g_strndup (line, key_len - 1); + + if (!g_key_file_is_key_name (key)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_PARSE, + _("Invalid key name: %s"), key); + g_free (key); + return; + } + + /* Pull the value from the line (chugging leading whitespace) + */ + while (g_ascii_isspace (*value_start)) + value_start++; + + value_len = line + length - value_start + 1; + + value = g_strndup (value_start, value_len); + + g_warn_if_fail (key_file->start_group != NULL); + + if (key_file->current_group + && key_file->current_group->name + && strcmp (key_file->start_group->name, + key_file->current_group->name) == 0 + && strcmp (key, "Encoding") == 0) + { + if (g_ascii_strcasecmp (value, "UTF-8") != 0) + { + gchar *value_utf8 = _g_utf8_make_valid (value); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains unsupported " + "encoding '%s'"), value_utf8); + g_free (value_utf8); + + g_free (key); + g_free (value); + return; + } + } + + /* Is this key a translation? If so, is it one that we care about? + */ + locale = key_get_locale (key); + + if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale)) + { + GKeyFileKeyValuePair *pair; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = key; + pair->value = value; + + g_key_file_add_key_value_pair (key_file, key_file->current_group, pair); + } + else + { + g_free (key); + g_free (value); + } + + g_free (locale); +} + +static gchar * +key_get_locale (const gchar *key) +{ + gchar *locale; + + locale = g_strrstr (key, "["); + + if (locale && strlen (locale) <= 2) + locale = NULL; + + if (locale) + locale = g_strndup (locale + 1, strlen (locale) - 2); + + return locale; +} + +static void +g_key_file_parse_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GError **error) +{ + GError *parse_error; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (data != NULL || length == 0); + + parse_error = NULL; + + i = 0; + while (i < length) + { + if (data[i] == '\n') + { + if (key_file->parse_buffer->len > 0 + && (key_file->parse_buffer->str[key_file->parse_buffer->len - 1] + == '\r')) + g_string_erase (key_file->parse_buffer, + key_file->parse_buffer->len - 1, + 1); + + /* When a newline is encountered flush the parse buffer so that the + * line can be parsed. Note that completely blank lines won't show + * up in the parse buffer, so they get parsed directly. + */ + if (key_file->parse_buffer->len > 0) + g_key_file_flush_parse_buffer (key_file, &parse_error); + else + g_key_file_parse_comment (key_file, "", 1, &parse_error); + + if (parse_error) + { + g_propagate_error (error, parse_error); + return; + } + i++; + } + else + { + const gchar *start_of_line; + const gchar *end_of_line; + gsize line_length; + + start_of_line = data + i; + end_of_line = memchr (start_of_line, '\n', length - i); + + if (end_of_line == NULL) + end_of_line = data + length; + + line_length = end_of_line - start_of_line; + + g_string_append_len (key_file->parse_buffer, start_of_line, line_length); + i += line_length; + } + } +} + +static void +g_key_file_flush_parse_buffer (GKeyFile *key_file, + GError **error) +{ + GError *file_error = NULL; + + g_return_if_fail (key_file != NULL); + + file_error = NULL; + + if (key_file->parse_buffer->len > 0) + { + g_key_file_parse_line (key_file, key_file->parse_buffer->str, + key_file->parse_buffer->len, + &file_error); + g_string_erase (key_file->parse_buffer, 0, -1); + + if (file_error) + { + g_propagate_error (error, file_error); + return; + } + } +} + +/** + * g_key_file_to_data: + * @key_file: a #GKeyFile + * @length: (out) (allow-none): return location for the length of the + * returned string, or %NULL + * @error: return location for a #GError, or %NULL + * + * This function outputs @key_file as a string. + * + * Note that this function never reports an error, + * so it is safe to pass %NULL as @error. + * + * Return value: a newly allocated string holding + * the contents of the #GKeyFile + * + * Since: 2.6 + **/ +gchar * +g_key_file_to_data (GKeyFile *key_file, + gsize *length, + GError **error) +{ + GString *data_string; + GList *group_node, *key_file_node; + gboolean has_blank_line = TRUE; + + g_return_val_if_fail (key_file != NULL, NULL); + + data_string = g_string_new (NULL); + + for (group_node = g_list_last (key_file->groups); + group_node != NULL; + group_node = group_node->prev) + { + GKeyFileGroup *group; + + group = (GKeyFileGroup *) group_node->data; + + /* separate groups by at least an empty line */ + if (!has_blank_line) + g_string_append_c (data_string, '\n'); + has_blank_line = group->has_trailing_blank_line; + + if (group->comment != NULL) + g_string_append_printf (data_string, "%s\n", group->comment->value); + + if (group->name != NULL) + g_string_append_printf (data_string, "[%s]\n", group->name); + + for (key_file_node = g_list_last (group->key_value_pairs); + key_file_node != NULL; + key_file_node = key_file_node->prev) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) key_file_node->data; + + if (pair->key != NULL) + g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value); + else + g_string_append_printf (data_string, "%s\n", pair->value); + } + } + + if (length) + *length = data_string->len; + + return g_string_free (data_string, FALSE); +} + +/** + * g_key_file_get_keys: + * @key_file: a #GKeyFile + * @group_name: a group name + * @length: (out): return location for the number of keys returned, or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns all keys for the group name @group_name. The array of + * returned keys will be %NULL-terminated, so @length may + * optionally be %NULL. In the event that the @group_name cannot + * be found, %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Return value: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_keys (GKeyFile *key_file, + const gchar *group_name, + gsize *length, + GError **error) +{ + GKeyFileGroup *group; + GList *tmp; + gchar **keys; + gsize i, num_keys; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name ? group_name : "(null)"); + return NULL; + } + + num_keys = 0; + for (tmp = group->key_value_pairs; tmp; tmp = tmp->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key) + num_keys++; + } + + keys = g_new (gchar *, num_keys + 1); + + i = num_keys - 1; + for (tmp = group->key_value_pairs; tmp; tmp = tmp->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key) + { + keys[i] = g_strdup (pair->key); + i--; + } + } + + keys[num_keys] = NULL; + + if (length) + *length = num_keys; + + return keys; +} + +/** + * g_key_file_get_start_group: + * @key_file: a #GKeyFile + * + * Returns the name of the start group of the file. + * + * Return value: The start group of the key file. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_start_group (GKeyFile *key_file) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + if (key_file->start_group) + return g_strdup (key_file->start_group->name); + + return NULL; +} + +/** + * g_key_file_get_groups: + * @key_file: a #GKeyFile + * @length: (out) (allow-none): return location for the number of returned groups, or %NULL + * + * Returns all groups in the key file loaded with @key_file. + * The array of returned groups will be %NULL-terminated, so + * @length may optionally be %NULL. + * + * Return value: (array zero-terminated=1) (transfer full): a newly-allocated %NULL-terminated array of strings. + * Use g_strfreev() to free it. + * Since: 2.6 + **/ +gchar ** +g_key_file_get_groups (GKeyFile *key_file, + gsize *length) +{ + GList *group_node; + gchar **groups; + gsize i, num_groups; + + g_return_val_if_fail (key_file != NULL, NULL); + + num_groups = g_list_length (key_file->groups); + + g_return_val_if_fail (num_groups > 0, NULL); + + group_node = g_list_last (key_file->groups); + + g_return_val_if_fail (((GKeyFileGroup *) group_node->data)->name == NULL, NULL); + + /* Only need num_groups instead of num_groups + 1 + * because the first group of the file (last in the + * list) is always the comment group at the top, + * which we skip + */ + groups = g_new (gchar *, num_groups); + + + i = 0; + for (group_node = group_node->prev; + group_node != NULL; + group_node = group_node->prev) + { + GKeyFileGroup *group; + + group = (GKeyFileGroup *) group_node->data; + + g_warn_if_fail (group->name != NULL); + + groups[i++] = g_strdup (group->name); + } + groups[i] = NULL; + + if (length) + *length = i; + + return groups; +} + +/** + * g_key_file_get_value: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError, or %NULL + * + * Returns the raw value associated with @key under @group_name. + * Use g_key_file_get_string() to retrieve an unescaped UTF-8 string. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * + * Return value: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + gchar *value = NULL; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name ? group_name : "(null)"); + return NULL; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (pair) + value = g_strdup (pair->value); + else + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND, + _("Key file does not have key '%s'"), key); + + return value; +} + +/** + * g_key_file_set_value: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: a string + * + * Associates a new value with @key under @group_name. + * + * If @key cannot be found then it is created. If @group_name cannot + * be found then it is created. To set an UTF-8 string which may contain + * characters that need escaping (such as newlines or spaces), use + * g_key_file_set_string(). + * + * Since: 2.6 + **/ +void +g_key_file_set_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *value) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (g_key_file_is_group_name (group_name)); + g_return_if_fail (g_key_file_is_key_name (key)); + g_return_if_fail (value != NULL); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_key_file_add_group (key_file, group_name); + group = (GKeyFileGroup *) key_file->groups->data; + + g_key_file_add_key (key_file, group, key, value); + } + else + { + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (!pair) + g_key_file_add_key (key_file, group, key, value); + else + { + g_free (pair->value); + pair->value = g_strdup (value); + } + } +} + +/** + * g_key_file_get_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError, or %NULL + * + * Returns the string value associated with @key under @group_name. + * Unlike g_key_file_get_value(), this function handles escape sequences + * like \s. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Return value: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *value, *string_value; + GError *key_file_error; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return NULL; + } + + if (!g_utf8_validate (value, -1, NULL)) + { + gchar *value_utf8 = _g_utf8_make_valid (value); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains key '%s' with value '%s' " + "which is not UTF-8"), key, value_utf8); + g_free (value_utf8); + g_free (value); + + return NULL; + } + + string_value = g_key_file_parse_value_as_string (key_file, value, NULL, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key '%s' " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return string_value; +} + +/** + * g_key_file_set_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @string: a string + * + * Associates a new string value with @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name cannot be found then it is created. + * Unlike g_key_file_set_value(), this function handles characters + * that need escaping, such as newlines. + * + * Since: 2.6 + **/ +void +g_key_file_set_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *string) +{ + gchar *value; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (string != NULL); + + value = g_key_file_parse_string_as_value (key_file, string, FALSE); + g_key_file_set_value (key_file, group_name, key, value); + g_free (value); +} + +/** + * g_key_file_get_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out) (allow-none): return location for the number of returned strings, or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns the values associated with @key under @group_name. + * + * In the event the key cannot be found, %NULL is returned and + * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. In the + * event that the @group_name cannot be found, %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND. + * + * Return value: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): + * a %NULL-terminated string array or %NULL if the specified + * key cannot be found. The array should be freed with g_strfreev(). + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar *value, *string_value, **values; + gint i, len; + GSList *p, *pieces = NULL; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return NULL; + } + + if (!g_utf8_validate (value, -1, NULL)) + { + gchar *value_utf8 = _g_utf8_make_valid (value); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + _("Key file contains key '%s' with value '%s' " + "which is not UTF-8"), key, value_utf8); + g_free (value_utf8); + g_free (value); + + return NULL; + } + + string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error); + g_free (value); + g_free (string_value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key '%s' " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + + g_slist_free_full (pieces, g_free); + return NULL; + } + + len = g_slist_length (pieces); + values = g_new (gchar *, len + 1); + for (p = pieces, i = 0; p; p = p->next) + values[i++] = p->data; + values[len] = NULL; + + g_slist_free (pieces); + + if (length) + *length = len; + + return values; +} + +/** + * g_key_file_set_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array zero-terminated=1 length=length) (element-type utf8): an array of string values + * @length: number of string values in @list + * + * Associates a list of string values for @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar * const list[], + gsize length) +{ + GString *value_list; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL || length == 0); + + value_list = g_string_sized_new (length * 128); + for (i = 0; i < length && list[i] != NULL; i++) + { + gchar *value; + + value = g_key_file_parse_string_as_value (key_file, list[i], TRUE); + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, value_list->str); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_set_locale_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: a locale identifier + * @string: a string + * + * Associates a string value for @key and @locale under @group_name. + * If the translation for @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar *string) +{ + gchar *full_key, *value; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (locale != NULL); + g_return_if_fail (string != NULL); + + value = g_key_file_parse_string_as_value (key_file, string, FALSE); + full_key = g_strdup_printf ("%s[%s]", key, locale); + g_key_file_set_value (key_file, group_name, full_key, value); + g_free (full_key); + g_free (value); +} + +/** + * g_key_file_get_locale_string: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: (allow-none): a locale identifier or %NULL + * @error: return location for a #GError, or %NULL + * + * Returns the value associated with @key under @group_name + * translated in the given @locale if available. If @locale is + * %NULL then the current locale is assumed. + * + * If @key cannot be found then %NULL is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated + * with @key cannot be interpreted or no suitable translation can + * be found then the untranslated value is returned. + * + * Return value: a newly allocated string or %NULL if the specified + * key cannot be found. + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + GError **error) +{ + gchar *candidate_key, *translated_value; + GError *key_file_error; + gchar **languages; + gboolean free_languages = FALSE; + gint i; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + candidate_key = NULL; + translated_value = NULL; + key_file_error = NULL; + + if (locale) + { + languages = g_get_locale_variants (locale); + free_languages = TRUE; + } + else + { + languages = (gchar **) g_get_language_names (); + free_languages = FALSE; + } + + for (i = 0; languages[i]; i++) + { + candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]); + + translated_value = g_key_file_get_string (key_file, + group_name, + candidate_key, NULL); + g_free (candidate_key); + + if (translated_value) + break; + + g_free (translated_value); + translated_value = NULL; + } + + /* Fallback to untranslated key + */ + if (!translated_value) + { + translated_value = g_key_file_get_string (key_file, group_name, key, + &key_file_error); + + if (!translated_value) + g_propagate_error (error, key_file_error); + } + + if (free_languages) + g_strfreev (languages); + + return translated_value; +} + +/** + * g_key_file_get_locale_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: (allow-none): a locale identifier or %NULL + * @length: (out) (allow-none): return location for the number of returned strings or %NULL + * @error: return location for a #GError or %NULL + * + * Returns the values associated with @key under @group_name + * translated in the given @locale if available. If @locale is + * %NULL then the current locale is assumed. + + * If @key cannot be found then %NULL is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated + * with @key cannot be interpreted or no suitable translations + * can be found then the untranslated values are returned. The + * returned array is %NULL-terminated, so @length may optionally + * be %NULL. + * + * Return value: (array zero-terminated=1 length=length) (element-type utf8) (transfer full): a newly allocated %NULL-terminated string array + * or %NULL if the key isn't found. The string array should be freed + * with g_strfreev(). + * + * Since: 2.6 + **/ +gchar ** +g_key_file_get_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + gsize *length, + GError **error) +{ + GError *key_file_error; + gchar **values, *value; + char list_separator[2]; + gsize len; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + key_file_error = NULL; + + value = g_key_file_get_locale_string (key_file, group_name, + key, locale, + &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!value) + { + if (length) + *length = 0; + return NULL; + } + + len = strlen (value); + if (value[len - 1] == key_file->list_separator) + value[len - 1] = '\0'; + + list_separator[0] = key_file->list_separator; + list_separator[1] = '\0'; + values = g_strsplit (value, list_separator, 0); + + g_free (value); + + if (length) + *length = g_strv_length (values); + + return values; +} + +/** + * g_key_file_set_locale_string_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @locale: a locale identifier + * @list: (array zero-terminated=1 length=length): a %NULL-terminated array of locale string values + * @length: the length of @list + * + * Associates a list of string values for @key and @locale under + * @group_name. If the translation for @key cannot be found then + * it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar * const list[], + gsize length) +{ + GString *value_list; + gchar *full_key; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (key != NULL); + g_return_if_fail (locale != NULL); + g_return_if_fail (length != 0); + + value_list = g_string_sized_new (length * 128); + for (i = 0; i < length && list[i] != NULL; i++) + { + gchar *value; + + value = g_key_file_parse_string_as_value (key_file, list[i], TRUE); + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + full_key = g_strdup_printf ("%s[%s]", key, locale); + g_key_file_set_value (key_file, group_name, full_key, value_list->str); + g_free (full_key); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_get_boolean: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a + * boolean. + * + * If @key cannot be found then %FALSE is returned and @error is set + * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value + * associated with @key cannot be interpreted as a boolean then %FALSE + * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Return value: the value associated with the key as a boolean, + * or %FALSE if the key was not found or could not be parsed. + * + * Since: 2.6 + **/ +gboolean +g_key_file_get_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error = NULL; + gchar *value; + gboolean bool_value; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (!value) + { + g_propagate_error (error, key_file_error); + return FALSE; + } + + bool_value = g_key_file_parse_value_as_boolean (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key '%s' " + "which has a value that cannot be interpreted."), + key); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return bool_value; +} + +/** + * g_key_file_set_boolean: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: %TRUE or %FALSE + * + * Associates a new boolean value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_key_file_parse_boolean_as_value (key_file, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_boolean_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of booleans returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * booleans. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as booleans then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Return value: (array length=length) (element-type gboolean) (transfer container): + * the values associated with the key as a list of booleans, or %NULL if the + * key was not found or could not be parsed. The returned list of booleans + * should be freed with g_free() when no longer needed. + * + * Since: 2.6 + **/ +gboolean * +g_key_file_get_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error; + gchar **values; + gboolean *bool_values; + gsize i, num_bools; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + key_file_error = NULL; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_bools, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + bool_values = g_new (gboolean, num_bools); + + for (i = 0; i < num_bools; i++) + { + bool_values[i] = g_key_file_parse_value_as_boolean (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (bool_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_bools; + + return bool_values; +} + +/** + * g_key_file_set_boolean_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of boolean values + * @length: length of @list + * + * Associates a list of boolean values with @key under @group_name. + * If @key cannot be found then it is created. + * If @group_name is %NULL, the start_group is used. + * + * Since: 2.6 + **/ +void +g_key_file_set_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean list[], + gsize length) +{ + GString *value_list; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + value_list = g_string_sized_new (length * 8); + for (i = 0; i < length; i++) + { + gchar *value; + + value = g_key_file_parse_boolean_as_value (key_file, list[i]); + + g_string_append (value_list, value); + g_string_append_c (value_list, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, value_list->str); + g_string_free (value_list, TRUE); +} + +/** + * g_key_file_get_integer: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as an + * integer. + * + * If @key cannot be found then 0 is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated + * with @key cannot be interpreted as an integer then 0 is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Return value: the value associated with the key as an integer, or + * 0 if the key was not found or could not be parsed. + * + * Since: 2.6 + **/ +gint +g_key_file_get_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error; + gchar *value; + gint int_value; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return 0; + } + + int_value = g_key_file_parse_value_as_integer (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key '%s' in group '%s' " + "which has a value that cannot be interpreted."), + key, group_name); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return int_value; +} + +/** + * g_key_file_set_integer: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_key_file_parse_integer_as_value (key_file, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_int64: + * @key_file: a non-%NULL #GKeyFile + * @group_name: a non-%NULL group name + * @key: a non-%NULL key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a signed + * 64-bit integer. This is similar to g_key_file_get_integer() but can return + * 64-bit results without truncation. + * + * Returns: the value associated with the key as a signed 64-bit integer, or + * 0 if the key was not found or could not be parsed. + * + * Since: 2.26 + */ +gint64 +g_key_file_get_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *s, *end; + gint64 v; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + s = g_key_file_get_value (key_file, group_name, key, error); + + if (s == NULL) + return 0; + + v = g_ascii_strtoll (s, &end, 10); + + if (*s == '\0' || *end != '\0') + { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key '%s' in group '%s' has value '%s' " + "where %s was expected"), + key, group_name, s, "int64"); + return 0; + } + + g_free (s); + return v; +} + +/** + * g_key_file_set_int64: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.26 + **/ +void +g_key_file_set_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint64 value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_strdup_printf ("%" G_GINT64_FORMAT, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_uint64: + * @key_file: a non-%NULL #GKeyFile + * @group_name: a non-%NULL group name + * @key: a non-%NULL key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as an unsigned + * 64-bit integer. This is similar to g_key_file_get_integer() but can return + * large positive results without truncation. + * + * Returns: the value associated with the key as an unsigned 64-bit integer, + * or 0 if the key was not found or could not be parsed. + * + * Since: 2.26 + */ +guint64 +g_key_file_get_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + gchar *s, *end; + guint64 v; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + s = g_key_file_get_value (key_file, group_name, key, error); + + if (s == NULL) + return 0; + + v = g_ascii_strtoull (s, &end, 10); + + if (*s == '\0' || *end != '\0') + { + g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key '%s' in group '%s' has value '%s' " + "where %s was expected"), + key, group_name, s, "uint64"); + return 0; + } + + g_free (s); + return v; +} + +/** + * g_key_file_set_uint64: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an integer value + * + * Associates a new integer value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.26 + **/ +void +g_key_file_set_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + guint64 value) +{ + gchar *result; + + g_return_if_fail (key_file != NULL); + + result = g_strdup_printf ("%" G_GUINT64_FORMAT, value); + g_key_file_set_value (key_file, group_name, key, result); + g_free (result); +} + +/** + * g_key_file_get_integer_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of integers returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * integers. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as integers then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Return value: (array length=length) (element-type gint) (transfer container): + * the values associated with the key as a list of integers, or %NULL if + * the key was not found or could not be parsed. The returned list of + * integers should be freed with g_free() when no longer needed. + * + * Since: 2.6 + **/ +gint * +g_key_file_get_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar **values; + gint *int_values; + gsize i, num_ints; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_ints, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + int_values = g_new (gint, num_ints); + + for (i = 0; i < num_ints; i++) + { + int_values[i] = g_key_file_parse_value_as_integer (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (int_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_ints; + + return int_values; +} + +/** + * g_key_file_set_integer_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of integer values + * @length: number of integer values in @list + * + * Associates a list of integer values with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.6 + **/ +void +g_key_file_set_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint list[], + gsize length) +{ + GString *values; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + values = g_string_sized_new (length * 16); + for (i = 0; i < length; i++) + { + gchar *value; + + value = g_key_file_parse_integer_as_value (key_file, list[i]); + + g_string_append (values, value); + g_string_append_c (values, key_file->list_separator); + + g_free (value); + } + + g_key_file_set_value (key_file, group_name, key, values->str); + g_string_free (values, TRUE); +} + +/** + * g_key_file_get_double: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @error: return location for a #GError + * + * Returns the value associated with @key under @group_name as a + * double. If @group_name is %NULL, the start_group is used. + * + * If @key cannot be found then 0.0 is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated + * with @key cannot be interpreted as a double then 0.0 is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Return value: the value associated with the key as a double, or + * 0.0 if the key was not found or could not be parsed. + * + * Since: 2.12 + **/ +gdouble +g_key_file_get_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *key_file_error; + gchar *value; + gdouble double_value; + + g_return_val_if_fail (key_file != NULL, -1); + g_return_val_if_fail (group_name != NULL, -1); + g_return_val_if_fail (key != NULL, -1); + + key_file_error = NULL; + + value = g_key_file_get_value (key_file, group_name, key, &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + return 0; + } + + double_value = g_key_file_parse_value_as_double (key_file, value, + &key_file_error); + g_free (value); + + if (key_file_error) + { + if (g_error_matches (key_file_error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE)) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains key '%s' in group '%s' " + "which has a value that cannot be interpreted."), + key, group_name); + g_error_free (key_file_error); + } + else + g_propagate_error (error, key_file_error); + } + + return double_value; +} + +/** + * g_key_file_set_double: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @value: an double value + * + * Associates a new double value with @key under @group_name. + * If @key cannot be found then it is created. + * + * Since: 2.12 + **/ +void +g_key_file_set_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble value) +{ + gchar result[G_ASCII_DTOSTR_BUF_SIZE]; + + g_return_if_fail (key_file != NULL); + + g_ascii_dtostr (result, sizeof (result), value); + g_key_file_set_value (key_file, group_name, key, result); +} + +/** + * g_key_file_get_double_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @length: (out): the number of doubles returned + * @error: return location for a #GError + * + * Returns the values associated with @key under @group_name as + * doubles. + * + * If @key cannot be found then %NULL is returned and @error is set to + * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated + * with @key cannot be interpreted as doubles then %NULL is returned + * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE. + * + * Return value: (array length=length) (element-type gdouble) (transfer container): + * the values associated with the key as a list of doubles, or %NULL if the + * key was not found or could not be parsed. The returned list of doubles + * should be freed with g_free() when no longer needed. + * + * Since: 2.12 + **/ +gdouble * +g_key_file_get_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) +{ + GError *key_file_error = NULL; + gchar **values; + gdouble *double_values; + gsize i, num_doubles; + + g_return_val_if_fail (key_file != NULL, NULL); + g_return_val_if_fail (group_name != NULL, NULL); + g_return_val_if_fail (key != NULL, NULL); + + if (length) + *length = 0; + + values = g_key_file_get_string_list (key_file, group_name, key, + &num_doubles, &key_file_error); + + if (key_file_error) + g_propagate_error (error, key_file_error); + + if (!values) + return NULL; + + double_values = g_new (gdouble, num_doubles); + + for (i = 0; i < num_doubles; i++) + { + double_values[i] = g_key_file_parse_value_as_double (key_file, + values[i], + &key_file_error); + + if (key_file_error) + { + g_propagate_error (error, key_file_error); + g_strfreev (values); + g_free (double_values); + + return NULL; + } + } + g_strfreev (values); + + if (length) + *length = num_doubles; + + return double_values; +} + +/** + * g_key_file_set_double_list: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key + * @list: (array length=length): an array of double values + * @length: number of double values in @list + * + * Associates a list of double values with @key under + * @group_name. If @key cannot be found then it is created. + * + * Since: 2.12 + **/ +void +g_key_file_set_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble list[], + gsize length) +{ + GString *values; + gsize i; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (list != NULL); + + values = g_string_sized_new (length * 16); + for (i = 0; i < length; i++) + { + gchar result[G_ASCII_DTOSTR_BUF_SIZE]; + + g_ascii_dtostr( result, sizeof (result), list[i] ); + + g_string_append (values, result); + g_string_append_c (values, key_file->list_separator); + } + + g_key_file_set_value (key_file, group_name, key, values->str); + g_string_free (values, TRUE); +} + +static gboolean +g_key_file_set_key_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *comment, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + GList *key_node, *comment_node, *tmp; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name ? group_name : "(null)"); + + return FALSE; + } + + /* First find the key the comments are supposed to be + * associated with + */ + key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key); + + if (key_node == NULL) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND, + _("Key file does not have key '%s' in group '%s'"), + key, group->name); + return FALSE; + } + + /* Then find all the comments already associated with the + * key and free them + */ + tmp = key_node->next; + while (tmp != NULL) + { + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key != NULL) + break; + + comment_node = tmp; + tmp = tmp->next; + g_key_file_remove_key_value_pair_node (key_file, group, + comment_node); + } + + if (comment == NULL) + return TRUE; + + /* Now we can add our new comment + */ + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); + + key_node = g_list_insert (key_node, pair, 1); + + return TRUE; +} + +static gboolean +g_key_file_set_group_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *comment, + GError **error) +{ + GKeyFileGroup *group; + + g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE); + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name ? group_name : "(null)"); + + return FALSE; + } + + /* First remove any existing comment + */ + if (group->comment) + { + g_key_file_key_value_pair_free (group->comment); + group->comment = NULL; + } + + if (comment == NULL) + return TRUE; + + /* Now we can add our new comment + */ + group->comment = g_slice_new (GKeyFileKeyValuePair); + group->comment->key = NULL; + group->comment->value = g_key_file_parse_comment_as_value (key_file, comment); + + return TRUE; +} + +static gboolean +g_key_file_set_top_comment (GKeyFile *key_file, + const gchar *comment, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + /* The last group in the list should be the top (comments only) + * group in the file + */ + g_warn_if_fail (key_file->groups != NULL); + group_node = g_list_last (key_file->groups); + group = (GKeyFileGroup *) group_node->data; + g_warn_if_fail (group->name == NULL); + + /* Note all keys must be comments at the top of + * the file, so we can just free it all. + */ + g_list_free_full (group->key_value_pairs, (GDestroyNotify) g_key_file_key_value_pair_free); + group->key_value_pairs = NULL; + + if (comment == NULL) + return TRUE; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = NULL; + pair->value = g_key_file_parse_comment_as_value (key_file, comment); + + group->key_value_pairs = + g_list_prepend (group->key_value_pairs, pair); + + return TRUE; +} + +/** + * g_key_file_set_comment: + * @key_file: a #GKeyFile + * @group_name: (allow-none): a group name, or %NULL + * @key: (allow-none): a key + * @comment: a comment + * @error: return location for a #GError + * + * Places a comment above @key from @group_name. + * If @key is %NULL then @comment will be written above @group_name. + * If both @key and @group_name are %NULL, then @comment will be + * written above the first group in the file. + * + * Returns: %TRUE if the comment was written, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_set_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *comment, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + + if (group_name != NULL && key != NULL) + { + if (!g_key_file_set_key_comment (key_file, group_name, key, comment, error)) + return FALSE; + } + else if (group_name != NULL) + { + if (!g_key_file_set_group_comment (key_file, group_name, comment, error)) + return FALSE; + } + else + { + if (!g_key_file_set_top_comment (key_file, comment, error)) + return FALSE; + } + + return TRUE; +} + +static gchar * +g_key_file_get_key_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + GList *key_node, *tmp; + GString *string; + gchar *comment; + + g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL); + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name ? group_name : "(null)"); + + return NULL; + } + + /* First find the key the comments are supposed to be + * associated with + */ + key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key); + + if (key_node == NULL) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND, + _("Key file does not have key '%s' in group '%s'"), + key, group->name); + return NULL; + } + + string = NULL; + + /* Then find all the comments already associated with the + * key and concatentate them. + */ + tmp = key_node->next; + if (!key_node->next) + return NULL; + + pair = (GKeyFileKeyValuePair *) tmp->data; + if (pair->key != NULL) + return NULL; + + while (tmp->next) + { + pair = (GKeyFileKeyValuePair *) tmp->next->data; + + if (pair->key != NULL) + break; + + tmp = tmp->next; + } + + while (tmp != key_node) + { + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (string == NULL) + string = g_string_sized_new (512); + + comment = g_key_file_parse_value_as_comment (key_file, pair->value); + g_string_append (string, comment); + g_free (comment); + + tmp = tmp->prev; + } + + if (string != NULL) + { + comment = string->str; + g_string_free (string, FALSE); + } + else + comment = NULL; + + return comment; +} + +static gchar * +get_group_comment (GKeyFile *key_file, + GKeyFileGroup *group, + GError **error) +{ + GString *string; + GList *tmp; + gchar *comment; + + string = NULL; + + tmp = group->key_value_pairs; + while (tmp) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (pair->key != NULL) + { + tmp = tmp->prev; + break; + } + + if (tmp->next == NULL) + break; + + tmp = tmp->next; + } + + while (tmp != NULL) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) tmp->data; + + if (string == NULL) + string = g_string_sized_new (512); + + comment = g_key_file_parse_value_as_comment (key_file, pair->value); + g_string_append (string, comment); + g_free (comment); + + tmp = tmp->prev; + } + + if (string != NULL) + return g_string_free (string, FALSE); + + return NULL; +} + +static gchar * +g_key_file_get_group_comment (GKeyFile *key_file, + const gchar *group_name, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name ? group_name : "(null)"); + + return NULL; + } + + if (group->comment) + return g_strdup (group->comment->value); + + group_node = g_key_file_lookup_group_node (key_file, group_name); + group_node = group_node->next; + group = (GKeyFileGroup *)group_node->data; + return get_group_comment (key_file, group, error); +} + +static gchar * +g_key_file_get_top_comment (GKeyFile *key_file, + GError **error) +{ + GList *group_node; + GKeyFileGroup *group; + + /* The last group in the list should be the top (comments only) + * group in the file + */ + g_warn_if_fail (key_file->groups != NULL); + group_node = g_list_last (key_file->groups); + group = (GKeyFileGroup *) group_node->data; + g_warn_if_fail (group->name == NULL); + + return get_group_comment (key_file, group, error); +} + +/** + * g_key_file_get_comment: + * @key_file: a #GKeyFile + * @group_name: a group name, or %NULL + * @key: a key + * @error: return location for a #GError + * + * Retrieves a comment above @key from @group_name. + * If @key is %NULL then @comment will be read from above + * @group_name. If both @key and @group_name are %NULL, then + * @comment will be read from above the first group in the file. + * + * Returns: a comment that should be freed with g_free() + * + * Since: 2.6 + **/ +gchar * +g_key_file_get_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, NULL); + + if (group_name != NULL && key != NULL) + return g_key_file_get_key_comment (key_file, group_name, key, error); + else if (group_name != NULL) + return g_key_file_get_group_comment (key_file, group_name, error); + else + return g_key_file_get_top_comment (key_file, error); +} + +/** + * g_key_file_remove_comment: + * @key_file: a #GKeyFile + * @group_name: (allow-none): a group name, or %NULL + * @key: (allow-none): a key + * @error: return location for a #GError + * + * Removes a comment above @key from @group_name. + * If @key is %NULL then @comment will be removed above @group_name. + * If both @key and @group_name are %NULL, then @comment will + * be removed above the first group in the file. + * + * Returns: %TRUE if the comment was removed, %FALSE otherwise + * + * Since: 2.6 + **/ + +gboolean +g_key_file_remove_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + + if (group_name != NULL && key != NULL) + return g_key_file_set_key_comment (key_file, group_name, key, NULL, error); + else if (group_name != NULL) + return g_key_file_set_group_comment (key_file, group_name, NULL, error); + else + return g_key_file_set_top_comment (key_file, NULL, error); +} + +/** + * g_key_file_has_group: + * @key_file: a #GKeyFile + * @group_name: a group name + * + * Looks whether the key file has the group @group_name. + * + * Return value: %TRUE if @group_name is a part of @key_file, %FALSE + * otherwise. + * Since: 2.6 + **/ +gboolean +g_key_file_has_group (GKeyFile *key_file, + const gchar *group_name) +{ + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + + return g_key_file_lookup_group (key_file, group_name) != NULL; +} + +/* This code remains from a historical attempt to add a new public API + * which respects the GError rules. + */ +static gboolean +g_key_file_has_key_full (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean *has_key, + GError **error) +{ + GKeyFileKeyValuePair *pair; + GKeyFileGroup *group; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + group = g_key_file_lookup_group (key_file, group_name); + + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name ? group_name : "(null)"); + + return FALSE; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (has_key) + *has_key = pair != NULL; + return TRUE; +} + +/** + * g_key_file_has_key: (skip) + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key name + * @error: return location for a #GError + * + * Looks whether the key file has the key @key in the group + * @group_name. + * + * This function does not follow the rules for #GError strictly; + * the return value both carries meaning and signals an error. To use + * this function, you must pass a #GError pointer in @error, and check + * whether it is not %NULL to see if an error occurred. + * + * Language bindings should use g_key_file_get_value() to test whether + * or not a key exists. + * + * Return value: %TRUE if @key is a part of @group_name, %FALSE + * otherwise. + * + * Since: 2.6 + **/ +gboolean +g_key_file_has_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GError *temp_error = NULL; + gboolean has_key; + + if (g_key_file_has_key_full (key_file, group_name, key, &has_key, &temp_error)) + { + return has_key; + } + else + { + g_propagate_error (error, temp_error); + return FALSE; + } +} + +static void +g_key_file_add_group (GKeyFile *key_file, + const gchar *group_name) +{ + GKeyFileGroup *group; + + g_return_if_fail (key_file != NULL); + g_return_if_fail (g_key_file_is_group_name (group_name)); + + group = g_key_file_lookup_group (key_file, group_name); + if (group != NULL) + { + key_file->current_group = group; + return; + } + + group = g_slice_new0 (GKeyFileGroup); + group->name = g_strdup (group_name); + group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal); + key_file->groups = g_list_prepend (key_file->groups, group); + key_file->current_group = group; + + if (key_file->start_group == NULL) + key_file->start_group = group; + + g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group); +} + +static void +g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair) +{ + if (pair != NULL) + { + g_free (pair->key); + g_free (pair->value); + g_slice_free (GKeyFileKeyValuePair, pair); + } +} + +/* Be careful not to call this function on a node with data in the + * lookup map without removing it from the lookup map, first. + * + * Some current cases where this warning is not a concern are + * when: + * - the node being removed is a comment node + * - the entire lookup map is getting destroyed soon after + * anyway. + */ +static void +g_key_file_remove_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + GList *pair_node) +{ + + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) pair_node->data; + + group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node); + + g_warn_if_fail (pair->value != NULL); + + g_key_file_key_value_pair_free (pair); + + g_list_free_1 (pair_node); +} + +static void +g_key_file_remove_group_node (GKeyFile *key_file, + GList *group_node) +{ + GKeyFileGroup *group; + GList *tmp; + + group = (GKeyFileGroup *) group_node->data; + + if (group->name) + g_hash_table_remove (key_file->group_hash, group->name); + + /* If the current group gets deleted make the current group the last + * added group. + */ + if (key_file->current_group == group) + { + /* groups should always contain at least the top comment group, + * unless g_key_file_clear has been called + */ + if (key_file->groups) + key_file->current_group = (GKeyFileGroup *) key_file->groups->data; + else + key_file->current_group = NULL; + } + + /* If the start group gets deleted make the start group the first + * added group. + */ + if (key_file->start_group == group) + { + tmp = g_list_last (key_file->groups); + while (tmp != NULL) + { + if (tmp != group_node && + ((GKeyFileGroup *) tmp->data)->name != NULL) + break; + + tmp = tmp->prev; + } + + if (tmp) + key_file->start_group = (GKeyFileGroup *) tmp->data; + else + key_file->start_group = NULL; + } + + key_file->groups = g_list_remove_link (key_file->groups, group_node); + + tmp = group->key_value_pairs; + while (tmp != NULL) + { + GList *pair_node; + + pair_node = tmp; + tmp = tmp->next; + g_key_file_remove_key_value_pair_node (key_file, group, pair_node); + } + + g_warn_if_fail (group->key_value_pairs == NULL); + + if (group->comment) + { + g_key_file_key_value_pair_free (group->comment); + group->comment = NULL; + } + + if (group->lookup_map) + { + g_hash_table_destroy (group->lookup_map); + group->lookup_map = NULL; + } + + g_free ((gchar *) group->name); + g_slice_free (GKeyFileGroup, group); + g_list_free_1 (group_node); +} + +/** + * g_key_file_remove_group: + * @key_file: a #GKeyFile + * @group_name: a group name + * @error: return location for a #GError or %NULL + * + * Removes the specified group, @group_name, + * from the key file. + * + * Returns: %TRUE if the group was removed, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_remove_group (GKeyFile *key_file, + const gchar *group_name, + GError **error) +{ + GList *group_node; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + + group_node = g_key_file_lookup_group_node (key_file, group_name); + + if (!group_node) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name); + return FALSE; + } + + g_key_file_remove_group_node (key_file, group_node); + + return TRUE; +} + +static void +g_key_file_add_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + GKeyFileKeyValuePair *pair) +{ + g_hash_table_replace (group->lookup_map, pair->key, pair); + group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair); + group->has_trailing_blank_line = FALSE; +} + +static void +g_key_file_add_key (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key, + const gchar *value) +{ + GKeyFileKeyValuePair *pair; + + pair = g_slice_new (GKeyFileKeyValuePair); + pair->key = g_strdup (key); + pair->value = g_strdup (value); + + g_key_file_add_key_value_pair (key_file, group, pair); +} + +/** + * g_key_file_remove_key: + * @key_file: a #GKeyFile + * @group_name: a group name + * @key: a key name to remove + * @error: return location for a #GError or %NULL + * + * Removes @key in @group_name from the key file. + * + * Returns: %TRUE if the key was removed, %FALSE otherwise + * + * Since: 2.6 + **/ +gboolean +g_key_file_remove_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) +{ + GKeyFileGroup *group; + GKeyFileKeyValuePair *pair; + + g_return_val_if_fail (key_file != NULL, FALSE); + g_return_val_if_fail (group_name != NULL, FALSE); + g_return_val_if_fail (key != NULL, FALSE); + + pair = NULL; + + group = g_key_file_lookup_group (key_file, group_name); + if (!group) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + _("Key file does not have group '%s'"), + group_name ? group_name : "(null)"); + return FALSE; + } + + pair = g_key_file_lookup_key_value_pair (key_file, group, key); + + if (!pair) + { + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_KEY_NOT_FOUND, + _("Key file does not have key '%s' in group '%s'"), + key, group->name); + return FALSE; + } + + group->key_value_pairs = g_list_remove (group->key_value_pairs, pair); + g_hash_table_remove (group->lookup_map, pair->key); + g_key_file_key_value_pair_free (pair); + + return TRUE; +} + +static GList * +g_key_file_lookup_group_node (GKeyFile *key_file, + const gchar *group_name) +{ + GKeyFileGroup *group; + GList *tmp; + + for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next) + { + group = (GKeyFileGroup *) tmp->data; + + if (group && group->name && strcmp (group->name, group_name) == 0) + break; + } + + return tmp; +} + +static GKeyFileGroup * +g_key_file_lookup_group (GKeyFile *key_file, + const gchar *group_name) +{ + return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name); +} + +static GList * +g_key_file_lookup_key_value_pair_node (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key) +{ + GList *key_node; + + for (key_node = group->key_value_pairs; + key_node != NULL; + key_node = key_node->next) + { + GKeyFileKeyValuePair *pair; + + pair = (GKeyFileKeyValuePair *) key_node->data; + + if (pair->key && strcmp (pair->key, key) == 0) + break; + } + + return key_node; +} + +static GKeyFileKeyValuePair * +g_key_file_lookup_key_value_pair (GKeyFile *key_file, + GKeyFileGroup *group, + const gchar *key) +{ + return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key); +} + +/* Lines starting with # or consisting entirely of whitespace are merely + * recorded, not parsed. This function assumes all leading whitespace + * has been stripped. + */ +static gboolean +g_key_file_line_is_comment (const gchar *line) +{ + return (*line == '#' || *line == '\0' || *line == '\n'); +} + +static gboolean +g_key_file_is_group_name (const gchar *name) +{ + gchar *p, *q; + + if (name == NULL) + return FALSE; + + p = q = (gchar *) name; + while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q)) + q = g_utf8_find_next_char (q, NULL); + + if (*q != '\0' || q == p) + return FALSE; + + return TRUE; +} + +static gboolean +g_key_file_is_key_name (const gchar *name) +{ + gchar *p, *q; + + if (name == NULL) + return FALSE; + + p = q = (gchar *) name; + /* We accept a little more than the desktop entry spec says, + * since gnome-vfs uses mime-types as keys in its cache. + */ + while (*q && *q != '=' && *q != '[' && *q != ']') + q = g_utf8_find_next_char (q, NULL); + + /* No empty keys, please */ + if (q == p) + return FALSE; + + /* We accept spaces in the middle of keys to not break + * existing apps, but we don't tolerate initial or final + * spaces, which would lead to silent corruption when + * rereading the file. + */ + if (*p == ' ' || q[-1] == ' ') + return FALSE; + + if (*q == '[') + { + q++; + while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@')) + q = g_utf8_find_next_char (q, NULL); + + if (*q != ']') + return FALSE; + + q++; + } + + if (*q != '\0') + return FALSE; + + return TRUE; +} + +/* A group in a key file is made up of a starting '[' followed by one + * or more letters making up the group name followed by ']'. + */ +static gboolean +g_key_file_line_is_group (const gchar *line) +{ + gchar *p; + + p = (gchar *) line; + if (*p != '[') + return FALSE; + + p++; + + while (*p && *p != ']') + p = g_utf8_find_next_char (p, NULL); + + if (*p != ']') + return FALSE; + + /* silently accept whitespace after the ] */ + p = g_utf8_find_next_char (p, NULL); + while (*p == ' ' || *p == '\t') + p = g_utf8_find_next_char (p, NULL); + + if (*p) + return FALSE; + + return TRUE; +} + +static gboolean +g_key_file_line_is_key_value_pair (const gchar *line) +{ + gchar *p; + + p = (gchar *) g_utf8_strchr (line, -1, '='); + + if (!p) + return FALSE; + + /* Key must be non-empty + */ + if (*p == line[0]) + return FALSE; + + return TRUE; +} + +static gchar * +g_key_file_parse_value_as_string (GKeyFile *key_file, + const gchar *value, + GSList **pieces, + GError **error) +{ + gchar *string_value, *p, *q0, *q; + + string_value = g_new (gchar, strlen (value) + 1); + + p = (gchar *) value; + q0 = q = string_value; + while (*p) + { + if (*p == '\\') + { + p++; + + switch (*p) + { + case 's': + *q = ' '; + break; + + case 'n': + *q = '\n'; + break; + + case 't': + *q = '\t'; + break; + + case 'r': + *q = '\r'; + break; + + case '\\': + *q = '\\'; + break; + + case '\0': + g_set_error_literal (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains escape character " + "at end of line")); + break; + + default: + if (pieces && *p == key_file->list_separator) + *q = key_file->list_separator; + else + { + *q++ = '\\'; + *q = *p; + + if (*error == NULL) + { + gchar sequence[3]; + + sequence[0] = '\\'; + sequence[1] = *p; + sequence[2] = '\0'; + + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Key file contains invalid escape " + "sequence '%s'"), sequence); + } + } + break; + } + } + else + { + *q = *p; + if (pieces && (*p == key_file->list_separator)) + { + *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0)); + q0 = q + 1; + } + } + + if (*p == '\0') + break; + + q++; + p++; + } + + *q = '\0'; + if (pieces) + { + if (q0 < q) + *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0)); + *pieces = g_slist_reverse (*pieces); + } + + return string_value; +} + +static gchar * +g_key_file_parse_string_as_value (GKeyFile *key_file, + const gchar *string, + gboolean escape_separator) +{ + gchar *value, *p, *q; + gsize length; + gboolean parsing_leading_space; + + length = strlen (string) + 1; + + /* Worst case would be that every character needs to be escaped. + * In other words every character turns to two characters + */ + value = g_new (gchar, 2 * length); + + p = (gchar *) string; + q = value; + parsing_leading_space = TRUE; + while (p < (string + length - 1)) + { + gchar escaped_character[3] = { '\\', 0, 0 }; + + switch (*p) + { + case ' ': + if (parsing_leading_space) + { + escaped_character[1] = 's'; + strcpy (q, escaped_character); + q += 2; + } + else + { + *q = *p; + q++; + } + break; + case '\t': + if (parsing_leading_space) + { + escaped_character[1] = 't'; + strcpy (q, escaped_character); + q += 2; + } + else + { + *q = *p; + q++; + } + break; + case '\n': + escaped_character[1] = 'n'; + strcpy (q, escaped_character); + q += 2; + break; + case '\r': + escaped_character[1] = 'r'; + strcpy (q, escaped_character); + q += 2; + break; + case '\\': + escaped_character[1] = '\\'; + strcpy (q, escaped_character); + q += 2; + parsing_leading_space = FALSE; + break; + default: + if (escape_separator && *p == key_file->list_separator) + { + escaped_character[1] = key_file->list_separator; + strcpy (q, escaped_character); + q += 2; + parsing_leading_space = TRUE; + } + else + { + *q = *p; + q++; + parsing_leading_space = FALSE; + } + break; + } + p++; + } + *q = '\0'; + + return value; +} + +static gint +g_key_file_parse_value_as_integer (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *eof_int; + glong long_value; + gint int_value; + + errno = 0; + long_value = strtol (value, &eof_int, 10); + + if (*value == '\0' || (*eof_int != '\0' && !g_ascii_isspace(*eof_int))) + { + gchar *value_utf8 = _g_utf8_make_valid (value); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value '%s' cannot be interpreted " + "as a number."), value_utf8); + g_free (value_utf8); + + return 0; + } + + int_value = long_value; + if (int_value != long_value || errno == ERANGE) + { + gchar *value_utf8 = _g_utf8_make_valid (value); + g_set_error (error, + G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Integer value '%s' out of range"), + value_utf8); + g_free (value_utf8); + + return 0; + } + + return int_value; +} + +static gchar * +g_key_file_parse_integer_as_value (GKeyFile *key_file, + gint value) + +{ + return g_strdup_printf ("%d", value); +} + +static gdouble +g_key_file_parse_value_as_double (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *end_of_valid_d; + gdouble double_value = 0; + + double_value = g_ascii_strtod (value, &end_of_valid_d); + + if (*end_of_valid_d != '\0' || end_of_valid_d == value) + { + gchar *value_utf8 = _g_utf8_make_valid (value); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value '%s' cannot be interpreted " + "as a float number."), + value_utf8); + g_free (value_utf8); + } + + return double_value; +} + +static gboolean +g_key_file_parse_value_as_boolean (GKeyFile *key_file, + const gchar *value, + GError **error) +{ + gchar *value_utf8; + + if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0) + return TRUE; + else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0) + return FALSE; + + value_utf8 = _g_utf8_make_valid (value); + g_set_error (error, G_KEY_FILE_ERROR, + G_KEY_FILE_ERROR_INVALID_VALUE, + _("Value '%s' cannot be interpreted " + "as a boolean."), value_utf8); + g_free (value_utf8); + + return FALSE; +} + +static gchar * +g_key_file_parse_boolean_as_value (GKeyFile *key_file, + gboolean value) +{ + if (value) + return g_strdup ("true"); + else + return g_strdup ("false"); +} + +static gchar * +g_key_file_parse_value_as_comment (GKeyFile *key_file, + const gchar *value) +{ + GString *string; + gchar **lines; + gsize i; + + string = g_string_sized_new (512); + + lines = g_strsplit (value, "\n", 0); + + for (i = 0; lines[i] != NULL; i++) + { + if (lines[i][0] != '#') + g_string_append_printf (string, "%s\n", lines[i]); + else + g_string_append_printf (string, "%s\n", lines[i] + 1); + } + g_strfreev (lines); + + return g_string_free (string, FALSE); +} + +static gchar * +g_key_file_parse_comment_as_value (GKeyFile *key_file, + const gchar *comment) +{ + GString *string; + gchar **lines; + gsize i; + + string = g_string_sized_new (512); + + lines = g_strsplit (comment, "\n", 0); + + for (i = 0; lines[i] != NULL; i++) + g_string_append_printf (string, "#%s%s", lines[i], + lines[i + 1] == NULL? "" : "\n"); + g_strfreev (lines); + + return g_string_free (string, FALSE); +} diff --git a/glib/glib/gkeyfile.h b/glib/glib/gkeyfile.h new file mode 100644 index 0000000..998bb7a --- /dev/null +++ b/glib/glib/gkeyfile.h @@ -0,0 +1,268 @@ +/* gkeyfile.h - desktop entry file parser + * + * Copyright 2004 Red Hat, Inc. + * + * Ray Strode + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_KEY_FILE_H__ +#define __G_KEY_FILE_H__ + +#include + +G_BEGIN_DECLS + +typedef enum +{ + G_KEY_FILE_ERROR_UNKNOWN_ENCODING, + G_KEY_FILE_ERROR_PARSE, + G_KEY_FILE_ERROR_NOT_FOUND, + G_KEY_FILE_ERROR_KEY_NOT_FOUND, + G_KEY_FILE_ERROR_GROUP_NOT_FOUND, + G_KEY_FILE_ERROR_INVALID_VALUE +} GKeyFileError; + +#define G_KEY_FILE_ERROR g_key_file_error_quark() + +GQuark g_key_file_error_quark (void); + +typedef struct _GKeyFile GKeyFile; + +typedef enum +{ + G_KEY_FILE_NONE = 0, + G_KEY_FILE_KEEP_COMMENTS = 1 << 0, + G_KEY_FILE_KEEP_TRANSLATIONS = 1 << 1 +} GKeyFileFlags; + +GKeyFile *g_key_file_new (void); +GKeyFile *g_key_file_ref (GKeyFile *key_file); +void g_key_file_unref (GKeyFile *key_file); +void g_key_file_free (GKeyFile *key_file); +void g_key_file_set_list_separator (GKeyFile *key_file, + gchar separator); +gboolean g_key_file_load_from_file (GKeyFile *key_file, + const gchar *file, + GKeyFileFlags flags, + GError **error); +gboolean g_key_file_load_from_data (GKeyFile *key_file, + const gchar *data, + gsize length, + GKeyFileFlags flags, + GError **error); +gboolean g_key_file_load_from_dirs (GKeyFile *key_file, + const gchar *file, + const gchar **search_dirs, + gchar **full_path, + GKeyFileFlags flags, + GError **error); +gboolean g_key_file_load_from_data_dirs (GKeyFile *key_file, + const gchar *file, + gchar **full_path, + GKeyFileFlags flags, + GError **error); +gchar *g_key_file_to_data (GKeyFile *key_file, + gsize *length, + GError **error) G_GNUC_MALLOC; +gchar *g_key_file_get_start_group (GKeyFile *key_file) G_GNUC_MALLOC; +gchar **g_key_file_get_groups (GKeyFile *key_file, + gsize *length) G_GNUC_MALLOC; +gchar **g_key_file_get_keys (GKeyFile *key_file, + const gchar *group_name, + gsize *length, + GError **error) G_GNUC_MALLOC; +gboolean g_key_file_has_group (GKeyFile *key_file, + const gchar *group_name); +gboolean g_key_file_has_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +gchar *g_key_file_get_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) G_GNUC_MALLOC; +void g_key_file_set_value (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *value); +gchar *g_key_file_get_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) G_GNUC_MALLOC; +void g_key_file_set_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *string); +gchar *g_key_file_get_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + GError **error) G_GNUC_MALLOC; +void g_key_file_set_locale_string (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar *string); +gboolean g_key_file_get_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +void g_key_file_set_boolean (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean value); +gint g_key_file_get_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +void g_key_file_set_integer (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint value); +gint64 g_key_file_get_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +void g_key_file_set_int64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint64 value); +guint64 g_key_file_get_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +void g_key_file_set_uint64 (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + guint64 value); +gdouble g_key_file_get_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +void g_key_file_set_double (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble value); +gchar **g_key_file_get_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) G_GNUC_MALLOC; +void g_key_file_set_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar * const list[], + gsize length); +gchar **g_key_file_get_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + gsize *length, + GError **error) G_GNUC_MALLOC; +void g_key_file_set_locale_string_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *locale, + const gchar * const list[], + gsize length); +gboolean *g_key_file_get_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) G_GNUC_MALLOC; +void g_key_file_set_boolean_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gboolean list[], + gsize length); +gint *g_key_file_get_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) G_GNUC_MALLOC; +void g_key_file_set_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gdouble list[], + gsize length); +gdouble *g_key_file_get_double_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gsize *length, + GError **error) G_GNUC_MALLOC; +void g_key_file_set_integer_list (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + gint list[], + gsize length); +gboolean g_key_file_set_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + const gchar *comment, + GError **error); +gchar *g_key_file_get_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error) G_GNUC_MALLOC; + +gboolean g_key_file_remove_comment (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +gboolean g_key_file_remove_key (GKeyFile *key_file, + const gchar *group_name, + const gchar *key, + GError **error); +gboolean g_key_file_remove_group (GKeyFile *key_file, + const gchar *group_name, + GError **error); + +/* Defines for handling freedesktop.org Desktop files */ +#define G_KEY_FILE_DESKTOP_GROUP "Desktop Entry" + +#define G_KEY_FILE_DESKTOP_KEY_TYPE "Type" +#define G_KEY_FILE_DESKTOP_KEY_VERSION "Version" +#define G_KEY_FILE_DESKTOP_KEY_NAME "Name" +#define G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME "GenericName" +#define G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY "NoDisplay" +#define G_KEY_FILE_DESKTOP_KEY_COMMENT "Comment" +#define G_KEY_FILE_DESKTOP_KEY_ICON "Icon" +#define G_KEY_FILE_DESKTOP_KEY_HIDDEN "Hidden" +#define G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN "OnlyShowIn" +#define G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN "NotShowIn" +#define G_KEY_FILE_DESKTOP_KEY_TRY_EXEC "TryExec" +#define G_KEY_FILE_DESKTOP_KEY_EXEC "Exec" +#define G_KEY_FILE_DESKTOP_KEY_PATH "Path" +#define G_KEY_FILE_DESKTOP_KEY_TERMINAL "Terminal" +#define G_KEY_FILE_DESKTOP_KEY_MIME_TYPE "MimeType" +#define G_KEY_FILE_DESKTOP_KEY_CATEGORIES "Categories" +#define G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY "StartupNotify" +#define G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS "StartupWMClass" +#define G_KEY_FILE_DESKTOP_KEY_URL "URL" + +#define G_KEY_FILE_DESKTOP_TYPE_APPLICATION "Application" +#define G_KEY_FILE_DESKTOP_TYPE_LINK "Link" +#define G_KEY_FILE_DESKTOP_TYPE_DIRECTORY "Directory" + +G_END_DECLS + +#endif /* __G_KEY_FILE_H__ */ diff --git a/glib/glib/glib-init.c b/glib/glib/glib-init.c new file mode 100644 index 0000000..f4edd5c --- /dev/null +++ b/glib/glib/glib-init.c @@ -0,0 +1,269 @@ +/* + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "glib-init.h" + +#include "gutils.h" /* for GDebugKey */ +#include "gconstructor.h" + +#include +#include +#include +#include + +/** + * g_mem_gc_friendly: + * + * This variable is %TRUE if the G_DEBUG environment variable + * includes the key gc-friendly. + */ +#ifdef ENABLE_GC_FRIENDLY_DEFAULT +gboolean g_mem_gc_friendly = TRUE; +#else +gboolean g_mem_gc_friendly = FALSE; +#endif +GLogLevelFlags g_log_msg_prefix = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING | + G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG; +GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK; + +static gboolean +debug_key_matches (const gchar *key, + const gchar *token, + guint length) +{ + /* may not call GLib functions: see note in g_parse_debug_string() */ + for (; length; length--, key++, token++) + { + char k = (*key == '_') ? '-' : tolower (*key ); + char t = (*token == '_') ? '-' : tolower (*token); + + if (k != t) + return FALSE; + } + + return *key == '\0'; +} + +/** + * g_parse_debug_string: + * @string: (allow-none): a list of debug options separated by colons, spaces, or + * commas, or %NULL. + * @keys: (array length=nkeys): pointer to an array of #GDebugKey which associate + * strings with bit flags. + * @nkeys: the number of #GDebugKeys in the array. + * + * Parses a string containing debugging options + * into a %guint containing bit flags. This is used + * within GDK and GTK+ to parse the debug options passed on the + * command line or through environment variables. + * + * If @string is equal to "all", all flags are set. Any flags + * specified along with "all" in @string are inverted; thus, + * "all,foo,bar" or "foo,bar,all" sets all flags + * except those corresponding to "foo" and "bar". + * + * If @string is equal to "help", all the available keys in @keys + * are printed out to standard error. + * + * Returns: the combined set of bit flags. + */ +guint +g_parse_debug_string (const gchar *string, + const GDebugKey *keys, + guint nkeys) +{ + guint i; + guint result = 0; + + if (string == NULL) + return 0; + + /* this function is used during the initialisation of gmessages, gmem + * and gslice, so it may not do anything that causes memory to be + * allocated or risks messages being emitted. + * + * this means, more or less, that this code may not call anything + * inside GLib. + */ + + if (!strcasecmp (string, "help")) + { + /* using stdio directly for the reason stated above */ + fprintf (stderr, "Supported debug values:"); + for (i = 0; i < nkeys; i++) + fprintf (stderr, " %s", keys[i].key); + fprintf (stderr, " all help\n"); + } + else + { + const gchar *p = string; + const gchar *q; + gboolean invert = FALSE; + + while (*p) + { + q = strpbrk (p, ":;, \t"); + if (!q) + q = p + strlen (p); + + if (debug_key_matches ("all", p, q - p)) + { + invert = TRUE; + } + else + { + for (i = 0; i < nkeys; i++) + if (debug_key_matches (keys[i].key, p, q - p)) + result |= keys[i].value; + } + + p = q; + if (*p) + p++; + } + + if (invert) + { + guint all_flags = 0; + + for (i = 0; i < nkeys; i++) + all_flags |= keys[i].value; + + result = all_flags & (~result); + } + } + + return result; +} + +static guint +g_parse_debug_envvar (const gchar *envvar, + const GDebugKey *keys, + gint n_keys, + guint default_value) +{ + const gchar *value; + +#ifdef OS_WIN32 + /* "fatal-warnings,fatal-criticals,all,help" is pretty short */ + gchar buffer[100]; + + if (GetEnvironmentVariable (envvar, buffer, 100) < 100) + value = buffer; + else + return 0; +#else + value = getenv (envvar); +#endif + + if (value == NULL) + return default_value; + + return g_parse_debug_string (value, keys, n_keys); +} + +static void +g_messages_prefixed_init (void) +{ + const GDebugKey keys[] = { + { "error", G_LOG_LEVEL_ERROR }, + { "critical", G_LOG_LEVEL_CRITICAL }, + { "warning", G_LOG_LEVEL_WARNING }, + { "message", G_LOG_LEVEL_MESSAGE }, + { "info", G_LOG_LEVEL_INFO }, + { "debug", G_LOG_LEVEL_DEBUG } + }; + + g_log_msg_prefix = g_parse_debug_envvar ("G_MESSAGES_PREFIXED", keys, G_N_ELEMENTS (keys), g_log_msg_prefix); +} + +static void +g_debug_init (void) +{ + const GDebugKey keys[] = { + { "gc-friendly", 1 }, + {"fatal-warnings", G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL }, + {"fatal-criticals", G_LOG_LEVEL_CRITICAL } + }; + GLogLevelFlags flags; + + flags = g_parse_debug_envvar ("G_DEBUG", keys, G_N_ELEMENTS (keys), 0); + + g_log_always_fatal |= flags & G_LOG_LEVEL_MASK; + + g_mem_gc_friendly = flags & 1; +} + +static void +glib_init (void) +{ + g_messages_prefixed_init (); + g_debug_init (); +} + +#if defined (G_OS_WIN32) + +HMODULE glib_dll; + +BOOL WINAPI +DllMain (HINSTANCE hinstDLL, + DWORD fdwReason, + LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + glib_dll = hinstDLL; + g_clock_win32_init (); + g_thread_win32_init (); + glib_init (); + break; + + case DLL_THREAD_DETACH: + g_thread_win32_thread_detach (); + break; + + default: + /* do nothing */ + ; + } + + return TRUE; +} + +#elif defined (G_HAS_CONSTRUCTORS) + +#ifdef G_DEFINE_CONSTRUCTOR_NEEDS_PRAGMA +#pragma G_DEFINE_CONSTRUCTOR_PRAGMA_ARGS(glib_init_ctor) +#endif +G_DEFINE_CONSTRUCTOR(glib_init_ctor) + +static void +glib_init_ctor (void) +{ + glib_init (); +} + +#else +# error Your platform/compiler is missing constructor support +#endif diff --git a/glib/glib/glib-init.h b/glib/glib/glib-init.h new file mode 100644 index 0000000..bf1ecd0 --- /dev/null +++ b/glib/glib/glib-init.h @@ -0,0 +1,40 @@ +/* + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * Author: Ryan Lortie + */ + +#ifndef __GLIB_INIT_H__ +#define __GLIB_INIT_H__ + +#include "gmessages.h" + +G_GNUC_INTERNAL extern GLogLevelFlags g_log_always_fatal; +G_GNUC_INTERNAL extern GLogLevelFlags g_log_msg_prefix; +GLIB_VAR gboolean g_mem_gc_friendly; + +#ifdef G_OS_WIN32 +#include + +G_GNUC_INTERNAL void g_thread_win32_thread_detach (void); +G_GNUC_INTERNAL void g_thread_win32_init (void); +G_GNUC_INTERNAL void g_clock_win32_init (void); +G_GNUC_INTERNAL extern HMODULE glib_dll; +#endif + +#endif /* __GLIB_INIT_H__ */ diff --git a/glib/glib/glib-mirroring-tab/Makefile b/glib/glib/glib-mirroring-tab/Makefile new file mode 100644 index 0000000..8ab193c --- /dev/null +++ b/glib/glib/glib-mirroring-tab/Makefile @@ -0,0 +1,11 @@ + +CFLAGS = `pkg-config --cflags glib-2.0` +LIBS = `pkg-config --libs glib-2.0` + + +all: gen-mirroring-tab + +gen-mirroring-tab: gen-mirroring-tab.o packtab.o + +clean: + $(RM) gen-mirroring-tab *.o diff --git a/glib/glib/glib-mirroring-tab/gen-mirroring-tab.c b/glib/glib/glib-mirroring-tab/gen-mirroring-tab.c new file mode 100644 index 0000000..6b16376 --- /dev/null +++ b/glib/glib/glib-mirroring-tab/gen-mirroring-tab.c @@ -0,0 +1,232 @@ +/* gen-mirroring-tab.c - generate gmirroringtable.h for glib + * copied from FriBidi. + * + * $Id$ + * $Author$ + * $Date$ + * $Revision$ + * $Source$ + * + * Author: + * Behdad Esfahbod, 2001, 2002, 2004 + * + * Copyright (C) 2004 Sharif FarsiWeb, Inc + * Copyright (C) 2001,2002,2004 Behdad Esfahbod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library, in a file named COPYING; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA + * + * For licensing issues, contact . + */ + +#include + +#include +#include + +#include "packtab.h" + +#define appname "gen-mirroring-tab" +#define outputname "gmirroringtable.h" + +static void +die ( + const char *msg +) +{ + fprintf (stderr, appname ": %s\n", msg); + exit (1); +} + +static void +die2 ( + const char *fmt, + const char *p +) +{ + fprintf (stderr, appname ": "); + fprintf (stderr, fmt, p); + fprintf (stderr, "\n"); + exit (1); +} + +static void +die4 ( + const char *fmt, + unsigned long l, + unsigned long p, + unsigned long q +) +{ + fprintf (stderr, appname ": "); + fprintf (stderr, fmt, l, p, q); + fprintf (stderr, "\n"); + exit (1); +} + +#define table_name "Mir" +#define macro_name "GLIB_GET_MIRRORING" + +#define UNICODE_CHARS 0x110000 + +static signed int table[UNICODE_CHARS]; +static char buf[4000]; +static signed long max_dist; + +static void +init ( + void +) +{ + max_dist = 0; +} + +static void +clear_tab ( + void +) +{ + register gunichar c; + + for (c = 0; c < UNICODE_CHARS; c++) + table[c] = 0; +} + +static void +init_tab_mirroring_txt ( + void +) +{ + clear_tab (); +} + +static void +read_bidi_mirroring_txt ( + FILE *f +) +{ + unsigned long l; + + init_tab_mirroring_txt (); + + l = 0; + while (fgets (buf, sizeof buf, f)) + { + unsigned long i, j; + signed long dist; + int k; + const char *s = buf; + + l++; + + while (*s == ' ') + s++; + + if (s[0] == '#' || s[0] == '\0' || s[0] == '\n') + continue; + + k = sscanf (s, "%lx; %lx", &i, &j); + if (k != 2 || i >= UNICODE_CHARS || j >= UNICODE_CHARS) + die4 ("invalid pair in input at line %ld: %04lX, %04lX", l, i, j); + dist = ((signed long) j - (signed long) i); + table[i] = dist; + if (dist > max_dist) + max_dist = dist; + else if (-dist > max_dist) + max_dist = -dist; + } +} + +static void +read_data ( + const char *data_file_type, + const char *data_file_name +) +{ + FILE *f; + + fprintf (stderr, "Reading `%s'\n", data_file_name); + if (!(f = fopen (data_file_name, "rt"))) + die2 ("error: cannot open `%s' for reading", data_file_name); + + if (!strcmp (data_file_type, "BidiMirroring.txt")) + read_bidi_mirroring_txt (f); + else + die2 ("error: unknown data-file-type %s", data_file_type); + + fclose (f); +} + +static void +gen_mirroring_tab ( + int max_depth, + const char *data_file_type +) +{ + int key_bytes; + const char *key_type; + + fprintf (stderr, + "Generating `" outputname "', it may take up to a few minutes\n"); + printf ("/* " outputname "\n * generated by " appname " " + "\n" " * from the file %s of */\n\n", data_file_type); + + printf ("#define PACKTAB_UINT8 guint8\n" + "#define PACKTAB_UINT16 guint16\n" + "#define PACKTAB_UINT32 guint32\n\n"); + + key_bytes = max_dist <= 0x7f ? 1 : max_dist < 0x7fff ? 2 : 4; + key_type = key_bytes == 1 ? "gint8" : key_bytes == 2 ? + "gint16" : "gint32"; + + if (!pack_table + (table, UNICODE_CHARS, key_bytes, 0, max_depth, 1, NULL, + key_type, table_name, macro_name "_DELTA", stdout)) + die ("error: insufficient memory, decrease max_depth"); + + printf ("#undef PACKTAB_UINT8\n" + "#undef PACKTAB_UINT16\n" "#undef PACKTAB_UINT32\n\n"); + + printf ("#define " macro_name "(x) ((x) + " macro_name "_DELTA(x))\n\n"); + + printf ("/* End of generated " outputname " */\n"); +} + +int +main ( + int argc, + const char **argv +) +{ + const char *data_file_type = "BidiMirroring.txt"; + + if (argc < 3) + die2 ("usage:\n " appname " max-lookups /path/to/%s [junk...]", + data_file_type); + + { + int max_depth = atoi (argv[1]); + const char *data_file_name = argv[2]; + + if (max_depth < 2) + die ("invalid depth"); + + init (); + read_data (data_file_type, data_file_name); + gen_mirroring_tab (max_depth, data_file_type); + } + + return 0; +} diff --git a/glib/glib/glib-mirroring-tab/packtab.c b/glib/glib/glib-mirroring-tab/packtab.c new file mode 100644 index 0000000..7c0ff5d --- /dev/null +++ b/glib/glib/glib-mirroring-tab/packtab.c @@ -0,0 +1,424 @@ +/* PackTab - Pack a static table + * Copyright (C) 2001 Behdad Esfahbod. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library, in a file named COPYING; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA + * + * For licensing issues, contact . + */ + +/* + 8 <= N <= 2^21 + int key + 1 <= max_depth <= 21 +*/ + +#include +#include +#include + +#include "packtab.h" + +typedef signed int uni_table[1024 * 1024 * 2]; +static int n, a, max_depth, digits, tab_width, per_row; +static long N; +signed int def_key; +static uni_table temp, x, perm, *tab; +static long pow[22], cluster, cmpcluster; +static const char *const *name, *key_type_name, *table_name, *macro_name; +static FILE *f; + +static long +most_binary ( + long min, + long max +) +{ + /* min should be less than max */ + register int i, ii; + + if (min == max) + return max; + + for (i = 21; max < pow[i]; i--) + ; + ii = i; + while (i && !((min ^ max) & pow[i])) + i--; + + if (ii == i) + { + /* min is less than half of max */ + for (i = 21 - 1; min < pow[i]; i--) + ; + i++; + return pow[i]; + } + + return max & (pow[i] - 1); +} + +static void +init ( + const signed int *table +) +{ + register int i; + + /* initialize powers of two */ + pow[0] = 1; + for (i = 1; i <= 21; i++) + pow[i] = pow[i - 1] << 1; + + /* reduce number of elements to get a more binary number */ + { + long essen; + + /* find number of essential items */ + essen = N - 1; + while (essen && table[essen] == def_key) + essen--; + essen++; + + N = most_binary (essen, N); + } + + for (n = 21; N % pow[n]; n--) + ; + digits = (n + 3) / 4; + for (i = 6; i; i--) + if (pow[i] * (tab_width + 1) < 80) + break; + per_row = pow[i]; +} + +static int +compare ( + const void *r, + const void *s +) +{ + int i; + for (i = 0; i < cmpcluster; i++) + if (((int *) r)[i] != ((int *) s)[i]) + return ((int *) r)[i] - ((int *) s)[i]; + return 0; +} + +static int lev, best_lev, p[22], best_p[22], nn; +static long c[22], best_c[22], s, best_s; +static long t[22], best_t[22], clusters[22], best_cluster[22]; + +static void +found ( + void +) +{ + int i; + + if (s < best_s) + { + best_s = s; + best_lev = lev; + for (i = 0; i <= lev; i++) + { + best_p[i] = p[i]; + best_c[i] = c[i]; + best_t[i] = t[i]; + best_cluster[i] = clusters[i]; + } + } +} + +static void +bt ( + int node_size +) +{ + long i, j, k, y, sbak; + long key_bytes; + + if (t[lev] == 1) + { + found (); + return; + } + if (lev == max_depth) + return; + + for (i = 1 - t[lev] % 2; i <= nn + (t[lev] >> nn) % 2; i++) + { + nn -= (p[lev] = i); + clusters[lev] = cluster = (i && nn >= 0) ? pow[i] : t[lev]; + cmpcluster = cluster + 1; + + t[lev + 1] = (t[lev] - 1) / cluster + 1; + for (j = 0; j < t[lev + 1]; j++) + { + memmove (temp + j * cmpcluster, tab[lev] + j * cluster, + cluster * sizeof (tab[lev][0])); + temp[j * cmpcluster + cluster] = j; + } + qsort (temp, t[lev + 1], cmpcluster * sizeof (temp[0]), compare); + for (j = 0; j < t[lev + 1]; j++) + { + perm[j] = temp[j * cmpcluster + cluster]; + temp[j * cmpcluster + cluster] = 0; + } + k = 1; + y = 0; + tab[lev + 1][perm[0]] = perm[0]; + for (j = 1; j < t[lev + 1]; j++) + { + if (compare (temp + y, temp + y + cmpcluster)) + { + k++; + tab[lev + 1][perm[j]] = perm[j]; + } + else + tab[lev + 1][perm[j]] = tab[lev + 1][perm[j - 1]]; + y += cmpcluster; + } + sbak = s; + s += k * node_size * cluster; + c[lev] = k; + + if (s >= best_s) + { + s = sbak; + nn += i; + return; + } + + key_bytes = k * cluster; + key_bytes = key_bytes < 0xff ? 1 : key_bytes < 0xffff ? 2 : 4; + lev++; + bt (key_bytes); + lev--; + + s = sbak; + nn += i; + } +} + +static void +solve ( + void +) +{ + best_lev = max_depth + 2; + best_s = N * a * 2; + lev = 0; + s = 0; + nn = n; + t[0] = N; + bt (a); +} + +static void +write_array ( + long max_key +) +{ + int i, j, k, y, ii, ofs; + const char *key_type; + + if (best_t[lev] == 1) + return; + + nn -= (i = best_p[lev]); + cluster = best_cluster[lev]; + cmpcluster = cluster + 1; + + t[lev + 1] = best_t[lev + 1]; + for (j = 0; j < t[lev + 1]; j++) + { + memmove (temp + j * cmpcluster, tab[lev] + j * cluster, + cluster * sizeof (tab[lev][0])); + temp[j * cmpcluster + cluster] = j; + } + qsort (temp, t[lev + 1], cmpcluster * sizeof (temp[0]), compare); + for (j = 0; j < t[lev + 1]; j++) + { + perm[j] = temp[j * cmpcluster + cluster]; + temp[j * cmpcluster + cluster] = 0; + } + k = 1; + y = 0; + tab[lev + 1][perm[0]] = x[0] = perm[0]; + for (j = 1; j < t[lev + 1]; j++) + { + if (compare (temp + y, temp + y + cmpcluster)) + { + x[k] = perm[j]; + tab[lev + 1][perm[j]] = x[k]; + k++; + } + else + tab[lev + 1][perm[j]] = tab[lev + 1][perm[j - 1]]; + y += cmpcluster; + } + + i = 0; + for (ii = 1; ii < k; ii++) + if (x[ii] < x[i]) + i = ii; + + key_type = !lev ? key_type_name : + max_key <= 0xff ? "PACKTAB_UINT8" : + max_key <= 0xffff ? "PACKTAB_UINT16" : "PACKTAB_UINT32"; + fprintf (f, "static const %s %sLev%d[%ld*%d] = {", key_type, table_name, + best_lev - lev - 1, cluster, k); + ofs = 0; + for (ii = 0; ii < k; ii++) + { + int kk, jj; + fprintf (f, "\n#define %sLev%d_%0*lX 0x%0X", table_name, + best_lev - lev - 1, digits, x[i] * pow[n - nn], ofs); + kk = x[i] * cluster; + if (!lev) + if (name) + for (j = 0; j < cluster; j++) + { + if (!(j % per_row) && j != cluster - 1) + fprintf (f, "\n "); + fprintf (f, "%*s,", tab_width, name[tab[lev][kk++]]); + } + else + for (j = 0; j < cluster; j++) + { + if (!(j % per_row) && j != cluster - 1) + fprintf (f, "\n "); + fprintf (f, "%*d,", tab_width, tab[lev][kk++]); + } + else + for (j = 0; j < cluster; j++, kk++) + fprintf (f, "\n %sLev%d_%0*lX, /* %0*lX..%0*lX */", table_name, + best_lev - lev, digits, + tab[lev][kk] * pow[n - nn - best_p[lev]], digits, + x[i] * pow[n - nn] + j * pow[n - nn - best_p[lev]], digits, + x[i] * pow[n - nn] + (j + 1) * pow[n - nn - best_p[lev]] - + 1); + ofs += cluster; + jj = i; + for (j = 0; j < k; j++) + if (x[j] > x[i] && (x[j] < x[jj] || jj == i)) + jj = j; + i = jj; + } + fprintf (f, "\n};\n\n"); + lev++; + write_array (cluster * k); + lev--; +} + +static void +write_source ( + void +) +{ + int i, j; + + lev = 0; + s = 0; + nn = n; + t[0] = N; + fprintf (f, "\n" "/* *IND" "ENT-OFF* */\n\n"); + write_array (0); + fprintf (f, "/* *IND" "ENT-ON* */\n\n"); + + fprintf (f, "#define %s(x) \\\n", macro_name); + fprintf (f, "\t((x) >= 0x%lx ? ", N); + if (name) + fprintf (f, "%s", name[def_key]); + else + fprintf (f, "%d", def_key); + fprintf (f, " : "); + j = 0; + for (i = best_lev - 1; i >= 0; i--) + { + fprintf (f, " \\\n\t%sLev%d[((x)", table_name, i); + if (j != 0) + fprintf (f, " >> %d", j); + if (i) + fprintf (f, " & 0x%02lx) +", pow[best_p[best_lev - 1 - i]] - 1); + j += best_p[best_lev - 1 - i]; + } + fprintf (f, ")"); + for (i = 0; i < best_lev; i++) + fprintf (f, "]"); + fprintf (f, ")\n\n"); +} + +static void +write_out ( + void +) +{ + int i; + fprintf (f, "/*\n" + " generated by packtab.c version %d\n\n" + " use %s(key) to access your table\n\n" + " assumed sizeof(%s): %d\n" + " required memory: %ld\n" + " lookups: %d\n" + " partition shape: %s", + packtab_version, macro_name, key_type_name, a, best_s, best_lev, + table_name); + for (i = best_lev - 1; i >= 0; i--) + fprintf (f, "[%ld]", best_cluster[i]); + fprintf (f, "\n" " different table entries:"); + for (i = best_lev - 1; i >= 0; i--) + fprintf (f, " %ld", best_c[i]); + fprintf (f, "\n*/\n"); + write_source (); +} + +int +pack_table ( + const signed int *base, + long key_num, + int key_size, + signed int default_key, + int p_max_depth, + int p_tab_width, + const char *const *p_name, + const char *p_key_type_name, + const char *p_table_name, + const char *p_macro_name, + FILE *out +) +{ + N = key_num; + a = key_size; + def_key = default_key; + max_depth = p_max_depth; + tab_width = p_tab_width; + name = p_name; + key_type_name = p_key_type_name; + table_name = p_table_name; + macro_name = p_macro_name; + f = out; + init (base); + if (!(tab = malloc ((n + 1) * sizeof (tab[0])))) + return 0; + memmove (tab[0], base, N * sizeof (base[0])); + solve (); + write_out (); + free (tab); + return 1; +} + +/* End of packtab.c */ diff --git a/glib/glib/glib-mirroring-tab/packtab.h b/glib/glib/glib-mirroring-tab/packtab.h new file mode 100644 index 0000000..7cab9be --- /dev/null +++ b/glib/glib/glib-mirroring-tab/packtab.h @@ -0,0 +1,50 @@ +/* PackTab - Pack a static table + * Copyright (C) 2001 Behdad Esfahbod. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library, in a file named COPYING; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA + * + * For licensing issues, contact . + */ + +#ifndef PACKTAB_H +#define PACKTAB_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define packtab_version 3 + + int pack_table ( + const signed int *base, + long key_num, + int key_size, + signed int default_key, + int max_depth, + int tab_width, + const char *const *name, + const char *key_type_name, + const char *table_name, + const char *macro_name, + FILE *out + ); + +#ifdef __cplusplus +} +#endif + +#endif /* PACKTAB_H */ diff --git a/glib/glib/glib-object.h b/glib/glib/glib-object.h new file mode 100644 index 0000000..336ba93 --- /dev/null +++ b/glib/glib/glib-object.h @@ -0,0 +1,42 @@ +/* GObject - GLib Type, Object, Parameter and Signal Library + * Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + */ +#ifndef __GLIB_GOBJECT_H__ +#define __GLIB_GOBJECT_H__ + +#define __GLIB_GOBJECT_H_INSIDE__ + +/* topmost include file for GObject header files */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef __GLIB_GOBJECT_H_INSIDE__ + +#endif /* __GLIB_GOBJECT_H__ */ diff --git a/glib/glib/glib-private.c b/glib/glib/glib-private.c new file mode 100644 index 0000000..3946e77 --- /dev/null +++ b/glib/glib/glib-private.c @@ -0,0 +1,46 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Colin Walters + */ + +#include "glib-private.h" + +/** + * glib__private__: + * @arg: Do not use this argument + * + * Do not call this function; it is used to share private + * API between glib, gobject, and gio. + */ +GLibPrivateVTable * +glib__private__ (void) +{ + static GLibPrivateVTable table = { + g_wakeup_new, + g_wakeup_free, + g_wakeup_get_pollfd, + g_wakeup_signal, + g_wakeup_acknowledge, + + g_get_worker_context + }; + + return &table; +} + diff --git a/glib/glib/glib-private.h b/glib/glib/glib-private.h new file mode 100644 index 0000000..fde0be8 --- /dev/null +++ b/glib/glib/glib-private.h @@ -0,0 +1,47 @@ +/* glib-private.h - GLib-internal private API, shared between glib, gobject, gio + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __GLIB_PRIVATE_H__ +#define __GLIB_PRIVATE_H__ + +#include +#include "gwakeup.h" + +G_GNUC_INTERNAL +GMainContext * g_get_worker_context (void); + +#define GLIB_PRIVATE_CALL(symbol) (glib__private__()->symbol) + +typedef struct { + /* See gwakeup.c */ + GWakeup * (* g_wakeup_new) (void); + void (* g_wakeup_free) (GWakeup *wakeup); + void (* g_wakeup_get_pollfd) (GWakeup *wakeup, + GPollFD *poll_fd); + void (* g_wakeup_signal) (GWakeup *wakeup); + void (* g_wakeup_acknowledge) (GWakeup *wakeup); + + /* See gmain.c */ + GMainContext * (* g_get_worker_context) (void); + /* Add other private functions here, initialize them in glib-private.c */ +} GLibPrivateVTable; + +GLibPrivateVTable *glib__private__ (void); + +#endif /* __G_MAIN_H__ */ diff --git a/glib/glib/glib-unix.c b/glib/glib/glib-unix.c new file mode 100644 index 0000000..b26609a --- /dev/null +++ b/glib/glib/glib-unix.c @@ -0,0 +1,280 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2011 Red Hat, Inc. + * + * glib-unix.c: UNIX specific API wrappers and convenience functions + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Authors: Colin Walters + */ + +#include "config.h" + +#include "glib-unix.h" +#include "gmain-internal.h" + +#include + +/** + * SECTION:gunix + * @title: UNIX-specific utilities and integration + * @short_description: pipes, signal handling + * @include: glib-unix.h + * + * Most of GLib is intended to be portable; in contrast, this set of + * functions is designed for programs which explicitly target UNIX, + * or are using it to build higher level abstractions which would be + * conditionally compiled if the platform matches G_OS_UNIX. + * + * To use these functions, you must explicitly include the + * "glib-unix.h" header. + */ + +GQuark +g_unix_error_quark (void) +{ + return g_quark_from_static_string ("g-unix-error-quark"); +} + +static gboolean +g_unix_set_error_from_errno (GError **error, + gint saved_errno) +{ + g_set_error_literal (error, + G_UNIX_ERROR, + 0, + g_strerror (saved_errno)); + errno = saved_errno; + return FALSE; +} + +/** + * g_unix_open_pipe: + * @fds: Array of two integers + * @flags: Bitfield of file descriptor flags, see "man 2 fcntl" + * @error: a #GError + * + * Similar to the UNIX pipe() call, but on modern systems like Linux + * uses the pipe2() system call, which atomically creates a pipe with + * the configured flags. The only supported flag currently is + * FD_CLOEXEC. If for example you want to configure + * O_NONBLOCK, that must still be done separately with + * fcntl(). + * + * This function does *not* take O_CLOEXEC, it takes + * FD_CLOEXEC as if for fcntl(); these are + * different on Linux/glibc. + * + * Returns: %TRUE on success, %FALSE if not (and errno will be set). + * + * Since: 2.30 + */ +gboolean +g_unix_open_pipe (int *fds, + int flags, + GError **error) +{ + int ecode; + + /* We only support FD_CLOEXEC */ + g_return_val_if_fail ((flags & (FD_CLOEXEC)) == flags, FALSE); + +#ifdef HAVE_PIPE2 + { + int pipe2_flags = 0; + if (flags & FD_CLOEXEC) + pipe2_flags |= O_CLOEXEC; + /* Atomic */ + ecode = pipe2 (fds, pipe2_flags); + if (ecode == -1 && errno != ENOSYS) + return g_unix_set_error_from_errno (error, errno); + else if (ecode == 0) + return TRUE; + /* Fall through on -ENOSYS, we must be running on an old kernel */ + } +#endif + ecode = pipe (fds); + if (ecode == -1) + return g_unix_set_error_from_errno (error, errno); + ecode = fcntl (fds[0], flags); + if (ecode == -1) + { + int saved_errno = errno; + close (fds[0]); + close (fds[1]); + return g_unix_set_error_from_errno (error, saved_errno); + } + ecode = fcntl (fds[1], flags); + if (ecode == -1) + { + int saved_errno = errno; + close (fds[0]); + close (fds[1]); + return g_unix_set_error_from_errno (error, saved_errno); + } + return TRUE; +} + +/** + * g_unix_set_fd_nonblocking: + * @fd: A file descriptor + * @nonblock: If %TRUE, set the descriptor to be non-blocking + * @error: a #GError + * + * Control the non-blocking state of the given file descriptor, + * according to @nonblock. On most systems this uses O_NONBLOCK, but + * on some older ones may use O_NDELAY. + * + * Returns: %TRUE if successful + * + * Since: 2.30 + */ +gboolean +g_unix_set_fd_nonblocking (gint fd, + gboolean nonblock, + GError **error) +{ +#ifdef F_GETFL + glong fcntl_flags; + fcntl_flags = fcntl (fd, F_GETFL); + + if (fcntl_flags == -1) + return g_unix_set_error_from_errno (error, errno); + + if (nonblock) + { +#ifdef O_NONBLOCK + fcntl_flags |= O_NONBLOCK; +#else + fcntl_flags |= O_NDELAY; +#endif + } + else + { +#ifdef O_NONBLOCK + fcntl_flags &= ~O_NONBLOCK; +#else + fcntl_flags &= ~O_NDELAY; +#endif + } + + if (fcntl (fd, F_SETFL, fcntl_flags) == -1) + return g_unix_set_error_from_errno (error, errno); + return TRUE; +#else + return g_unix_set_error_from_errno (error, EINVAL); +#endif +} + + +/** + * g_unix_signal_source_new: + * @signum: A signal number + * + * Create a #GSource that will be dispatched upon delivery of the UNIX + * signal @signum. Currently only SIGHUP, + * SIGINT, and SIGTERM can + * be monitored. Note that unlike the UNIX default, all sources which + * have created a watch will be dispatched, regardless of which + * underlying thread invoked g_unix_signal_source_new(). + * + * For example, an effective use of this function is to handle SIGTERM + * cleanly; flushing any outstanding files, and then calling + * g_main_loop_quit (). It is not safe to do any of this a regular + * UNIX signal handler; your handler may be invoked while malloc() or + * another library function is running, causing reentrancy if you + * attempt to use it from the handler. None of the GLib/GObject API + * is safe against this kind of reentrancy. + * + * The interaction of this source when combined with native UNIX + * functions like sigprocmask() is not defined. + * + * The source will not initially be associated with any #GMainContext + * and must be added to one with g_source_attach() before it will be + * executed. + * + * Returns: A newly created #GSource + * + * Since: 2.30 + */ +GSource * +g_unix_signal_source_new (int signum) +{ + g_return_val_if_fail (signum == SIGHUP || signum == SIGINT || signum == SIGTERM, NULL); + + return _g_main_create_unix_signal_watch (signum); +} + +/** + * g_unix_signal_add_full: + * @priority: the priority of the signal source. Typically this will be in + * the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH. + * @signum: Signal number + * @handler: Callback + * @user_data: Data for @handler + * @notify: #GDestroyNotify for @handler + * + * A convenience function for g_unix_signal_source_new(), which + * attaches to the default #GMainContext. You can remove the watch + * using g_source_remove(). + * + * Returns: An ID (greater than 0) for the event source + * + * Since: 2.30 + */ +guint +g_unix_signal_add_full (int priority, + int signum, + GSourceFunc handler, + gpointer user_data, + GDestroyNotify notify) +{ + guint id; + GSource *source; + + source = g_unix_signal_source_new (signum); + + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority (source, priority); + + g_source_set_callback (source, handler, user_data, notify); + id = g_source_attach (source, NULL); + g_source_unref (source); + + return id; +} + +/** + * g_unix_signal_add: + * @signum: Signal number + * @handler: Callback + * @user_data: Data for @handler + * + * A convenience function for g_unix_signal_source_new(), which + * attaches to the default #GMainContext. You can remove the watch + * using g_source_remove(). + * + * Returns: An ID (greater than 0) for the event source + * + * Since: 2.30 + */ +guint +g_unix_signal_add (int signum, + GSourceFunc handler, + gpointer user_data) +{ + return g_unix_signal_add_full (G_PRIORITY_DEFAULT, signum, handler, user_data, NULL); +} diff --git a/glib/glib/glib-unix.h b/glib/glib/glib-unix.h new file mode 100644 index 0000000..0b3bec1 --- /dev/null +++ b/glib/glib/glib-unix.h @@ -0,0 +1,84 @@ +/* glib-unix.h - Unix specific integration + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_UNIX_H__ +#define __G_UNIX_H__ + +/* We need to include the UNIX headers needed to use the APIs below, + * but we also take this opportunity to include a wide selection of + * other UNIX headers. If one of the headers below is broken on some + * system, work around it here (or better, fix the system or tell + * people to use a better one). + */ +#include +#include +#include +#include +#include + +#include + +#ifndef G_OS_UNIX +#error "This header may only be used on UNIX" +#endif + +G_BEGIN_DECLS + +/** + * G_UNIX_ERROR: + * + * Error domain for API in the "g_unix_" namespace. Note that there is + * no exported enumeration mapping %errno. Instead, all functions + * ensure that %errno is relevant. The code for all #G_UNIX_ERROR is + * always 0, and the error message is always + * generated via g_strerror(). + * + * It is expected that most code will not look at %errno from these + * APIs. Important cases where one would want to differentiate between + * errors are already covered by existing cross-platform GLib API, + * such as e.g. #GFile wrapping ENOENT. However, it is + * provided for completeness, at least. + */ +#define G_UNIX_ERROR (g_unix_error_quark()) + +GQuark g_unix_error_quark (void); + +gboolean g_unix_open_pipe (gint *fds, + gint flags, + GError **error); + +gboolean g_unix_set_fd_nonblocking (gint fd, + gboolean nonblock, + GError **error); + +GSource *g_unix_signal_source_new (gint signum); + +guint g_unix_signal_add_full (gint priority, + gint signum, + GSourceFunc handler, + gpointer user_data, + GDestroyNotify notify); + +guint g_unix_signal_add (gint signum, + GSourceFunc handler, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_UNIX_H__ */ diff --git a/glib/glib/glib.h b/glib/glib/glib.h new file mode 100644 index 0000000..77abf23 --- /dev/null +++ b/glib/glib/glib.h @@ -0,0 +1,112 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_LIB_H__ +#define __G_LIB_H__ + +#define __GLIB_H_INSIDE__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef G_PLATFORM_WIN32 +#include +#endif + +#include +#include +#include +#include +#include +#include + +#undef __GLIB_H_INSIDE__ + +#endif /* __G_LIB_H__ */ diff --git a/glib/glib/glib.py b/glib/glib/glib.py new file mode 100644 index 0000000..9a47d52 --- /dev/null +++ b/glib/glib/glib.py @@ -0,0 +1,250 @@ +import gdb + +# This is not quite right, as local vars may override symname +def read_global_var (symname): + return gdb.selected_frame().read_var(symname) + +def g_quark_to_string (quark): + if quark == None: + return None + quark = long(quark) + if quark == 0: + return None + val = read_global_var ("g_quarks") + max_q = long(read_global_var ("g_quark_seq_id")) + if quark < max_q: + return val[quark].string() + return None + +# We override the node printers too, so that node->next is not expanded +class GListNodePrinter: + "Prints a GList node" + + def __init__ (self, val): + self.val = val + + def to_string (self): + return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"])) + +class GSListNodePrinter: + "Prints a GSList node" + + def __init__ (self, val): + self.val = val + + def to_string (self): + return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"])) + +class GListPrinter: + "Prints a GList" + + class _iterator: + def __init__(self, head, listtype): + self.link = head + self.listtype = listtype + self.count = 0 + + def __iter__(self): + return self + + def next(self): + if self.link == 0: + raise StopIteration + data = self.link['data'] + self.link = self.link['next'] + count = self.count + self.count = self.count + 1 + return ('[%d]' % count, data) + + def __init__ (self, val, listtype): + self.val = val + self.listtype = listtype + + def children(self): + return self._iterator(self.val, self.listtype) + + def to_string (self): + return "0x%x" % (long(self.val)) + + def display_hint (self): + return "array" + +class GHashPrinter: + "Prints a GHashTable" + + class _iterator: + def __init__(self, ht, keys_are_strings): + self.ht = ht + if ht != 0: + self.keys = ht["keys"] + self.values = ht["values"] + self.hashes = ht["hashes"] + self.size = ht["size"] + self.pos = 0 + self.keys_are_strings = keys_are_strings + self.value = None + + def __iter__(self): + return self + + def next(self): + if self.ht == 0: + raise StopIteration + if self.value != None: + v = self.value + self.value = None + return v + while long(self.pos) < long(self.size): + self.pos = self.pos + 1 + if long (self.hashes[self.pos]) >= 2: + key = self.keys[self.pos] + val = self.values[self.pos] + + if self.keys_are_strings: + key = key.cast (gdb.lookup_type("char").pointer()) + + # Queue value for next result + self.value = ('[%dv]'% (self.pos), val) + + # Return key + return ('[%dk]'% (self.pos), key) + raise StopIteration + + def __init__ (self, val): + self.val = val + self.keys_are_strings = False + try: + string_hash = read_global_var ("g_str_hash") + except: + string_hash = None + if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash: + self.keys_are_strings = True + + def children(self): + return self._iterator(self.val, self.keys_are_strings) + + def to_string (self): + return "0x%x" % (long(self.val)) + + def display_hint (self): + return "map" + +def pretty_printer_lookup (val): + if is_g_type_instance (val): + return GTypePrettyPrinter (val) + +def pretty_printer_lookup (val): + # None yet, want things like hash table and list + + type = val.type.unqualified() + + # If it points to a reference, get the reference. + if type.code == gdb.TYPE_CODE_REF: + type = type.target () + + if type.code == gdb.TYPE_CODE_PTR: + type = type.target().unqualified() + t = str(type) + if t == "GList": + return GListPrinter(val, "GList") + if t == "GSList": + return GListPrinter(val, "GSList") + if t == "GHashTable": + return GHashPrinter(val) + else: + t = str(type) + if t == "GList": + return GListNodePrinter(val) + if t == "GSList *": + return GListPrinter(val, "GSList") + return None + +def register (obj): + if obj == None: + obj = gdb + + obj.pretty_printers.append(pretty_printer_lookup) + +class ForeachCommand (gdb.Command): + """Foreach on list""" + + def __init__ (self): + super (ForeachCommand, self).__init__ ("gforeach", + gdb.COMMAND_DATA, + gdb.COMPLETE_SYMBOL) + + def valid_name (self, name): + if not name[0].isalpha(): + return False + return True + + def parse_args (self, arg): + i = arg.find(" ") + if i <= 0: + raise Exception ("No var specified") + var = arg[:i] + if not self.valid_name(var): + raise Exception ("Invalid variable name") + + while i < len (arg) and arg[i].isspace(): + i = i + 1 + + if arg[i:i+2] != "in": + raise Exception ("Invalid syntax, missing in") + + i = i + 2 + + while i < len (arg) and arg[i].isspace(): + i = i + 1 + + colon = arg.find (":", i) + if colon == -1: + raise Exception ("Invalid syntax, missing colon") + + val = arg[i:colon] + + colon = colon + 1 + while colon < len (arg) and arg[colon].isspace(): + colon = colon + 1 + + command = arg[colon:] + + return (var, val, command) + + def do_iter(self, arg, item, command): + item = item.cast (gdb.lookup_type("void").pointer()) + item = long(item) + to_eval = "set $%s = (void *)0x%x\n"%(arg, item) + gdb.execute(to_eval) + gdb.execute(command) + + def slist_iterator (self, arg, container, command): + l = container.cast (gdb.lookup_type("GSList").pointer()) + while long(l) != 0: + self.do_iter (arg, l["data"], command) + l = l["next"] + + def list_iterator (self, arg, container, command): + l = container.cast (gdb.lookup_type("GList").pointer()) + while long(l) != 0: + self.do_iter (arg, l["data"], command) + l = l["next"] + + def pick_iterator (self, container): + t = container.type.unqualified() + if t.code == gdb.TYPE_CODE_PTR: + t = t.target().unqualified() + t = str(t) + if t == "GSList": + return self.slist_iterator + if t == "GList": + return self.list_iterator + raise Exception("Invalid container type %s"%(str(container.type))) + + def invoke (self, arg, from_tty): + (var, container, command) = self.parse_args(arg) + container = gdb.parse_and_eval (container) + func = self.pick_iterator(container) + func(var, container, command) + +ForeachCommand () diff --git a/glib/glib/glib.rc.in b/glib/glib/glib.rc.in new file mode 100644 index 0000000..a476718 --- /dev/null +++ b/glib/glib/glib.rc.in @@ -0,0 +1,30 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0 + FILEFLAGSMASK 0 + FILEFLAGS 0 + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN + BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904B0" + BEGIN + VALUE "CompanyName", "The GLib developer community" + VALUE "FileDescription", "GLib" + VALUE "FileVersion", "@GLIB_VERSION@.0" + VALUE "InternalName", "libglib-2.0-@LT_CURRENT_MINUS_AGE@" + VALUE "LegalCopyright", "Copyright © 1995-2011 Peter Mattis, Spencer Kimball, Josh MacDonald and others." + VALUE "OriginalFilename", "libglib-2.0-@LT_CURRENT_MINUS_AGE@.dll" + VALUE "ProductName", "GLib" + VALUE "ProductVersion", "@GLIB_VERSION@" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END + END diff --git a/glib/glib/glib.stp.in b/glib/glib/glib.stp.in new file mode 100644 index 0000000..95d3351 --- /dev/null +++ b/glib/glib/glib.stp.in @@ -0,0 +1,84 @@ +global gquarks + +/* This is needed to keep track of gquark for use in other probes.*/ +probe process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("quark__new") +{ + gquarks[pid(), $arg2] = user_string($arg1) +} + +/** + * probe glib.quark_new - Called when a #GQuark is initially created + * @quark: integer value for the quark + * @str: string form of the quark + */ +probe glib.quark_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("quark__new") +{ + str = user_string ($arg1); + quark = $arg2; + probestr = sprintf("glib.quark_new(%s) -> %d", str, quark); +} + +/** + * probe glib.mem_alloc - Called when a malloc block is initially requested + * @mem: Raw memory pointer returned + * @n_bytes: number of bytes + * @zeroed: Boolean value, %TRUE if this block was filled with NUL bytes + * @failable: Boolean value, %TRUE if program execution can continue on allocation failure + */ +probe glib.mem_alloc = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("mem__alloc") +{ + mem = $arg1; + n_bytes = $arg2; + zeroed = $arg3; + failable = $arg4; + probestr = sprintf("glib.mem_alloc(n_bytes=%d) -> %p", n_bytes, mem); +} + +/** + * probe glib.mem_free - Called when a malloc block freed + */ +probe glib.mem_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("mem__free") +{ + mem = $arg1; /* ARG: @mem: Raw memory pointer */ + probestr = sprintf("glib.mem_free(mem=%p)", mem); +} + +/** + * probe glib.mem_realloc - Called when a malloc block is resized + * @mem: Raw memory pointer returned + * @old_mem: Original memory pointer + * @n_bytes: number of bytes + * @failable: Boolean value, %TRUE if program execution can continue on allocation failure + */ +probe glib.mem_realloc = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("mem__realloc") +{ + mem = $arg1; + old_mem = $arg2; + n_bytes = $arg3; + failable = $arg4; + probestr = sprintf("glib.mem_realloc(old_mem=%p, n_bytes=%d) -> %p", old_mem, n_bytes, mem); +} + +/** + * probe glib.slice_alloc - Called when g_slice_alloc() is used + * @mem: Raw memory pointer returned + * @n_bytes: number of bytes + */ +probe glib.slice_alloc = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("slice__alloc") +{ + mem = $arg1; + n_bytes = $arg2; + probestr = sprintf("glib.slice_alloc(n_bytes=%d) -> %p", n_bytes, mem); +} + +/** + * probe glib.slice_free - Called when memory slice is freed + * @mem: Raw memory pointer returned + * @n_bytes: Number of bytes + */ +probe glib.slice_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("slice__free") +{ + mem = $arg1; + n_bytes = $arg2; + probestr = sprintf("glib.slice_free(n_bytes=%d) -> %p", n_bytes, mem); +} diff --git a/glib/glib/glib.symbols b/glib/glib/glib.symbols new file mode 100644 index 0000000..6c2db0d --- /dev/null +++ b/glib/glib/glib.symbols @@ -0,0 +1,1665 @@ +/* This file lists all exported symbols. It is used to generate + * the glib.def file used to control exports on Windows. + */ +g_array_append_vals +g_array_free +g_array_insert_vals +g_array_new +g_array_ref +g_array_unref +g_array_get_element_size +g_array_prepend_vals +g_array_remove_index +g_array_remove_index_fast +g_array_remove_range +g_array_set_clear_func +g_array_set_size +g_array_sized_new +g_array_sort +g_array_sort_with_data +g_byte_array_append +g_byte_array_free +g_byte_array_free_to_bytes +g_byte_array_unref +g_byte_array_ref +g_byte_array_new +g_byte_array_new_take +g_byte_array_prepend +g_byte_array_remove_index +g_byte_array_remove_index_fast +g_byte_array_remove_range +g_byte_array_set_size +g_byte_array_sized_new +g_byte_array_sort +g_byte_array_sort_with_data +g_bytes_compare +g_bytes_equal +g_bytes_get_data +g_bytes_get_size +g_bytes_hash +g_bytes_new +g_bytes_new_from_bytes +g_bytes_new_static +g_bytes_new_take +g_bytes_new_with_free_func +g_bytes_ref +g_bytes_unref +g_bytes_unref_to_array +g_bytes_unref_to_data +g_ptr_array_add +g_ptr_array_foreach +g_ptr_array_free +g_ptr_array_unref +g_ptr_array_ref +g_ptr_array_new +g_ptr_array_new_full +g_ptr_array_new_with_free_func +g_ptr_array_set_free_func +g_ptr_array_remove +g_ptr_array_remove_fast +g_ptr_array_remove_index +g_ptr_array_remove_index_fast +g_ptr_array_remove_range +g_ptr_array_set_size +g_ptr_array_sized_new +g_ptr_array_sort +g_ptr_array_sort_with_data +g_async_queue_length +g_async_queue_length_unlocked +g_async_queue_lock +g_async_queue_new +g_async_queue_new_full +g_async_queue_pop +g_async_queue_pop_unlocked +g_async_queue_push +g_async_queue_push_unlocked +g_async_queue_push_sorted +g_async_queue_push_sorted_unlocked +g_async_queue_ref +g_async_queue_sort +g_async_queue_sort_unlocked +g_async_queue_timed_pop +g_async_queue_timed_pop_unlocked +g_async_queue_timeout_pop +g_async_queue_timeout_pop_unlocked +g_async_queue_try_pop +g_async_queue_try_pop_unlocked +g_async_queue_unlock +g_async_queue_unref +g_async_queue_ref_unlocked +g_async_queue_unref_and_unlock +g_atomic_int_add +g_atomic_int_and +g_atomic_int_compare_and_exchange +g_atomic_int_dec_and_test +g_atomic_int_exchange_and_add +g_atomic_int_get +g_atomic_int_inc +g_atomic_int_or +g_atomic_int_set +g_atomic_int_xor +g_atomic_pointer_add +g_atomic_pointer_and +g_atomic_pointer_compare_and_exchange +g_atomic_pointer_get +g_atomic_pointer_or +g_atomic_pointer_set +g_atomic_pointer_xor +g_on_error_query +g_on_error_stack_trace +g_base64_encode_step +g_base64_encode_close +g_base64_encode +g_base64_decode_step +g_base64_decode +g_base64_decode_inplace +g_bookmark_file_error_quark +g_bookmark_file_new +g_bookmark_file_free +g_bookmark_file_load_from_file +g_bookmark_file_load_from_data +g_bookmark_file_load_from_data_dirs +g_bookmark_file_to_data +g_bookmark_file_to_file +g_bookmark_file_set_title +g_bookmark_file_get_title +g_bookmark_file_set_description +g_bookmark_file_get_description +g_bookmark_file_set_mime_type +g_bookmark_file_get_mime_type +g_bookmark_file_set_groups +g_bookmark_file_add_group +g_bookmark_file_has_group +g_bookmark_file_get_groups +g_bookmark_file_add_application +g_bookmark_file_has_application +g_bookmark_file_get_applications +g_bookmark_file_set_app_info +g_bookmark_file_get_app_info +g_bookmark_file_set_is_private +g_bookmark_file_get_is_private +g_bookmark_file_set_icon +g_bookmark_file_get_icon +g_bookmark_file_set_added +g_bookmark_file_get_added +g_bookmark_file_set_modified +g_bookmark_file_get_modified +g_bookmark_file_set_visited +g_bookmark_file_get_visited +g_bookmark_file_has_item +g_bookmark_file_get_size +g_bookmark_file_get_uris +g_bookmark_file_remove_group +g_bookmark_file_remove_application +g_bookmark_file_remove_item +g_bookmark_file_move_item +g_cache_destroy +g_cache_insert +g_cache_key_foreach +g_cache_new +g_cache_remove +g_cache_value_foreach +g_checksum_type_get_length +g_checksum_new +g_checksum_copy +g_checksum_free +g_checksum_update +g_checksum_reset +g_checksum_get_string +g_checksum_get_digest +g_compute_checksum_for_data +g_compute_checksum_for_string +g_completion_add_items +g_completion_clear_items +g_completion_complete +g_completion_complete_utf8 +g_completion_free +g_completion_new +g_completion_remove_items +g_completion_set_compare +g_get_filename_charsets +g_convert +g_convert_error_quark +g_convert_with_fallback +g_convert_with_iconv +g_iconv +g_iconv_close +g_iconv_open +g_locale_from_utf8 +g_locale_to_utf8 +g_filename_display_name +g_filename_display_basename +#ifndef _WIN64 +g_filename_from_uri PRIVATE +g_filename_from_utf8 PRIVATE +g_filename_to_uri PRIVATE +g_filename_to_utf8 PRIVATE +#endif +#ifdef G_OS_WIN32 +g_filename_from_uri_utf8 +g_filename_from_utf8_utf8 +g_filename_to_uri_utf8 +g_filename_to_utf8_utf8 +#endif +g_uri_list_extract_uris +g_datalist_clear +g_datalist_foreach +g_datalist_get_data +g_datalist_get_flags +g_datalist_id_get_data +g_datalist_id_remove_no_notify +g_datalist_id_set_data_full +g_datalist_set_flags +g_datalist_unset_flags +g_datalist_init +g_dataset_destroy +g_dataset_foreach +g_dataset_id_get_data +g_dataset_id_remove_no_notify +g_dataset_id_set_data_full +g_quark_from_static_string +g_quark_from_string +g_quark_to_string +g_quark_try_string +g_intern_string +g_intern_static_string +g_date_add_days +g_date_add_months +g_date_add_years +g_date_clamp +g_date_clear +g_date_compare +g_date_days_between +g_date_free +g_date_get_day +g_date_get_day_of_year +g_date_get_days_in_month +g_date_get_iso8601_week_of_year +g_date_get_julian +g_date_get_monday_week_of_year +g_date_get_monday_weeks_in_year +g_date_get_month +g_date_get_sunday_week_of_year +g_date_get_sunday_weeks_in_year +g_date_get_weekday +g_date_get_year +g_date_is_first_of_month +g_date_is_last_of_month +g_date_is_leap_year +g_date_new +g_date_new_dmy +g_date_new_julian +g_date_order +g_date_set_day +g_date_set_dmy +g_date_set_julian +g_date_set_month +g_date_set_parse +g_date_set_time +g_date_set_time_t +g_date_set_time_val +g_date_set_year +g_date_strftime +g_date_subtract_days +g_date_subtract_months +g_date_subtract_years +g_date_to_struct_tm +g_date_valid +g_date_valid_day +g_date_valid_dmy +g_date_valid_julian +g_date_valid_month +g_date_valid_weekday +g_date_valid_year +g_date_time_add +g_date_time_add_days +g_date_time_add_full +g_date_time_add_hours +g_date_time_add_minutes +g_date_time_add_months +g_date_time_add_seconds +g_date_time_add_weeks +g_date_time_add_years +g_date_time_compare +g_date_time_difference +g_date_time_equal +g_date_time_format +g_date_time_get_day_of_month +g_date_time_get_day_of_week +g_date_time_get_day_of_year +g_date_time_get_hour +g_date_time_get_microsecond +g_date_time_get_minute +g_date_time_get_month +g_date_time_get_second +g_date_time_get_seconds +g_date_time_get_timezone_abbreviation +g_date_time_get_utc_offset +g_date_time_get_week_numbering_year +g_date_time_get_week_of_year +g_date_time_get_year +g_date_time_get_ymd +g_date_time_hash +g_date_time_is_daylight_savings +g_date_time_new +g_date_time_new_from_timeval_local +g_date_time_new_from_timeval_utc +g_date_time_new_from_unix_local +g_date_time_new_from_unix_utc +g_date_time_new_local +g_date_time_new_now +g_date_time_new_now_local +g_date_time_new_now_utc +g_date_time_new_utc +g_date_time_ref +g_date_time_to_local +g_date_time_to_timeval +g_date_time_to_timezone +g_date_time_to_unix +g_date_time_to_utc +g_date_time_unref +g_time_zone_new +g_time_zone_new_local +g_time_zone_new_utc +g_time_zone_ref +g_time_zone_unref +g_time_zone_adjust_time +g_time_zone_find_interval +g_time_zone_get_abbreviation +g_time_zone_get_offset +g_time_zone_is_dst +g_dir_close +#ifndef _WIN64 +g_dir_open PRIVATE +g_dir_read_name PRIVATE +#endif +#ifdef G_OS_WIN32 +g_dir_open_utf8 +g_dir_read_name_utf8 +#endif +g_dir_rewind +g_clear_error +g_error_copy +g_error_free +g_error_matches +g_error_new +g_error_new_literal +g_error_new_valist +g_propagate_error +g_set_error +g_set_error_literal +g_prefix_error +g_propagate_prefixed_error +g_build_filename +g_build_filenamev +g_build_path +g_build_pathv +g_file_error_from_errno +g_file_error_quark +#ifndef _WIN64 +g_file_get_contents PRIVATE +#endif +g_file_set_contents +g_dir_make_tmp +#ifndef _WIN64 +g_file_open_tmp PRIVATE +g_file_test PRIVATE +#endif +g_file_read_link +g_format_size +g_format_size_full +g_format_size_for_display +#ifndef _WIN64 +g_mkstemp PRIVATE +#endif +g_mkdtemp +g_mkdtemp_full +g_mkstemp_full +g_mkdir_with_parents +#ifdef G_OS_WIN32 +g_file_get_contents_utf8 +g_file_open_tmp_utf8 +g_file_test_utf8 +g_mkstemp_utf8 +#endif +g_hash_table_add +g_hash_table_contains +g_hash_table_destroy +g_hash_table_unref +g_hash_table_ref +g_hash_table_find +g_hash_table_foreach +g_hash_table_foreach_remove +g_hash_table_foreach_steal +g_hash_table_get_keys +g_hash_table_get_values +g_hash_table_insert +g_hash_table_lookup +g_hash_table_lookup_extended +g_hash_table_new +g_hash_table_new_full +g_hash_table_remove +g_hash_table_remove_all +g_hash_table_replace +g_hash_table_size +g_hash_table_steal +g_hash_table_steal_all +g_hash_table_iter_init +g_hash_table_iter_next +g_hash_table_iter_get_hash_table +g_hash_table_iter_remove +g_hash_table_iter_replace +g_hash_table_iter_steal +g_hmac_new +g_hmac_copy +g_hmac_ref +g_hmac_unref +g_hmac_update +g_hmac_get_string +g_hmac_get_digest +g_compute_hmac_for_data +g_compute_hmac_for_string +g_hook_alloc +g_hook_compare_ids +g_hook_destroy +g_hook_destroy_link +g_hook_find +g_hook_find_data +g_hook_find_func +g_hook_find_func_data +g_hook_first_valid +g_hook_free +g_hook_get +g_hook_insert_before +g_hook_insert_sorted +g_hook_list_clear +g_hook_list_init +g_hook_list_invoke +g_hook_list_invoke_check +g_hook_list_marshal +g_hook_list_marshal_check +g_hook_next_valid +g_hook_prepend +g_hook_ref +g_hook_unref +g_io_add_watch +g_io_add_watch_full +g_io_create_watch +g_io_channel_error_from_errno +g_io_channel_error_quark +g_io_channel_flush +g_io_channel_get_buffer_condition +g_io_channel_get_buffered +g_io_channel_get_buffer_size +g_io_channel_get_close_on_unref +g_io_channel_get_encoding +g_io_channel_get_flags +g_io_channel_get_line_term +g_io_channel_init +g_io_channel_read_chars +g_io_channel_read_line +g_io_channel_read_line_string +g_io_channel_read_to_end +g_io_channel_read_unichar +g_io_channel_ref +g_io_channel_seek_position +g_io_channel_set_buffered +g_io_channel_set_buffer_size +g_io_channel_set_close_on_unref +g_io_channel_set_encoding +g_io_channel_set_flags +g_io_channel_set_line_term +g_io_channel_shutdown +g_io_channel_unref +g_io_channel_close +g_io_channel_read +g_io_channel_seek +g_io_channel_write +g_io_channel_write_chars +g_io_channel_write_unichar +#ifdef G_OS_UNIX +g_io_channel_unix_get_fd +g_io_channel_unix_new +g_io_channel_new_file +#endif +#ifdef G_OS_WIN32 +g_io_channel_unix_get_fd +g_io_channel_unix_new +#ifndef _WIN64 +g_io_channel_new_file PRIVATE +#endif +g_io_channel_new_file_utf8 +g_io_channel_win32_get_fd +g_io_channel_win32_make_pollfd +g_io_channel_win32_new_fd +g_io_channel_win32_new_messages +g_io_channel_win32_new_socket +#ifndef _WIN64 +g_io_channel_win32_new_stream_socket PRIVATE +#endif +g_io_channel_win32_poll +g_io_channel_win32_set_debug +#endif +g_key_file_error_quark +g_key_file_ref +g_key_file_unref +g_key_file_free +g_key_file_get_boolean +g_key_file_get_boolean_list +g_key_file_get_comment +g_key_file_get_groups +g_key_file_get_double +g_key_file_get_double_list +g_key_file_get_integer +g_key_file_get_int64 +g_key_file_get_uint64 +g_key_file_get_integer_list +g_key_file_get_keys +g_key_file_get_locale_string +g_key_file_get_locale_string_list +g_key_file_get_start_group +g_key_file_get_string +g_key_file_get_string_list +g_key_file_get_value +g_key_file_has_group +g_key_file_has_key +g_key_file_load_from_dirs +g_key_file_load_from_data +g_key_file_load_from_data_dirs +g_key_file_load_from_file +g_key_file_new +g_key_file_remove_comment +g_key_file_remove_group +g_key_file_remove_key +g_key_file_set_boolean +g_key_file_set_boolean_list +g_key_file_set_comment +g_key_file_set_double +g_key_file_set_double_list +g_key_file_set_integer +g_key_file_set_int64 +g_key_file_set_uint64 +g_key_file_set_integer_list +g_key_file_set_list_separator +g_key_file_set_locale_string +g_key_file_set_locale_string_list +g_key_file_set_string +g_key_file_set_string_list +g_key_file_set_value +g_key_file_to_data +g_list_alloc +g_list_append +g_list_concat +g_list_copy +g_list_delete_link +g_list_find +g_list_find_custom +g_list_first +g_list_foreach +g_list_free +g_list_free_full +g_list_free_1 +g_list_index +g_list_insert +g_list_insert_before +g_list_insert_sorted +g_list_insert_sorted_with_data +g_list_last +g_list_length +g_list_nth +g_list_nth_data +g_list_nth_prev +g_list_pop_allocator +g_list_position +g_list_prepend +g_list_push_allocator +g_list_remove +g_list_remove_all +g_list_remove_link +g_list_reverse +g_list_sort +g_list_sort_with_data +g_child_watch_add +g_child_watch_add_full +g_child_watch_source_new +g_get_current_time +g_get_monotonic_time +g_get_real_time +g_main_context_acquire +g_main_context_add_poll +g_main_context_check +g_main_context_default +g_main_context_dispatch +g_main_context_find_source_by_funcs_user_data +g_main_context_find_source_by_id +g_main_context_find_source_by_user_data +g_main_context_get_poll_func +g_main_context_get_thread_default +g_main_context_is_owner +g_main_context_iteration +g_main_context_new +g_main_context_pending +g_main_context_pop_thread_default +g_main_context_prepare +g_main_context_push_thread_default +g_main_context_query +g_main_context_ref +g_main_context_ref_thread_default +g_main_context_release +g_main_context_remove_poll +g_main_context_set_poll_func +g_main_context_unref +g_main_context_wait +g_main_context_wakeup +g_main_context_invoke +g_main_context_invoke_full +g_main_depth +g_main_current_source +g_main_loop_get_context +g_main_loop_is_running +g_main_loop_new +g_main_loop_quit +g_main_loop_ref +g_main_loop_run +g_main_loop_unref +g_source_add_child_source +g_source_add_poll +g_source_attach +g_source_destroy +g_source_get_can_recurse +g_source_get_context +g_source_get_time +g_source_get_current_time +g_source_get_id +g_source_get_name +g_source_get_priority +g_source_new +g_source_ref +g_source_remove +g_source_remove_by_funcs_user_data +g_source_remove_by_user_data +g_source_remove_child_source +g_source_remove_poll +g_source_set_callback +g_source_set_callback_indirect +g_source_set_can_recurse +g_source_set_funcs +g_source_set_name +g_source_set_name_by_id +g_source_is_destroyed +g_source_set_priority +g_source_unref +g_idle_add +g_idle_add_full +g_idle_remove_by_data +g_idle_source_new +g_timeout_add +g_timeout_add_seconds +g_timeout_add_full +g_timeout_add_seconds_full +g_timeout_source_new +g_timeout_source_new_seconds +g_mapped_file_new +g_mapped_file_new_from_fd +g_mapped_file_get_length +g_mapped_file_get_contents +g_mapped_file_ref +g_mapped_file_unref +g_mapped_file_free +g_markup_error_quark +g_markup_escape_text +g_markup_parse_context_end_parse +g_markup_parse_context_free +g_markup_parse_context_get_element +g_markup_parse_context_get_element_stack +g_markup_parse_context_get_position +g_markup_parse_context_get_user_data +g_markup_parse_context_new +g_markup_parse_context_parse +g_markup_parse_context_push +g_markup_parse_context_pop +g_markup_printf_escaped +g_markup_vprintf_escaped +g_markup_collect_attributes +g_free +g_malloc +g_malloc0 +g_malloc_n +g_malloc0_n +g_mem_is_system_malloc +g_mem_profile +g_mem_set_vtable +g_realloc +g_realloc_n +g_try_malloc +g_try_malloc0 +g_try_malloc_n +g_try_malloc0_n +g_try_realloc +g_try_realloc_n +g_allocator_free +g_allocator_new +g_mem_chunk_alloc +g_mem_chunk_alloc0 +g_mem_chunk_clean +g_mem_chunk_destroy +g_mem_chunk_free +g_mem_chunk_info +g_mem_chunk_new +g_mem_chunk_print +g_mem_chunk_reset +g_blow_chunks +g_slice_alloc +g_slice_alloc0 +g_slice_copy +g_slice_free1 +g_slice_free_chain_with_offset +g_slice_set_config +g_slice_get_config +g_slice_get_config_state +#ifdef G_ENABLE_DEBUG +g_slice_debug_tree_statistics +#endif +g_printf_string_upper_bound +g_log +g_log_default_handler +g_log_remove_handler +g_log_set_always_fatal +g_log_set_default_handler +g_log_set_fatal_mask +g_log_set_handler +g_logv +g_return_if_fail_warning +g_warn_message +g_assert_warning +g_print +g_printerr +g_set_printerr_handler +g_set_print_handler +g_node_child_index +g_node_child_position +g_node_children_foreach +g_node_copy +g_node_copy_deep +g_node_depth +g_node_destroy +g_node_find +g_node_find_child +g_node_first_sibling +g_node_get_root +g_node_insert +g_node_insert_after +g_node_insert_before +g_node_is_ancestor +g_node_last_child +g_node_last_sibling +g_node_max_height +g_node_n_children +g_node_new +g_node_n_nodes +g_node_nth_child +g_node_pop_allocator +g_node_prepend +g_node_push_allocator +g_node_reverse_children +g_node_traverse +g_node_unlink +g_option_context_add_group +g_option_context_add_main_entries +g_option_error_quark +g_option_context_free +g_option_context_get_description +g_option_context_get_help_enabled +g_option_context_get_ignore_unknown_options +g_option_context_get_main_group +g_option_context_get_summary +g_option_context_new +g_option_context_parse +g_option_context_set_description +g_option_context_set_help_enabled +g_option_context_set_ignore_unknown_options +g_option_context_set_main_group +g_option_context_set_summary +g_option_context_set_translate_func +g_option_context_set_translation_domain +g_option_context_get_help +g_option_group_add_entries +g_option_group_free +g_option_group_new +g_option_group_set_error_hook +g_option_group_set_parse_hooks +g_option_group_set_translate_func +g_option_group_set_translation_domain +g_pattern_match +g_pattern_match_simple +g_pattern_match_string +g_pattern_spec_equal +g_pattern_spec_free +g_pattern_spec_new +g_poll +g_spaced_primes_closest +g_fprintf +g_printf +g_sprintf +g_vasprintf +g_vfprintf +g_vprintf +g_vsprintf +g_snprintf +g_vsnprintf +g_qsort_with_data +g_queue_clear +g_queue_copy +g_queue_delete_link +g_queue_find +g_queue_find_custom +g_queue_foreach +g_queue_free +g_queue_free_full +g_queue_get_length +g_queue_index +g_queue_init +g_queue_insert_after +g_queue_insert_before +g_queue_insert_sorted +g_queue_is_empty +g_queue_link_index +g_queue_new +g_queue_peek_head +g_queue_peek_head_link +g_queue_peek_nth +g_queue_peek_nth_link +g_queue_peek_tail +g_queue_peek_tail_link +g_queue_pop_head +g_queue_pop_head_link +g_queue_pop_nth +g_queue_pop_nth_link +g_queue_pop_tail +g_queue_pop_tail_link +g_queue_push_head +g_queue_push_head_link +g_queue_push_nth +g_queue_push_nth_link +g_queue_push_tail +g_queue_push_tail_link +g_queue_remove +g_queue_remove_all +g_queue_reverse +g_queue_sort +g_queue_unlink +g_rand_copy +g_rand_double +g_rand_double_range +g_rand_free +g_rand_int +g_rand_int_range +g_rand_new +g_rand_new_with_seed +g_rand_new_with_seed_array +g_random_double +g_random_double_range +g_random_int +g_random_int_range +g_random_set_seed +g_rand_set_seed +g_rand_set_seed_array +g_relation_count +g_relation_delete +g_relation_destroy +g_relation_exists +g_relation_index +g_relation_insert +g_relation_new +g_relation_print +g_relation_select +g_tuples_destroy +g_tuples_index +g_scanner_cur_line +g_scanner_cur_position +g_scanner_cur_token +g_scanner_cur_value +g_scanner_destroy +g_scanner_eof +g_scanner_error +g_scanner_get_next_token +g_scanner_input_file +g_scanner_input_text +g_scanner_lookup_symbol +g_scanner_new +g_scanner_peek_next_token +g_scanner_scope_add_symbol +g_scanner_scope_foreach_symbol +g_scanner_scope_lookup_symbol +g_scanner_scope_remove_symbol +g_scanner_set_scope +g_scanner_sync_file_offset +g_scanner_unexp_token +g_scanner_warn +g_sequence_new +g_sequence_free +g_sequence_get_length +g_sequence_foreach +g_sequence_foreach_range +g_sequence_sort +g_sequence_sort_iter +g_sequence_get_begin_iter +g_sequence_get_end_iter +g_sequence_get_iter_at_pos +g_sequence_append +g_sequence_prepend +g_sequence_insert_before +g_sequence_move +g_sequence_swap +g_sequence_insert_sorted +g_sequence_insert_sorted_iter +g_sequence_sort_changed +g_sequence_sort_changed_iter +g_sequence_remove +g_sequence_remove_range +g_sequence_move_range +g_sequence_search +g_sequence_search_iter +g_sequence_lookup +g_sequence_lookup_iter +g_sequence_get +g_sequence_set +g_sequence_iter_is_begin +g_sequence_iter_is_end +g_sequence_iter_next +g_sequence_iter_prev +g_sequence_iter_get_position +g_sequence_iter_move +g_sequence_iter_get_sequence +g_sequence_iter_compare +g_sequence_range_get_midpoint +g_shell_error_quark +g_shell_parse_argv +g_shell_quote +g_shell_unquote +g_slist_alloc +g_slist_append +g_slist_concat +g_slist_copy +g_slist_delete_link +g_slist_find +g_slist_find_custom +g_slist_foreach +g_slist_free +g_slist_free_full +g_slist_free_1 +g_slist_index +g_slist_insert +g_slist_insert_before +g_slist_insert_sorted +g_slist_insert_sorted_with_data +g_slist_last +g_slist_length +g_slist_nth +g_slist_nth_data +g_slist_pop_allocator +g_slist_position +g_slist_prepend +g_slist_push_allocator +g_slist_remove +g_slist_remove_all +g_slist_remove_link +g_slist_reverse +g_slist_sort +g_slist_sort_with_data +#ifndef _WIN64 +g_spawn_async PRIVATE +g_spawn_async_with_pipes PRIVATE +#endif +g_spawn_close_pid +#ifndef _WIN64 +g_spawn_command_line_async PRIVATE +g_spawn_command_line_sync PRIVATE +#endif +g_spawn_error_quark +#ifndef _WIN64 +g_spawn_sync PRIVATE +#endif +#ifdef G_OS_WIN32 +g_spawn_async_utf8 +g_spawn_async_with_pipes_utf8 +g_spawn_command_line_async_utf8 +g_spawn_command_line_sync_utf8 +g_spawn_sync_utf8 +#endif +#if !defined(G_OS_UNIX) || defined(G_STDIO_NO_WRAP_ON_UNIX) +/* gstdio wrappers */ +g_chmod +g_open +g_creat +g_rename +g_mkdir +g_stat +g_lstat +g_remove +g_fopen +g_freopen +g_utime +#endif +g_access +g_chdir +g_unlink +g_rmdir +g_ascii_digit_value +g_ascii_dtostr +g_ascii_formatd +g_ascii_strdown +g_ascii_strtod +g_ascii_strtoull +g_ascii_strtoll +g_ascii_strup +g_ascii_tolower +g_ascii_toupper +g_ascii_xdigit_value +g_ascii_strcasecmp +g_ascii_strncasecmp +g_memdup +g_stpcpy +g_strcanon +g_strchomp +g_strchug +g_strcompress +g_strconcat +g_strdelimit +g_strdup +g_strdup_printf +g_strdupv +g_strdup_vprintf +g_strerror +g_strescape +g_strfreev +g_str_has_prefix +g_str_has_suffix +g_strjoin +g_strjoinv +g_strlcat +g_strlcpy +g_strndup +g_strnfill +g_strreverse +g_strrstr +g_strrstr_len +g_strsignal +g_strsplit +g_strsplit_set +g_strstr_len +g_strtod +g_strcasecmp +g_strncasecmp +g_strup +g_strdown +g_strv_length +g_strip_context +g_dgettext +g_dcgettext +g_dngettext +g_dpgettext +g_dpgettext2 +g_uri_unescape_string +g_uri_unescape_segment +g_uri_parse_scheme +g_uri_escape_string +g_string_append +g_string_append_len +g_string_append_printf +g_string_append_unichar +g_string_append_vprintf +g_string_ascii_down +g_string_ascii_up +g_string_assign +g_string_chunk_free +g_string_chunk_clear +g_string_chunk_insert +g_string_chunk_insert_const +g_string_chunk_insert_len +g_string_chunk_new +g_string_equal +g_string_erase +g_string_free +g_string_hash +g_string_insert +g_string_insert_c +g_string_insert_len +g_string_insert_unichar +g_string_new +g_string_new_len +g_string_overwrite +g_string_overwrite_len +g_string_prepend +g_string_prepend_c +g_string_prepend_len +g_string_prepend_unichar +g_string_printf +g_string_set_size +g_string_sized_new +g_string_truncate +g_string_append_uri_escaped +g_string_down +g_string_up +g_string_vprintf +g_string_append_c +g_bit_lock +g_bit_trylock +g_bit_unlock +g_pointer_bit_lock +g_pointer_bit_trylock +g_pointer_bit_unlock +g_once_impl +g_once_init_enter_impl +g_once_init_leave +g_once_init_enter +g_threads_got_initialized +g_thread_gettime +g_thread_create +g_thread_create_full +g_thread_error_quark +g_thread_exit +g_thread_functions_for_glib_use +g_thread_init_glib +g_thread_join +g_thread_new +g_thread_ref +g_thread_self +g_thread_set_priority +g_thread_try_new +g_thread_use_default_impl +g_thread_unref +g_thread_yield +g_static_mutex_free +g_static_mutex_get_mutex_impl +g_static_mutex_init +g_static_private_free +g_static_private_get +g_static_private_init +g_static_private_set +g_static_rec_mutex_free +g_static_rec_mutex_init +g_static_rec_mutex_lock +g_static_rec_mutex_lock_full +g_static_rec_mutex_trylock +g_static_rec_mutex_unlock +g_static_rec_mutex_unlock_full +g_static_rw_lock_free +g_static_rw_lock_init +g_static_rw_lock_reader_lock +g_static_rw_lock_reader_trylock +g_static_rw_lock_reader_unlock +g_static_rw_lock_writer_lock +g_static_rw_lock_writer_trylock +g_static_rw_lock_writer_unlock +g_thread_foreach +g_thread_get_initialized +g_thread_pool_free +g_thread_pool_get_max_threads +g_thread_pool_get_max_unused_threads +g_thread_pool_get_max_idle_time +g_thread_pool_get_num_threads +g_thread_pool_get_num_unused_threads +g_thread_pool_new +g_thread_pool_push +g_thread_pool_set_max_threads +g_thread_pool_set_max_unused_threads +g_thread_pool_set_max_idle_time +g_thread_pool_stop_unused_threads +g_thread_pool_unprocessed +g_thread_pool_set_sort_function +g_test_log_set_fatal_handler +g_assertion_message +g_assertion_message_cmpnum +g_assertion_message_cmpstr +g_assertion_message_expr +g_assertion_message_error +g_strcmp0 +g_test_add_data_func +g_test_add_func +g_test_add_vtable +g_test_bug +g_test_bug_base +g_test_config_vars +g_test_create_case +g_test_create_suite +g_test_fail +g_test_get_root +g_test_init +g_test_log_buffer_free +g_test_log_buffer_new +g_test_log_buffer_pop +g_test_log_buffer_push +g_test_log_msg_free +g_test_log_type_name +g_test_maximized_result +g_test_message +g_test_minimized_result +g_test_queue_destroy +g_test_queue_free +g_test_rand_double +g_test_rand_double_range +g_test_rand_int +g_test_rand_int_range +g_test_run +g_test_run_suite +g_test_suite_add +g_test_suite_add_suite +g_test_timer_elapsed +g_test_timer_last +g_test_timer_start +g_test_trap_assertions +g_test_trap_fork +g_test_trap_has_passed +g_test_trap_reached_timeout +g_timer_continue +g_timer_destroy +g_timer_elapsed +g_timer_new +g_timer_reset +g_timer_start +g_timer_stop +g_time_val_add +g_time_val_from_iso8601 +g_time_val_to_iso8601 +g_usleep +g_tree_destroy +g_tree_foreach +g_tree_height +g_tree_insert +g_tree_lookup +g_tree_lookup_extended +g_tree_new +g_tree_ref +g_tree_unref +g_tree_new_full +g_tree_new_with_data +g_tree_nnodes +g_tree_remove +g_tree_replace +g_tree_search +g_tree_steal +g_tree_traverse +g_unichar_break_type +g_unichar_combining_class +g_unichar_compose +g_unichar_decompose +g_unichar_isalnum +g_unichar_isalpha +g_unichar_iscntrl +g_unichar_isdefined +g_unichar_isdigit +g_unichar_isgraph +g_unichar_islower +g_unichar_isprint +g_unichar_ispunct +g_unichar_isspace +g_unichar_istitle +g_unichar_isupper +g_unichar_iswide +g_unichar_iswide_cjk +g_unichar_isxdigit +g_unichar_iszerowidth +g_unichar_fully_decompose +g_unichar_tolower +g_unichar_totitle +g_unichar_toupper +g_unichar_ismark +g_unichar_get_mirror_char +g_unichar_get_script +g_unichar_digit_value +g_unichar_xdigit_value +g_unichar_type +g_unicode_canonical_decomposition +g_unicode_canonical_ordering +g_unicode_script_from_iso15924 +g_unicode_script_to_iso15924 +g_utf8_casefold +g_utf8_collate +g_utf8_collate_key +g_utf8_collate_key_for_filename +g_utf8_find_next_char +g_utf8_find_prev_char +g_utf8_get_char +g_utf8_get_char_validated +g_utf8_normalize +g_utf8_offset_to_pointer +g_utf8_pointer_to_offset +g_utf8_prev_char +g_utf8_strup +g_utf8_strdown +g_utf8_strchr +g_utf8_strlen +g_utf8_strncpy +g_utf8_strrchr +g_utf8_strreverse +g_utf8_substring +g_utf8_to_ucs4 +g_utf8_to_ucs4_fast +g_utf8_to_utf16 +g_utf8_validate +g_get_charset +g_ucs4_to_utf16 +g_ucs4_to_utf8 +g_utf16_to_ucs4 +g_utf16_to_utf8 +g_unichar_to_utf8 +g_unichar_validate +glib_pgettext +glib_gettext +#ifdef G_OS_WIN32 +_glib_get_locale_dir +#endif +g_int_equal +g_int_hash +g_int64_equal +g_int64_hash +g_double_equal +g_double_hash +g_direct_equal +g_direct_hash +g_str_equal +g_str_hash +g_atexit +g_basename +g_get_application_name +#ifndef _WIN64 +g_find_program_in_path PRIVATE +g_get_current_dir PRIVATE +g_getenv PRIVATE +g_unsetenv PRIVATE +g_get_home_dir PRIVATE +g_setenv PRIVATE +#endif +g_get_host_name +g_listenv +g_get_environ +g_environ_getenv +g_environ_setenv +g_environ_unsetenv +#ifdef G_OS_WIN32 +g_find_program_in_path_utf8 +g_get_current_dir_utf8 +g_getenv_utf8 +g_unsetenv_utf8 +g_setenv_utf8 +g_get_home_dir_utf8 +#endif +g_get_language_names +g_get_locale_variants +g_get_prgname +#ifndef _WIN64 +g_get_real_name PRIVATE +#endif +#ifdef G_OS_WIN32 +g_get_real_name_utf8 +#endif +g_get_system_config_dirs +g_get_system_data_dirs +#ifdef G_OS_WIN32 +g_win32_get_system_data_dirs_for_module +#endif +#ifndef _WIN64 +g_get_tmp_dir PRIVATE +#endif +#ifdef G_OS_WIN32 +g_get_tmp_dir_utf8 +#endif +g_get_user_cache_dir +g_get_user_config_dir +g_get_user_data_dir +g_reload_user_special_dirs_cache +g_get_user_runtime_dir +g_get_user_special_dir +#ifndef _WIN64 +g_get_user_name PRIVATE +#endif +#ifdef G_OS_WIN32 +g_get_user_name_utf8 +#endif +glib_check_version +glib__private__ +g_nullify_pointer +g_parse_debug_string +g_path_get_basename +g_path_get_dirname +g_path_is_absolute +g_path_skip_root +g_set_application_name +g_set_prgname +g_bit_nth_lsf +g_bit_nth_msf +g_bit_storage +g_trash_stack_height +g_trash_stack_peek +g_trash_stack_pop +g_trash_stack_push +g_get_codeset +g_regex_error_quark +g_regex_new +g_regex_ref +g_regex_unref +g_regex_get_pattern +g_regex_get_max_backref +g_regex_get_capture_count +g_regex_get_string_number +g_regex_get_compile_flags +g_regex_get_match_flags +g_regex_escape_string +g_regex_escape_nul +g_regex_match_simple +g_regex_match +g_regex_match_full +g_regex_match_all +g_regex_match_all_full +g_regex_split_simple +g_regex_split +g_regex_split_full +g_regex_replace +g_regex_replace_literal +g_regex_replace_eval +g_regex_check_replacement +g_match_info_get_regex +g_match_info_get_string +g_match_info_ref +g_match_info_unref +g_match_info_free +g_match_info_next +g_match_info_matches +g_match_info_get_match_count +g_match_info_is_partial_match +g_match_info_expand_references +g_match_info_fetch +g_match_info_fetch_pos +g_match_info_fetch_named +g_match_info_fetch_named_pos +g_match_info_fetch_all +g_variant_type_string_is_valid +g_variant_type_string_scan +g_variant_type_free +g_variant_type_copy +g_variant_type_new +g_variant_type_get_string_length +g_variant_type_peek_string +g_variant_type_dup_string +g_variant_type_is_definite +g_variant_type_is_container +g_variant_type_is_basic +g_variant_type_is_maybe +g_variant_type_is_array +g_variant_type_is_tuple +g_variant_type_is_dict_entry +g_variant_type_is_variant +g_variant_type_hash +g_variant_type_equal +g_variant_type_is_subtype_of +g_variant_type_element +g_variant_type_first +g_variant_type_next +g_variant_type_n_items +g_variant_type_key +g_variant_type_value +g_variant_type_new_array +g_variant_type_new_maybe +g_variant_type_new_tuple +g_variant_type_new_dict_entry +g_variant_type_checked_ +g_variant_unref +g_variant_ref +g_variant_ref_sink +g_variant_is_floating +g_variant_take_ref +g_variant_n_children +g_variant_get_child_value +g_variant_get_size +g_variant_get_data +g_variant_store +g_variant_is_normal_form +g_variant_get_type +g_variant_get_type_string +g_variant_is_of_type +g_variant_is_container +g_variant_classify +g_variant_compare +g_variant_new_boolean +g_variant_new_byte +g_variant_new_int16 +g_variant_new_uint16 +g_variant_new_int32 +g_variant_new_uint32 +g_variant_new_int64 +g_variant_new_uint64 +g_variant_new_handle +g_variant_new_double +g_variant_new_fixed_array +g_variant_new_string +g_variant_new_object_path +g_variant_is_object_path +g_variant_new_signature +g_variant_is_signature +g_variant_new_variant +g_variant_new_strv +g_variant_new_objv +g_variant_new_bytestring +g_variant_new_bytestring_array +g_variant_get_boolean +g_variant_get_byte +g_variant_get_int16 +g_variant_get_uint16 +g_variant_get_int32 +g_variant_get_uint32 +g_variant_get_int64 +g_variant_get_uint64 +g_variant_get_handle +g_variant_get_double +g_variant_get_string +g_variant_dup_string +g_variant_get_variant +g_variant_get_strv +g_variant_dup_strv +g_variant_get_objv +g_variant_dup_objv +g_variant_get_bytestring +g_variant_dup_bytestring +g_variant_get_bytestring_array +g_variant_dup_bytestring_array +g_variant_new_maybe +g_variant_new_array +g_variant_new_tuple +g_variant_new_dict_entry +g_variant_get_maybe +g_variant_get_fixed_array +g_variant_print +g_variant_print_string +g_variant_hash +g_variant_equal +g_variant_iter_copy +g_variant_iter_free +g_variant_iter_init +g_variant_iter_n_children +g_variant_iter_new +g_variant_iter_next_value +g_variant_builder_add_value +g_variant_builder_init +g_variant_builder_clear +g_variant_builder_open +g_variant_builder_close +g_variant_builder_end +g_variant_builder_new +g_variant_builder_unref +g_variant_builder_ref +g_variant_new_va +g_variant_get_va +g_variant_new +g_variant_get +g_variant_builder_add +g_variant_get_child +g_variant_lookup_value +g_variant_lookup +g_variant_iter_next +g_variant_iter_loop +g_variant_new_from_data +g_variant_get_normal_form +g_variant_byteswap +g_variant_new_parsed +g_variant_new_parsed_va +g_variant_builder_add_parsed +g_variant_parse +g_variant_parser_get_error_quark +g_variant_type_info_get_type_string +g_variant_type_info_query +g_variant_type_info_element +g_variant_type_info_query_element +g_variant_type_info_n_members +g_variant_type_info_member_info +g_variant_type_info_get +g_variant_type_info_ref +g_variant_type_info_unref +g_variant_type_info_assert_no_infos +g_variant_serialised_byteswap +g_variant_serialised_get_child +g_variant_serialised_is_normal +g_variant_serialised_n_children +g_variant_serialiser_is_object_path +g_variant_serialiser_is_signature +g_variant_serialiser_is_string +g_variant_serialiser_needed_size +g_variant_serialiser_serialise +g_variant_format_string_scan_type +g_variant_format_string_scan +#ifdef G_OS_WIN32 +g_win32_error_message +g_win32_ftruncate +g_win32_get_package_installation_directory_of_module +#ifndef _WIN64 +g_win32_get_package_installation_directory PRIVATE +#endif +g_win32_get_package_installation_directory_utf8 +#ifndef _WIN64 +g_win32_get_package_installation_subdirectory PRIVATE +#endif +g_win32_get_package_installation_subdirectory_utf8 +g_win32_get_windows_version +g_win32_getlocale +g_win32_locale_filename_from_utf8 +#endif +g_hostname_is_non_ascii +g_hostname_is_ascii_encoded +g_hostname_is_ip_address +g_hostname_to_ascii +g_hostname_to_unicode +#ifdef G_OS_UNIX +g_unix_error_quark +g_unix_open_pipe +g_unix_set_fd_nonblocking +g_unix_signal_add +g_unix_signal_add_full +g_unix_signal_source_new +#endif +g_ascii_table +g_utf8_skip +g_idle_funcs +g_timeout_funcs +g_io_watch_funcs +g_child_watch_funcs +glib_binary_age +glib_interface_age +glib_major_version +glib_mem_profiler_table +glib_micro_version +glib_minor_version +glib_on_error_halt +g_mem_gc_friendly +g_cond_broadcast +g_cond_clear +g_cond_free +g_cond_init +g_cond_new +g_cond_signal +g_cond_timed_wait +g_cond_wait +g_cond_wait_until +g_mutex_clear +g_mutex_free +g_mutex_init +g_mutex_lock +g_mutex_new +g_mutex_trylock +g_mutex_unlock +g_private_new +g_private_get +g_private_replace +g_private_set +g_rw_lock_clear +g_rw_lock_init +g_rw_lock_reader_lock +g_rw_lock_reader_trylock +g_rw_lock_reader_unlock +g_rw_lock_writer_lock +g_rw_lock_writer_trylock +g_rw_lock_writer_unlock +g_rec_mutex_clear +g_rec_mutex_init +g_rec_mutex_lock +g_rec_mutex_trylock +g_rec_mutex_unlock diff --git a/glib/glib/glib_trace.h b/glib/glib/glib_trace.h new file mode 100644 index 0000000..789e88d --- /dev/null +++ b/glib/glib/glib_trace.h @@ -0,0 +1,43 @@ +/* GLIB - Library of useful routines for C programming + * + * Copyright (C) 2009,2010 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alexander Larsson + */ + +#ifndef __GLIBTRACE_H__ +#define __GLIBTRACE_H__ + +#ifndef SIZEOF_CHAR +#error "config.h must be included prior to glib_trace.h" +#endif + +#ifdef HAVE_DTRACE + +/* include the generated probes header and put markers in code */ +#include "glib_probes.h" +#define TRACE(probe) probe + +#else + +/* Wrap the probe to allow it to be removed when no systemtap available */ +#define TRACE(probe) + +#endif + +#endif /* __GLIBTRACE_H__ */ diff --git a/glib/glib/glibintl.h b/glib/glib/glibintl.h new file mode 100644 index 0000000..507e1c3 --- /dev/null +++ b/glib/glib/glibintl.h @@ -0,0 +1,42 @@ +#ifndef __GLIBINTL_H__ +#define __GLIBINTL_H__ + +#ifndef SIZEOF_CHAR +#error "config.h must be included prior to glibintl.h" +#endif + +const gchar * glib_gettext (const gchar *str) G_GNUC_FORMAT(1); +const gchar * glib_pgettext (const gchar *msgctxtid, + gsize msgidoffset) G_GNUC_FORMAT(1); + +#ifdef ENABLE_NLS + +#include +#define _(String) glib_gettext(String) +/* Split out this in the code, but keep it in the same domain for now */ +#define P_(String) glib_gettext(String) +#define C_(Context,String) glib_pgettext (Context "\004" String, strlen (Context) + 1) + +#ifdef gettext_noop +#define N_(String) gettext_noop(String) +#else +#define N_(String) (String) +#endif +#else /* NLS is disabled */ +#define _(String) (String) +#define N_(String) (String) +#define P_(String) (String) +#define C_(Context,String) (String) +#define textdomain(String) ((String) ? (String) : "messages") +#define gettext(String) (String) +#define dgettext(Domain,String) (String) +#define dcgettext(Domain,String,Type) (String) +#define dngettext(Domain,String1,String2,N) ((N) == 1 ? (String1) : (String2)) +#define bindtextdomain(Domain,Directory) (Domain) +#define bind_textdomain_codeset(Domain,Codeset) +#endif + +/* not really I18N-related, but also a string marker macro */ +#define I_(string) g_intern_static_string (string) + +#endif /* __GLIBINTL_H__ */ diff --git a/glib/glib/glist.c b/glib/glib/glist.c new file mode 100644 index 0000000..dac7dc8 --- /dev/null +++ b/glib/glib/glist.c @@ -0,0 +1,1133 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "glist.h" +#include "gslice.h" + +#include "gtestutils.h" + +/** + * SECTION:linked_lists_double + * @title: Doubly-Linked Lists + * @short_description: linked lists that can be iterated over in both directions + * + * The #GList structure and its associated functions provide a standard + * doubly-linked list data structure. + * + * Each element in the list contains a piece of data, together with + * pointers which link to the previous and next elements in the list. + * Using these pointers it is possible to move through the list in both + * directions (unlike the Singly-Linked Lists which + * only allows movement through the list in the forward direction). + * + * The data contained in each element can be either integer values, by + * using one of the Type + * Conversion Macros, or simply pointers to any type of data. + * + * List elements are allocated from the slice allocator, which is more + * efficient than allocating elements individually. + * + * Note that most of the #GList functions expect to be passed a pointer + * to the first element in the list. The functions which insert + * elements return the new start of the list, which may have changed. + * + * There is no function to create a #GList. %NULL is considered to be + * the empty list so you simply set a #GList* to %NULL. + * + * To add elements, use g_list_append(), g_list_prepend(), + * g_list_insert() and g_list_insert_sorted(). + * + * To remove elements, use g_list_remove(). + * + * To find elements in the list use g_list_first(), g_list_last(), + * g_list_next(), g_list_previous(), g_list_nth(), g_list_nth_data(), + * g_list_find() and g_list_find_custom(). + * + * To find the index of an element use g_list_position() and + * g_list_index(). + * + * To call a function for each element in the list use g_list_foreach(). + * + * To free the entire list, use g_list_free(). + **/ + +/** + * GList: + * @data: holds the element's data, which can be a pointer to any kind + * of data, or any integer value using the Type Conversion + * Macros. + * @next: contains the link to the next element in the list. + * @prev: contains the link to the previous element in the list. + * + * The #GList struct is used for each element in a doubly-linked list. + **/ + +/** + * g_list_previous: + * @list: an element in a #GList. + * @Returns: the previous element, or %NULL if there are no previous + * elements. + * + * A convenience macro to get the previous element in a #GList. + **/ + +/** + * g_list_next: + * @list: an element in a #GList. + * @Returns: the next element, or %NULL if there are no more elements. + * + * A convenience macro to get the next element in a #GList. + **/ + +#define _g_list_alloc() g_slice_new (GList) +#define _g_list_alloc0() g_slice_new0 (GList) +#define _g_list_free1(list) g_slice_free (GList, list) + +/** + * g_list_alloc: + * @Returns: a pointer to the newly-allocated #GList element. + * + * Allocates space for one #GList element. It is called by + * g_list_append(), g_list_prepend(), g_list_insert() and + * g_list_insert_sorted() and so is rarely used on its own. + **/ +GList* +g_list_alloc (void) +{ + return _g_list_alloc0 (); +} + +/** + * g_list_free: + * @list: a #GList + * + * Frees all of the memory used by a #GList. + * The freed elements are returned to the slice allocator. + * + * + * If list elements contain dynamically-allocated memory, + * you should either use g_list_free_full() or free them manually + * first. + * + */ +void +g_list_free (GList *list) +{ + g_slice_free_chain (GList, list, next); +} + +/** + * g_list_free_1: + * @list: a #GList element + * + * Frees one #GList element. + * It is usually used after g_list_remove_link(). + */ +/** + * g_list_free1: + * + * Another name for g_list_free_1(). + **/ +void +g_list_free_1 (GList *list) +{ + _g_list_free1 (list); +} + +/** + * g_list_free_full: + * @list: a pointer to a #GList + * @free_func: the function to be called to free each element's data + * + * Convenience method, which frees all the memory used by a #GList, and + * calls the specified destroy function on every element's data. + * + * Since: 2.28 + */ +void +g_list_free_full (GList *list, + GDestroyNotify free_func) +{ + g_list_foreach (list, (GFunc) free_func, NULL); + g_list_free (list); +} + +/** + * g_list_append: + * @list: a pointer to a #GList + * @data: the data for the new element + * + * Adds a new element on to the end of the list. + * + * + * The return value is the new start of the list, which + * may have changed, so make sure you store the new value. + * + * + * + * Note that g_list_append() has to traverse the entire list + * to find the end, which is inefficient when adding multiple + * elements. A common idiom to avoid the inefficiency is to prepend + * the elements and reverse the list when all elements have been added. + * + * + * |[ + * /* Notice that these are initialized to the empty list. */ + * GList *list = NULL, *number_list = NULL; + * + * /* This is a list of strings. */ + * list = g_list_append (list, "first"); + * list = g_list_append (list, "second"); + * + * /* This is a list of integers. */ + * number_list = g_list_append (number_list, GINT_TO_POINTER (27)); + * number_list = g_list_append (number_list, GINT_TO_POINTER (14)); + * ]| + * + * Returns: the new start of the #GList + */ +GList* +g_list_append (GList *list, + gpointer data) +{ + GList *new_list; + GList *last; + + new_list = _g_list_alloc (); + new_list->data = data; + new_list->next = NULL; + + if (list) + { + last = g_list_last (list); + /* g_assert (last != NULL); */ + last->next = new_list; + new_list->prev = last; + + return list; + } + else + { + new_list->prev = NULL; + return new_list; + } +} + +/** + * g_list_prepend: + * @list: a pointer to a #GList + * @data: the data for the new element + * + * Adds a new element on to the start of the list. + * + * + * The return value is the new start of the list, which + * may have changed, so make sure you store the new value. + * + * + * |[ + * /* Notice that it is initialized to the empty list. */ + * GList *list = NULL; + * list = g_list_prepend (list, "last"); + * list = g_list_prepend (list, "first"); + * ]| + * + * Returns: the new start of the #GList + */ +GList* +g_list_prepend (GList *list, + gpointer data) +{ + GList *new_list; + + new_list = _g_list_alloc (); + new_list->data = data; + new_list->next = list; + + if (list) + { + new_list->prev = list->prev; + if (list->prev) + list->prev->next = new_list; + list->prev = new_list; + } + else + new_list->prev = NULL; + + return new_list; +} + +/** + * g_list_insert: + * @list: a pointer to a #GList + * @data: the data for the new element + * @position: the position to insert the element. If this is + * negative, or is larger than the number of elements in the + * list, the new element is added on to the end of the list. + * + * Inserts a new element into the list at the given position. + * + * Returns: the new start of the #GList + */ +GList* +g_list_insert (GList *list, + gpointer data, + gint position) +{ + GList *new_list; + GList *tmp_list; + + if (position < 0) + return g_list_append (list, data); + else if (position == 0) + return g_list_prepend (list, data); + + tmp_list = g_list_nth (list, position); + if (!tmp_list) + return g_list_append (list, data); + + new_list = _g_list_alloc (); + new_list->data = data; + new_list->prev = tmp_list->prev; + tmp_list->prev->next = new_list; + new_list->next = tmp_list; + tmp_list->prev = new_list; + + return list; +} + +/** + * g_list_insert_before: + * @list: a pointer to a #GList + * @sibling: the list element before which the new element + * is inserted or %NULL to insert at the end of the list + * @data: the data for the new element + * + * Inserts a new element into the list before the given position. + * + * Returns: the new start of the #GList + */ +GList* +g_list_insert_before (GList *list, + GList *sibling, + gpointer data) +{ + if (!list) + { + list = g_list_alloc (); + list->data = data; + g_return_val_if_fail (sibling == NULL, list); + return list; + } + else if (sibling) + { + GList *node; + + node = _g_list_alloc (); + node->data = data; + node->prev = sibling->prev; + node->next = sibling; + sibling->prev = node; + if (node->prev) + { + node->prev->next = node; + return list; + } + else + { + g_return_val_if_fail (sibling == list, node); + return node; + } + } + else + { + GList *last; + + last = list; + while (last->next) + last = last->next; + + last->next = _g_list_alloc (); + last->next->data = data; + last->next->prev = last; + last->next->next = NULL; + + return list; + } +} + +/** + * g_list_concat: + * @list1: a #GList + * @list2: the #GList to add to the end of the first #GList + * + * Adds the second #GList onto the end of the first #GList. + * Note that the elements of the second #GList are not copied. + * They are used directly. + * + * Returns: the start of the new #GList + */ +GList * +g_list_concat (GList *list1, GList *list2) +{ + GList *tmp_list; + + if (list2) + { + tmp_list = g_list_last (list1); + if (tmp_list) + tmp_list->next = list2; + else + list1 = list2; + list2->prev = tmp_list; + } + + return list1; +} + +/** + * g_list_remove: + * @list: a #GList + * @data: the data of the element to remove + * + * Removes an element from a #GList. + * If two elements contain the same data, only the first is removed. + * If none of the elements contain the data, the #GList is unchanged. + * + * Returns: the new start of the #GList + */ +GList* +g_list_remove (GList *list, + gconstpointer data) +{ + GList *tmp; + + tmp = list; + while (tmp) + { + if (tmp->data != data) + tmp = tmp->next; + else + { + if (tmp->prev) + tmp->prev->next = tmp->next; + if (tmp->next) + tmp->next->prev = tmp->prev; + + if (list == tmp) + list = list->next; + + _g_list_free1 (tmp); + + break; + } + } + return list; +} + +/** + * g_list_remove_all: + * @list: a #GList + * @data: data to remove + * + * Removes all list nodes with data equal to @data. + * Returns the new head of the list. Contrast with + * g_list_remove() which removes only the first node + * matching the given data. + * + * Returns: new head of @list + */ +GList* +g_list_remove_all (GList *list, + gconstpointer data) +{ + GList *tmp = list; + + while (tmp) + { + if (tmp->data != data) + tmp = tmp->next; + else + { + GList *next = tmp->next; + + if (tmp->prev) + tmp->prev->next = next; + else + list = next; + if (next) + next->prev = tmp->prev; + + _g_list_free1 (tmp); + tmp = next; + } + } + return list; +} + +static inline GList* +_g_list_remove_link (GList *list, + GList *link) +{ + if (link) + { + if (link->prev) + link->prev->next = link->next; + if (link->next) + link->next->prev = link->prev; + + if (link == list) + list = list->next; + + link->next = NULL; + link->prev = NULL; + } + + return list; +} + +/** + * g_list_remove_link: + * @list: a #GList + * @llink: an element in the #GList + * + * Removes an element from a #GList, without freeing the element. + * The removed element's prev and next links are set to %NULL, so + * that it becomes a self-contained list with one element. + * + * Returns: the new start of the #GList, without the element + */ +GList* +g_list_remove_link (GList *list, + GList *llink) +{ + return _g_list_remove_link (list, llink); +} + +/** + * g_list_delete_link: + * @list: a #GList + * @link_: node to delete from @list + * + * Removes the node link_ from the list and frees it. + * Compare this to g_list_remove_link() which removes the node + * without freeing it. + * + * Returns: the new head of @list + */ +GList* +g_list_delete_link (GList *list, + GList *link_) +{ + list = _g_list_remove_link (list, link_); + _g_list_free1 (link_); + + return list; +} + +/** + * g_list_copy: + * @list: a #GList + * + * Copies a #GList. + * + * + * Note that this is a "shallow" copy. If the list elements + * consist of pointers to data, the pointers are copied but + * the actual data is not. + * + * + * Returns: a copy of @list + */ +GList* +g_list_copy (GList *list) +{ + GList *new_list = NULL; + + if (list) + { + GList *last; + + new_list = _g_list_alloc (); + new_list->data = list->data; + new_list->prev = NULL; + last = new_list; + list = list->next; + while (list) + { + last->next = _g_list_alloc (); + last->next->prev = last; + last = last->next; + last->data = list->data; + list = list->next; + } + last->next = NULL; + } + + return new_list; +} + +/** + * g_list_reverse: + * @list: a #GList + * + * Reverses a #GList. + * It simply switches the next and prev pointers of each element. + * + * Returns: the start of the reversed #GList + */ +GList* +g_list_reverse (GList *list) +{ + GList *last; + + last = NULL; + while (list) + { + last = list; + list = last->next; + last->next = last->prev; + last->prev = list; + } + + return last; +} + +/** + * g_list_nth: + * @list: a #GList + * @n: the position of the element, counting from 0 + * + * Gets the element at the given position in a #GList. + * + * Returns: the element, or %NULL if the position is off + * the end of the #GList + */ +GList* +g_list_nth (GList *list, + guint n) +{ + while ((n-- > 0) && list) + list = list->next; + + return list; +} + +/** + * g_list_nth_prev: + * @list: a #GList + * @n: the position of the element, counting from 0 + * + * Gets the element @n places before @list. + * + * Returns: the element, or %NULL if the position is + * off the end of the #GList + */ +GList* +g_list_nth_prev (GList *list, + guint n) +{ + while ((n-- > 0) && list) + list = list->prev; + + return list; +} + +/** + * g_list_nth_data: + * @list: a #GList + * @n: the position of the element + * + * Gets the data of the element at the given position. + * + * Returns: the element's data, or %NULL if the position + * is off the end of the #GList + */ +gpointer +g_list_nth_data (GList *list, + guint n) +{ + while ((n-- > 0) && list) + list = list->next; + + return list ? list->data : NULL; +} + +/** + * g_list_find: + * @list: a #GList + * @data: the element data to find + * + * Finds the element in a #GList which + * contains the given data. + * + * Returns: the found #GList element, + * or %NULL if it is not found + */ +GList* +g_list_find (GList *list, + gconstpointer data) +{ + while (list) + { + if (list->data == data) + break; + list = list->next; + } + + return list; +} + +/** + * g_list_find_custom: + * @list: a #GList + * @data: user data passed to the function + * @func: the function to call for each element. + * It should return 0 when the desired element is found + * + * Finds an element in a #GList, using a supplied function to + * find the desired element. It iterates over the list, calling + * the given function which should return 0 when the desired + * element is found. The function takes two #gconstpointer arguments, + * the #GList element's data as the first argument and the + * given user data. + * + * Returns: the found #GList element, or %NULL if it is not found + */ +GList* +g_list_find_custom (GList *list, + gconstpointer data, + GCompareFunc func) +{ + g_return_val_if_fail (func != NULL, list); + + while (list) + { + if (! func (list->data, data)) + return list; + list = list->next; + } + + return NULL; +} + + +/** + * g_list_position: + * @list: a #GList + * @llink: an element in the #GList + * + * Gets the position of the given element + * in the #GList (starting from 0). + * + * Returns: the position of the element in the #GList, + * or -1 if the element is not found + */ +gint +g_list_position (GList *list, + GList *llink) +{ + gint i; + + i = 0; + while (list) + { + if (list == llink) + return i; + i++; + list = list->next; + } + + return -1; +} + +/** + * g_list_index: + * @list: a #GList + * @data: the data to find + * + * Gets the position of the element containing + * the given data (starting from 0). + * + * Returns: the index of the element containing the data, + * or -1 if the data is not found + */ +gint +g_list_index (GList *list, + gconstpointer data) +{ + gint i; + + i = 0; + while (list) + { + if (list->data == data) + return i; + i++; + list = list->next; + } + + return -1; +} + +/** + * g_list_last: + * @list: a #GList + * + * Gets the last element in a #GList. + * + * Returns: the last element in the #GList, + * or %NULL if the #GList has no elements + */ +GList* +g_list_last (GList *list) +{ + if (list) + { + while (list->next) + list = list->next; + } + + return list; +} + +/** + * g_list_first: + * @list: a #GList + * + * Gets the first element in a #GList. + * + * Returns: the first element in the #GList, + * or %NULL if the #GList has no elements + */ +GList* +g_list_first (GList *list) +{ + if (list) + { + while (list->prev) + list = list->prev; + } + + return list; +} + +/** + * g_list_length: + * @list: a #GList + * + * Gets the number of elements in a #GList. + * + * + * This function iterates over the whole list to + * count its elements. + * + * + * Returns: the number of elements in the #GList + */ +guint +g_list_length (GList *list) +{ + guint length; + + length = 0; + while (list) + { + length++; + list = list->next; + } + + return length; +} + +/** + * g_list_foreach: + * @list: a #GList + * @func: the function to call with each element's data + * @user_data: user data to pass to the function + * + * Calls a function for each element of a #GList. + */ +/** + * GFunc: + * @data: the element's data. + * @user_data: user data passed to g_list_foreach() or + * g_slist_foreach(). + * + * Specifies the type of functions passed to g_list_foreach() and + * g_slist_foreach(). + **/ +void +g_list_foreach (GList *list, + GFunc func, + gpointer user_data) +{ + while (list) + { + GList *next = list->next; + (*func) (list->data, user_data); + list = next; + } +} + +static GList* +g_list_insert_sorted_real (GList *list, + gpointer data, + GFunc func, + gpointer user_data) +{ + GList *tmp_list = list; + GList *new_list; + gint cmp; + + g_return_val_if_fail (func != NULL, list); + + if (!list) + { + new_list = _g_list_alloc0 (); + new_list->data = data; + return new_list; + } + + cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); + + while ((tmp_list->next) && (cmp > 0)) + { + tmp_list = tmp_list->next; + + cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); + } + + new_list = _g_list_alloc0 (); + new_list->data = data; + + if ((!tmp_list->next) && (cmp > 0)) + { + tmp_list->next = new_list; + new_list->prev = tmp_list; + return list; + } + + if (tmp_list->prev) + { + tmp_list->prev->next = new_list; + new_list->prev = tmp_list->prev; + } + new_list->next = tmp_list; + tmp_list->prev = new_list; + + if (tmp_list == list) + return new_list; + else + return list; +} + +/** + * g_list_insert_sorted: + * @list: a pointer to a #GList + * @data: the data for the new element + * @func: the function to compare elements in the list. It should + * return a number > 0 if the first parameter comes after the + * second parameter in the sort order. + * + * Inserts a new element into the list, using the given comparison + * function to determine its position. + * + * Returns: the new start of the #GList + */ +GList* +g_list_insert_sorted (GList *list, + gpointer data, + GCompareFunc func) +{ + return g_list_insert_sorted_real (list, data, (GFunc) func, NULL); +} + +/** + * g_list_insert_sorted_with_data: + * @list: a pointer to a #GList + * @data: the data for the new element + * @func: the function to compare elements in the list. + * It should return a number > 0 if the first parameter + * comes after the second parameter in the sort order. + * @user_data: user data to pass to comparison function. + * + * Inserts a new element into the list, using the given comparison + * function to determine its position. + * + * Returns: the new start of the #GList + * + * Since: 2.10 + */ +GList* +g_list_insert_sorted_with_data (GList *list, + gpointer data, + GCompareDataFunc func, + gpointer user_data) +{ + return g_list_insert_sorted_real (list, data, (GFunc) func, user_data); +} + +static GList * +g_list_sort_merge (GList *l1, + GList *l2, + GFunc compare_func, + gpointer user_data) +{ + GList list, *l, *lprev; + gint cmp; + + l = &list; + lprev = NULL; + + while (l1 && l2) + { + cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data); + + if (cmp <= 0) + { + l->next = l1; + l1 = l1->next; + } + else + { + l->next = l2; + l2 = l2->next; + } + l = l->next; + l->prev = lprev; + lprev = l; + } + l->next = l1 ? l1 : l2; + l->next->prev = l; + + return list.next; +} + +static GList* +g_list_sort_real (GList *list, + GFunc compare_func, + gpointer user_data) +{ + GList *l1, *l2; + + if (!list) + return NULL; + if (!list->next) + return list; + + l1 = list; + l2 = list->next; + + while ((l2 = l2->next) != NULL) + { + if ((l2 = l2->next) == NULL) + break; + l1 = l1->next; + } + l2 = l1->next; + l1->next = NULL; + + return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data), + g_list_sort_real (l2, compare_func, user_data), + compare_func, + user_data); +} + +/** + * g_list_sort: + * @list: a #GList + * @compare_func: the comparison function used to sort the #GList. + * This function is passed the data from 2 elements of the #GList + * and should return 0 if they are equal, a negative value if the + * first element comes before the second, or a positive value if + * the first element comes after the second. + * + * Sorts a #GList using the given comparison function. The algorithm + * used is a stable sort. + * + * Returns: the start of the sorted #GList + */ +/** + * GCompareFunc: + * @a: a value. + * @b: a value to compare with. + * @Returns: negative value if @a < @b; zero if @a = @b; positive + * value if @a > @b. + * + * Specifies the type of a comparison function used to compare two + * values. The function should return a negative integer if the first + * value comes before the second, 0 if they are equal, or a positive + * integer if the first value comes after the second. + **/ +GList * +g_list_sort (GList *list, + GCompareFunc compare_func) +{ + return g_list_sort_real (list, (GFunc) compare_func, NULL); + +} + +/** + * g_list_sort_with_data: + * @list: a #GList + * @compare_func: comparison function + * @user_data: user data to pass to comparison function + * + * Like g_list_sort(), but the comparison function accepts + * a user data argument. + * + * Returns: the new head of @list + */ +/** + * GCompareDataFunc: + * @a: a value. + * @b: a value to compare with. + * @user_data: user data to pass to comparison function. + * @Returns: negative value if @a < @b; zero if @a = @b; positive + * value if @a > @b. + * + * Specifies the type of a comparison function used to compare two + * values. The function should return a negative integer if the first + * value comes before the second, 0 if they are equal, or a positive + * integer if the first value comes after the second. + **/ +GList * +g_list_sort_with_data (GList *list, + GCompareDataFunc compare_func, + gpointer user_data) +{ + return g_list_sort_real (list, (GFunc) compare_func, user_data); +} diff --git a/glib/glib/glist.h b/glib/glib/glist.h new file mode 100644 index 0000000..aaa11f2 --- /dev/null +++ b/glib/glib/glist.h @@ -0,0 +1,117 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_LIST_H__ +#define __G_LIST_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GList GList; + +struct _GList +{ + gpointer data; + GList *next; + GList *prev; +}; + +/* Doubly linked lists + */ +GList* g_list_alloc (void) G_GNUC_WARN_UNUSED_RESULT; +void g_list_free (GList *list); +void g_list_free_1 (GList *list); +#define g_list_free1 g_list_free_1 +void g_list_free_full (GList *list, + GDestroyNotify free_func); +GList* g_list_append (GList *list, + gpointer data) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_prepend (GList *list, + gpointer data) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_insert (GList *list, + gpointer data, + gint position) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_insert_sorted (GList *list, + gpointer data, + GCompareFunc func) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_insert_sorted_with_data (GList *list, + gpointer data, + GCompareDataFunc func, + gpointer user_data) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_insert_before (GList *list, + GList *sibling, + gpointer data) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_concat (GList *list1, + GList *list2) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_remove (GList *list, + gconstpointer data) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_remove_all (GList *list, + gconstpointer data) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_remove_link (GList *list, + GList *llink) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_delete_link (GList *list, + GList *link_) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_reverse (GList *list) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_copy (GList *list) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_nth (GList *list, + guint n); +GList* g_list_nth_prev (GList *list, + guint n); +GList* g_list_find (GList *list, + gconstpointer data); +GList* g_list_find_custom (GList *list, + gconstpointer data, + GCompareFunc func); +gint g_list_position (GList *list, + GList *llink); +gint g_list_index (GList *list, + gconstpointer data); +GList* g_list_last (GList *list); +GList* g_list_first (GList *list); +guint g_list_length (GList *list); +void g_list_foreach (GList *list, + GFunc func, + gpointer user_data); +GList* g_list_sort (GList *list, + GCompareFunc compare_func) G_GNUC_WARN_UNUSED_RESULT; +GList* g_list_sort_with_data (GList *list, + GCompareDataFunc compare_func, + gpointer user_data) G_GNUC_WARN_UNUSED_RESULT; +gpointer g_list_nth_data (GList *list, + guint n); + + +#define g_list_previous(list) ((list) ? (((GList *)(list))->prev) : NULL) +#define g_list_next(list) ((list) ? (((GList *)(list))->next) : NULL) + +G_END_DECLS + +#endif /* __G_LIST_H__ */ diff --git a/glib/glib/gmacros.h b/glib/glib/gmacros.h new file mode 100644 index 0000000..4ad57da --- /dev/null +++ b/glib/glib/gmacros.h @@ -0,0 +1,343 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* This file must not include any other glib header file and must thus + * not refer to variables from glibconfig.h + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_MACROS_H__ +#define __G_MACROS_H__ + +/* We include stddef.h to get the system's definition of NULL + */ +#include + +/* Here we provide G_GNUC_EXTENSION as an alias for __extension__, + * where this is valid. This allows for warningless compilation of + * "long long" types even in the presence of '-ansi -pedantic'. + */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) +# define G_GNUC_EXTENSION __extension__ +#else +# define G_GNUC_EXTENSION +#endif + +/* Provide macros to feature the GCC function attribute. + */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +#define G_GNUC_PURE \ + __attribute__((__pure__)) +#define G_GNUC_MALLOC \ + __attribute__((__malloc__)) +#else +#define G_GNUC_PURE +#define G_GNUC_MALLOC +#endif + +#if __GNUC__ >= 4 +#define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__)) +#else +#define G_GNUC_NULL_TERMINATED +#endif + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +#define G_GNUC_ALLOC_SIZE(x) __attribute__((__alloc_size__(x))) +#define G_GNUC_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y))) +#else +#define G_GNUC_ALLOC_SIZE(x) +#define G_GNUC_ALLOC_SIZE2(x,y) +#endif + +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4) +#define G_GNUC_PRINTF( format_idx, arg_idx ) \ + __attribute__((__format__ (__printf__, format_idx, arg_idx))) +#define G_GNUC_SCANF( format_idx, arg_idx ) \ + __attribute__((__format__ (__scanf__, format_idx, arg_idx))) +#define G_GNUC_FORMAT( arg_idx ) \ + __attribute__((__format_arg__ (arg_idx))) +#define G_GNUC_NORETURN \ + __attribute__((__noreturn__)) +#define G_GNUC_CONST \ + __attribute__((__const__)) +#define G_GNUC_UNUSED \ + __attribute__((__unused__)) +#define G_GNUC_NO_INSTRUMENT \ + __attribute__((__no_instrument_function__)) +#else /* !__GNUC__ */ +#define G_GNUC_PRINTF( format_idx, arg_idx ) +#define G_GNUC_SCANF( format_idx, arg_idx ) +#define G_GNUC_FORMAT( arg_idx ) +#define G_GNUC_NORETURN +#define G_GNUC_CONST +#define G_GNUC_UNUSED +#define G_GNUC_NO_INSTRUMENT +#endif /* !__GNUC__ */ + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define G_GNUC_DEPRECATED \ + __attribute__((__deprecated__)) +#else +#define G_GNUC_DEPRECATED +#endif /* __GNUC__ */ + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define G_GNUC_DEPRECATED_FOR(f) \ + __attribute__((deprecated("Use " #f " instead"))) +#else +#define G_GNUC_DEPRECATED_FOR(f) G_GNUC_DEPRECATED +#endif /* __GNUC__ */ + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) +#define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wdeprecated-declarations\"") +#define G_GNUC_END_IGNORE_DEPRECATIONS \ + _Pragma ("GCC diagnostic pop") +#else +#define G_GNUC_BEGIN_IGNORE_DEPRECATIONS +#define G_GNUC_END_IGNORE_DEPRECATIONS +#endif + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) +# define G_GNUC_MAY_ALIAS __attribute__((may_alias)) +#else +# define G_GNUC_MAY_ALIAS +#endif + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) +#define G_GNUC_WARN_UNUSED_RESULT \ + __attribute__((warn_unused_result)) +#else +#define G_GNUC_WARN_UNUSED_RESULT +#endif /* __GNUC__ */ + +#ifndef G_DISABLE_DEPRECATED +/* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with + * macros, so we can refer to them as strings unconditionally. + * usage not-recommended since gcc-3.0 + */ +#if defined (__GNUC__) && (__GNUC__ < 3) +#define G_GNUC_FUNCTION __FUNCTION__ +#define G_GNUC_PRETTY_FUNCTION __PRETTY_FUNCTION__ +#else /* !__GNUC__ */ +#define G_GNUC_FUNCTION "" +#define G_GNUC_PRETTY_FUNCTION "" +#endif /* !__GNUC__ */ +#endif /* !G_DISABLE_DEPRECATED */ + +#define G_STRINGIFY(macro_or_string) G_STRINGIFY_ARG (macro_or_string) +#define G_STRINGIFY_ARG(contents) #contents + +#ifndef __GI_SCANNER__ /* The static assert macro really confuses the introspection parser */ +#define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2 +#define G_PASTE(identifier1,identifier2) G_PASTE_ARGS (identifier1, identifier2) +#ifdef __COUNTER__ +#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __COUNTER__)[(expr) ? 1 : -1] +#else +#define G_STATIC_ASSERT(expr) typedef char G_PASTE (_GStaticAssertCompileTimeAssertion_, __LINE__)[(expr) ? 1 : -1] +#endif +#define G_STATIC_ASSERT_EXPR(expr) ((void) sizeof (char[(expr) ? 1 : -1])) +#endif + +/* Provide a string identifying the current code position */ +#if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__cplusplus) +# define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__) ":" __PRETTY_FUNCTION__ "()" +#else +# define G_STRLOC __FILE__ ":" G_STRINGIFY (__LINE__) +#endif + +/* Provide a string identifying the current function, non-concatenatable */ +#if defined (__GNUC__) +# define G_STRFUNC ((const char*) (__PRETTY_FUNCTION__)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 19901L +# define G_STRFUNC ((const char*) (__func__)) +#elif defined(_MSC_VER) && (_MSC_VER > 1300) +# define G_STRFUNC ((const char*) (__FUNCTION__)) +#else +# define G_STRFUNC ((const char*) ("???")) +#endif + +/* Guard C code in headers, while including them from C++ */ +#ifdef __cplusplus +# define G_BEGIN_DECLS extern "C" { +# define G_END_DECLS } +#else +# define G_BEGIN_DECLS +# define G_END_DECLS +#endif + +/* Provide definitions for some commonly used macros. + * Some of them are only provided if they haven't already + * been defined. It is assumed that if they are already + * defined then the current definition is correct. + */ +#ifndef NULL +# ifdef __cplusplus +# define NULL (0L) +# else /* !__cplusplus */ +# define NULL ((void*) 0) +# endif /* !__cplusplus */ +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef TRUE +#define TRUE (!FALSE) +#endif + +#undef MAX +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + +#undef MIN +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) + +#undef ABS +#define ABS(a) (((a) < 0) ? -(a) : (a)) + +#undef CLAMP +#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) + +/* Count the number of elements in an array. The array must be defined + * as such; using this with a dynamically allocated array will give + * incorrect results. + */ +#define G_N_ELEMENTS(arr) (sizeof (arr) / sizeof ((arr)[0])) + +/* Macros by analogy to GINT_TO_POINTER, GPOINTER_TO_INT + */ +#define GPOINTER_TO_SIZE(p) ((gsize) (p)) +#define GSIZE_TO_POINTER(s) ((gpointer) (gsize) (s)) + +/* Provide convenience macros for handling structure + * fields through their offsets. + */ + +#if defined(__GNUC__) && __GNUC__ >= 4 +# define G_STRUCT_OFFSET(struct_type, member) \ + ((glong) offsetof (struct_type, member)) +#else +# define G_STRUCT_OFFSET(struct_type, member) \ + ((glong) ((guint8*) &((struct_type*) 0)->member)) +#endif + +#define G_STRUCT_MEMBER_P(struct_p, struct_offset) \ + ((gpointer) ((guint8*) (struct_p) + (glong) (struct_offset))) +#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset) \ + (*(member_type*) G_STRUCT_MEMBER_P ((struct_p), (struct_offset))) + +/* Provide simple macro statement wrappers: + * G_STMT_START { statements; } G_STMT_END; + * This can be used as a single statement, like: + * if (x) G_STMT_START { ... } G_STMT_END; else ... + * This intentionally does not use compiler extensions like GCC's '({...})' to + * avoid portability issue or side effects when compiled with different compilers. + */ +#if !(defined (G_STMT_START) && defined (G_STMT_END)) +# define G_STMT_START do +# define G_STMT_END while (0) +#endif + +/* Deprecated -- do not use. */ +#ifndef G_DISABLE_DEPRECATED +#ifdef G_DISABLE_CONST_RETURNS +#define G_CONST_RETURN +#else +#define G_CONST_RETURN const +#endif +#endif + +/* + * The G_LIKELY and G_UNLIKELY macros let the programmer give hints to + * the compiler about the expected result of an expression. Some compilers + * can use this information for optimizations. + * + * The _G_BOOLEAN_EXPR macro is intended to trigger a gcc warning when + * putting assignments in g_return_if_fail (). + */ +#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__) +#define _G_BOOLEAN_EXPR(expr) \ + G_GNUC_EXTENSION ({ \ + int _g_boolean_var_; \ + if (expr) \ + _g_boolean_var_ = 1; \ + else \ + _g_boolean_var_ = 0; \ + _g_boolean_var_; \ +}) +#define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 1)) +#define G_UNLIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 0)) +#else +#define G_LIKELY(expr) (expr) +#define G_UNLIKELY(expr) (expr) +#endif + +#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1) +#define G_DEPRECATED __attribute__((__deprecated__)) +#elif defined(_MSC_VER) && (_MSC_VER >= 1300) +#define G_DEPRECATED __declspec(deprecated) +#else +#define G_DEPRECATED +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define G_DEPRECATED_FOR(f) __attribute__((__deprecated__("Use '" #f "' instead"))) +#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) +#define G_DEPRECATED_FOR(f) __declspec(deprecated("is deprecated. Use '" #f "' instead")) +#else +#define G_DEPRECATED_FOR(f) G_DEPRECATED +#endif + +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#define G_UNAVAILABLE(maj,min) __attribute__((deprecated("Not available before " #maj "." #min))) +#elif defined(_MSC_FULL_VER) && (_MSC_FULL_VER > 140050320) +#define G_UNAVAILABLE(maj,min) __declspec(deprecated("is not available before " #maj "." #min)) +#else +#define G_UNAVAILABLE(maj,min) +#endif + +/* These macros are used to mark deprecated functions in GLib headers, + * and thus have to be exposed in installed headers. But please + * do *not* use them in other projects. Instead, use G_DEPRECATED + * or define your own wrappers around it. + */ + +#ifdef GLIB_DISABLE_DEPRECATION_WARNINGS +#define GLIB_DEPRECATED +#define GLIB_DEPRECATED_FOR(f) +#define GLIB_UNAVAILABLE(maj,min) +#else +#define GLIB_DEPRECATED G_DEPRECATED +#define GLIB_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f) +#define GLIB_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min) +#endif + +#endif /* __G_MACROS_H__ */ diff --git a/glib/glib/gmain-internal.h b/glib/glib/gmain-internal.h new file mode 100644 index 0000000..648aff3 --- /dev/null +++ b/glib/glib/gmain-internal.h @@ -0,0 +1,35 @@ +/* gmain-internal.h - GLib-internal mainloop API + * Copyright (C) 2011 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (GLIB_COMPILATION) +#error "This is a private header" +#endif + +#ifndef __G_MAIN_INTERNAL_H__ +#define __G_MAIN_INTERNAL_H__ + +#include "gmain.h" + +G_BEGIN_DECLS + +GSource *_g_main_create_unix_signal_watch (int signum); + +G_END_DECLS + +#endif /* __G_MAIN_H__ */ diff --git a/glib/glib/gmain.c b/glib/glib/gmain.c new file mode 100644 index 0000000..077a935 --- /dev/null +++ b/glib/glib/gmain.c @@ -0,0 +1,4891 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gmain.c: Main loop abstraction, timeouts, and idle functions + * Copyright 1998 Owen Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" +#include "glibconfig.h" + +/* Uncomment the next line (and the corresponding line in gpoll.c) to + * enable debugging printouts if the environment variable + * G_MAIN_POLL_DEBUG is set to some value. + */ +/* #define G_MAIN_POLL_DEBUG */ + +#ifdef _WIN32 +/* Always enable debugging printout on Windows, as it is more often + * needed there... + */ +#define G_MAIN_POLL_DEBUG +#endif + +#ifdef G_OS_UNIX +#include "glib-unix.h" +#include +#ifdef HAVE_EVENTFD +#include +#endif +#endif + +#include +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif /* HAVE_SYS_TIME_H */ +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#include +#include + +#ifdef G_OS_WIN32 +#define STRICT +#include +#endif /* G_OS_WIN32 */ + +#ifdef G_OS_BEOS +#include +#include +#endif /* G_OS_BEOS */ + +#include "gmain.h" + +#include "garray.h" +#include "giochannel.h" +#include "ghash.h" +#include "ghook.h" +#include "gqueue.h" +#include "gstrfuncs.h" +#include "gtestutils.h" + +#ifdef G_OS_WIN32 +#include "gwin32.h" +#endif + +#ifdef G_MAIN_POLL_DEBUG +#include "gtimer.h" +#endif + +#include "gwakeup.h" +#include "gmain-internal.h" +#include "glib-private.h" + +/** + * SECTION:main + * @title: The Main Event Loop + * @short_description: manages all available sources of events + * + * The main event loop manages all the available sources of events for + * GLib and GTK+ applications. These events can come from any number of + * different types of sources such as file descriptors (plain files, + * pipes or sockets) and timeouts. New types of event sources can also + * be added using g_source_attach(). + * + * To allow multiple independent sets of sources to be handled in + * different threads, each source is associated with a #GMainContext. + * A GMainContext can only be running in a single thread, but + * sources can be added to it and removed from it from other threads. + * + * Each event source is assigned a priority. The default priority, + * #G_PRIORITY_DEFAULT, is 0. Values less than 0 denote higher priorities. + * Values greater than 0 denote lower priorities. Events from high priority + * sources are always processed before events from lower priority sources. + * + * Idle functions can also be added, and assigned a priority. These will + * be run whenever no events with a higher priority are ready to be processed. + * + * The #GMainLoop data type represents a main event loop. A GMainLoop is + * created with g_main_loop_new(). After adding the initial event sources, + * g_main_loop_run() is called. This continuously checks for new events from + * each of the event sources and dispatches them. Finally, the processing of + * an event from one of the sources leads to a call to g_main_loop_quit() to + * exit the main loop, and g_main_loop_run() returns. + * + * It is possible to create new instances of #GMainLoop recursively. + * This is often used in GTK+ applications when showing modal dialog + * boxes. Note that event sources are associated with a particular + * #GMainContext, and will be checked and dispatched for all main + * loops associated with that GMainContext. + * + * GTK+ contains wrappers of some of these functions, e.g. gtk_main(), + * gtk_main_quit() and gtk_events_pending(). + * + * Creating new source types + * One of the unusual features of the #GMainLoop functionality + * is that new types of event source can be created and used in + * addition to the builtin type of event source. A new event source + * type is used for handling GDK events. A new source type is created + * by deriving from the #GSource structure. + * The derived type of source is represented by a structure that has + * the #GSource structure as a first element, and other elements specific + * to the new source type. To create an instance of the new source type, + * call g_source_new() passing in the size of the derived structure and + * a table of functions. These #GSourceFuncs determine the behavior of + * the new source type. + * New source types basically interact with the main context + * in two ways. Their prepare function in #GSourceFuncs can set a timeout + * to determine the maximum amount of time that the main loop will sleep + * before checking the source again. In addition, or as well, the source + * can add file descriptors to the set that the main context checks using + * g_source_add_poll(). + * + * Customizing the main loop iteration + * Single iterations of a #GMainContext can be run with + * g_main_context_iteration(). In some cases, more detailed control + * of exactly how the details of the main loop work is desired, for + * instance, when integrating the #GMainLoop with an external main loop. + * In such cases, you can call the component functions of + * g_main_context_iteration() directly. These functions are + * g_main_context_prepare(), g_main_context_query(), + * g_main_context_check() and g_main_context_dispatch(). + * The operation of these functions can best be seen in terms + * of a state diagram, as shown in . + *
States of a Main Context + * + *
+ *
+ * + * On Unix, the GLib mainloop is incompatible with fork(). Any program + * using the mainloop must either exec() or exit() from the child + * without returning to the mainloop. + */ + +/* Types */ + +typedef struct _GTimeoutSource GTimeoutSource; +typedef struct _GChildWatchSource GChildWatchSource; +typedef struct _GUnixSignalWatchSource GUnixSignalWatchSource; +typedef struct _GPollRec GPollRec; +typedef struct _GSourceCallback GSourceCallback; + +typedef enum +{ + G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT, + G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1) +} GSourceFlags; + +typedef struct _GMainWaiter GMainWaiter; + +struct _GMainWaiter +{ + GCond *cond; + GMutex *mutex; +}; + +typedef struct _GMainDispatch GMainDispatch; + +struct _GMainDispatch +{ + gint depth; + GSList *dispatching_sources; /* stack of current sources */ +}; + +#ifdef G_MAIN_POLL_DEBUG +gboolean _g_main_poll_debug = FALSE; +#endif + +struct _GMainContext +{ + /* The following lock is used for both the list of sources + * and the list of poll records + */ + GMutex mutex; + GCond cond; + GThread *owner; + guint owner_count; + GSList *waiters; + + gint ref_count; + + GPtrArray *pending_dispatches; + gint timeout; /* Timeout for current iteration */ + + guint next_id; + GSource *source_list; + gint in_check_or_prepare; + + GPollRec *poll_records, *poll_records_tail; + guint n_poll_records; + GPollFD *cached_poll_array; + guint cached_poll_array_size; + + GWakeup *wakeup; + + GPollFD wake_up_rec; + +/* Flag indicating whether the set of fd's changed during a poll */ + gboolean poll_changed; + + GPollFunc poll_func; + + gint64 time; + gboolean time_is_fresh; +}; + +struct _GSourceCallback +{ + guint ref_count; + GSourceFunc func; + gpointer data; + GDestroyNotify notify; +}; + +struct _GMainLoop +{ + GMainContext *context; + gboolean is_running; + gint ref_count; +}; + +struct _GTimeoutSource +{ + GSource source; + gint64 expiration; + guint interval; + gboolean seconds; +}; + +struct _GChildWatchSource +{ + GSource source; + GPid pid; + gint child_status; +#ifdef G_OS_WIN32 + GPollFD poll; +#else /* G_OS_WIN32 */ + gboolean child_exited; +#endif /* G_OS_WIN32 */ +}; + +struct _GUnixSignalWatchSource +{ + GSource source; + int signum; + gboolean pending; +}; + +struct _GPollRec +{ + GPollFD *fd; + GPollRec *prev; + GPollRec *next; + gint priority; +}; + +struct _GSourcePrivate +{ + GSList *child_sources; + GSource *parent_source; +}; + +#define LOCK_CONTEXT(context) g_mutex_lock (&context->mutex) +#define UNLOCK_CONTEXT(context) g_mutex_unlock (&context->mutex) +#define G_THREAD_SELF g_thread_self () + +#define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0) +#define SOURCE_BLOCKED(source) (((source)->flags & G_HOOK_FLAG_IN_CALL) != 0 && \ + ((source)->flags & G_SOURCE_CAN_RECURSE) == 0) + +#define SOURCE_UNREF(source, context) \ + G_STMT_START { \ + if ((source)->ref_count > 1) \ + (source)->ref_count--; \ + else \ + g_source_unref_internal ((source), (context), TRUE); \ + } G_STMT_END + + +/* Forward declarations */ + +static void g_source_unref_internal (GSource *source, + GMainContext *context, + gboolean have_lock); +static void g_source_destroy_internal (GSource *source, + GMainContext *context, + gboolean have_lock); +static void g_source_set_priority_unlocked (GSource *source, + GMainContext *context, + gint priority); +static void g_main_context_poll (GMainContext *context, + gint timeout, + gint priority, + GPollFD *fds, + gint n_fds); +static void g_main_context_add_poll_unlocked (GMainContext *context, + gint priority, + GPollFD *fd); +static void g_main_context_remove_poll_unlocked (GMainContext *context, + GPollFD *fd); + +static gboolean g_timeout_prepare (GSource *source, + gint *timeout); +static gboolean g_timeout_check (GSource *source); +static gboolean g_timeout_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data); +static gboolean g_child_watch_prepare (GSource *source, + gint *timeout); +static gboolean g_child_watch_check (GSource *source); +static gboolean g_child_watch_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data); +static void g_child_watch_finalize (GSource *source); +#ifdef G_OS_UNIX +static void g_unix_signal_handler (int signum); +static gboolean g_unix_signal_watch_prepare (GSource *source, + gint *timeout); +static gboolean g_unix_signal_watch_check (GSource *source); +static gboolean g_unix_signal_watch_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data); +static void g_unix_signal_watch_finalize (GSource *source); +#endif +static gboolean g_idle_prepare (GSource *source, + gint *timeout); +static gboolean g_idle_check (GSource *source); +static gboolean g_idle_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data); + +static GMainContext *glib_worker_context; + +G_LOCK_DEFINE_STATIC (main_loop); +static GMainContext *default_main_context; + +#ifndef G_OS_WIN32 + + +/* UNIX signals work by marking one of these variables then waking the + * worker context to check on them and dispatch accordingly. + */ +#ifdef HAVE_SIG_ATOMIC_T +static volatile sig_atomic_t unix_signal_pending[NSIG]; +static volatile sig_atomic_t any_unix_signal_pending; +#else +static volatile int unix_signal_pending[NSIG]; +static volatile int any_unix_signal_pending; +#endif + +/* Guards all the data below */ +G_LOCK_DEFINE_STATIC (unix_signal_lock); +static GSList *unix_signal_watches; +static GSList *unix_child_watches; + +static GSourceFuncs g_unix_signal_funcs = +{ + g_unix_signal_watch_prepare, + g_unix_signal_watch_check, + g_unix_signal_watch_dispatch, + g_unix_signal_watch_finalize +}; +#endif /* !G_OS_WIN32 */ +G_LOCK_DEFINE_STATIC (main_context_list); +static GSList *main_context_list = NULL; + +GSourceFuncs g_timeout_funcs = +{ + g_timeout_prepare, + g_timeout_check, + g_timeout_dispatch, + NULL +}; + +GSourceFuncs g_child_watch_funcs = +{ + g_child_watch_prepare, + g_child_watch_check, + g_child_watch_dispatch, + g_child_watch_finalize +}; + +GSourceFuncs g_idle_funcs = +{ + g_idle_prepare, + g_idle_check, + g_idle_dispatch, + NULL +}; + +/** + * g_main_context_ref: + * @context: a #GMainContext + * + * Increases the reference count on a #GMainContext object by one. + * + * Returns: the @context that was passed in (since 2.6) + **/ +GMainContext * +g_main_context_ref (GMainContext *context) +{ + g_return_val_if_fail (context != NULL, NULL); + g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL); + + g_atomic_int_inc (&context->ref_count); + + return context; +} + +static inline void +poll_rec_list_free (GMainContext *context, + GPollRec *list) +{ + g_slice_free_chain (GPollRec, list, next); +} + +/** + * g_main_context_unref: + * @context: a #GMainContext + * + * Decreases the reference count on a #GMainContext object by one. If + * the result is zero, free the context and free all associated memory. + **/ +void +g_main_context_unref (GMainContext *context) +{ + GSource *source; + g_return_if_fail (context != NULL); + g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); + + if (!g_atomic_int_dec_and_test (&context->ref_count)) + return; + + G_LOCK (main_context_list); + main_context_list = g_slist_remove (main_context_list, context); + G_UNLOCK (main_context_list); + + source = context->source_list; + while (source) + { + GSource *next = source->next; + g_source_destroy_internal (source, context, FALSE); + source = next; + } + + g_mutex_clear (&context->mutex); + + g_ptr_array_free (context->pending_dispatches, TRUE); + g_free (context->cached_poll_array); + + poll_rec_list_free (context, context->poll_records); + + g_wakeup_free (context->wakeup); + g_cond_clear (&context->cond); + + g_free (context); +} + +/** + * g_main_context_new: + * + * Creates a new #GMainContext structure. + * + * Return value: the new #GMainContext + **/ +GMainContext * +g_main_context_new (void) +{ + static gsize initialised; + GMainContext *context; + + if (g_once_init_enter (&initialised)) + { +#ifdef G_MAIN_POLL_DEBUG + if (getenv ("G_MAIN_POLL_DEBUG") != NULL) + _g_main_poll_debug = TRUE; +#endif + + g_once_init_leave (&initialised, TRUE); + } + + context = g_new0 (GMainContext, 1); + + g_mutex_init (&context->mutex); + g_cond_init (&context->cond); + + context->owner = NULL; + context->waiters = NULL; + + context->ref_count = 1; + + context->next_id = 1; + + context->source_list = NULL; + + context->poll_func = g_poll; + + context->cached_poll_array = NULL; + context->cached_poll_array_size = 0; + + context->pending_dispatches = g_ptr_array_new (); + + context->time_is_fresh = FALSE; + + context->wakeup = g_wakeup_new (); + g_wakeup_get_pollfd (context->wakeup, &context->wake_up_rec); + g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec); + + G_LOCK (main_context_list); + main_context_list = g_slist_append (main_context_list, context); + +#ifdef G_MAIN_POLL_DEBUG + if (_g_main_poll_debug) + g_print ("created context=%p\n", context); +#endif + + G_UNLOCK (main_context_list); + + return context; +} + +/** + * g_main_context_default: + * + * Returns the global default main context. This is the main context + * used for main loop functions when a main loop is not explicitly + * specified, and corresponds to the "main" main loop. See also + * g_main_context_get_thread_default(). + * + * Return value: (transfer none): the global default main context. + **/ +GMainContext * +g_main_context_default (void) +{ + /* Slow, but safe */ + + G_LOCK (main_loop); + + if (!default_main_context) + { + default_main_context = g_main_context_new (); +#ifdef G_MAIN_POLL_DEBUG + if (_g_main_poll_debug) + g_print ("default context=%p\n", default_main_context); +#endif + } + + G_UNLOCK (main_loop); + + return default_main_context; +} + +static void +free_context (gpointer data) +{ + GMainContext *context = data; + + g_main_context_release (context); + if (context) + g_main_context_unref (context); +} + +static void +free_context_stack (gpointer data) +{ + g_queue_free_full((GQueue *) data, (GDestroyNotify) free_context); +} + +static GPrivate thread_context_stack = G_PRIVATE_INIT (free_context_stack); + +/** + * g_main_context_push_thread_default: + * @context: a #GMainContext, or %NULL for the global default context + * + * Acquires @context and sets it as the thread-default context for the + * current thread. This will cause certain asynchronous operations + * (such as most gio-based I/O) which are + * started in this thread to run under @context and deliver their + * results to its main loop, rather than running under the global + * default context in the main thread. Note that calling this function + * changes the context returned by + * g_main_context_get_thread_default(), not the + * one returned by g_main_context_default(), so it does not affect the + * context used by functions like g_idle_add(). + * + * Normally you would call this function shortly after creating a new + * thread, passing it a #GMainContext which will be run by a + * #GMainLoop in that thread, to set a new default context for all + * async operations in that thread. (In this case, you don't need to + * ever call g_main_context_pop_thread_default().) In some cases + * however, you may want to schedule a single operation in a + * non-default context, or temporarily use a non-default context in + * the main thread. In that case, you can wrap the call to the + * asynchronous operation inside a + * g_main_context_push_thread_default() / + * g_main_context_pop_thread_default() pair, but it is up to you to + * ensure that no other asynchronous operations accidentally get + * started while the non-default context is active. + * + * Beware that libraries that predate this function may not correctly + * handle being used from a thread with a thread-default context. Eg, + * see g_file_supports_thread_contexts(). + * + * Since: 2.22 + **/ +void +g_main_context_push_thread_default (GMainContext *context) +{ + GQueue *stack; + gboolean acquired_context; + + acquired_context = g_main_context_acquire (context); + g_return_if_fail (acquired_context); + + if (context == g_main_context_default ()) + context = NULL; + else if (context) + g_main_context_ref (context); + + stack = g_private_get (&thread_context_stack); + if (!stack) + { + stack = g_queue_new (); + g_private_set (&thread_context_stack, stack); + } + + g_queue_push_head (stack, context); +} + +/** + * g_main_context_pop_thread_default: + * @context: a #GMainContext object, or %NULL + * + * Pops @context off the thread-default context stack (verifying that + * it was on the top of the stack). + * + * Since: 2.22 + **/ +void +g_main_context_pop_thread_default (GMainContext *context) +{ + GQueue *stack; + + if (context == g_main_context_default ()) + context = NULL; + + stack = g_private_get (&thread_context_stack); + + g_return_if_fail (stack != NULL); + g_return_if_fail (g_queue_peek_head (stack) == context); + + g_queue_pop_head (stack); + + g_main_context_release (context); + if (context) + g_main_context_unref (context); +} + +/** + * g_main_context_get_thread_default: + * + * Gets the thread-default #GMainContext for this thread. Asynchronous + * operations that want to be able to be run in contexts other than + * the default one should call this method or + * g_main_context_ref_thread_default() to get a #GMainContext to add + * their #GSources to. (Note that even in single-threaded + * programs applications may sometimes want to temporarily push a + * non-default context, so it is not safe to assume that this will + * always return %NULL if you are running in the default thread.) + * + * If you need to hold a reference on the context, use + * g_main_context_ref_thread_default() instead. + * + * Returns: (transfer none): the thread-default #GMainContext, or + * %NULL if the thread-default context is the global default context. + * + * Since: 2.22 + **/ +GMainContext * +g_main_context_get_thread_default (void) +{ + GQueue *stack; + + stack = g_private_get (&thread_context_stack); + if (stack) + return g_queue_peek_head (stack); + else + return NULL; +} + +/** + * g_main_context_ref_thread_default: + * + * Gets the thread-default #GMainContext for this thread, as with + * g_main_context_get_thread_default(), but also adds a reference to + * it with g_main_context_ref(). In addition, unlike + * g_main_context_get_thread_default(), if the thread-default context + * is the global default context, this will return that #GMainContext + * (with a ref added to it) rather than returning %NULL. + * + * Returns: (transfer full): the thread-default #GMainContext. Unref + * with g_main_context_unref() when you are done with it. + * + * Since: 2.32 + */ +GMainContext * +g_main_context_ref_thread_default (void) +{ + GMainContext *context; + + context = g_main_context_get_thread_default (); + if (!context) + context = g_main_context_default (); + return g_main_context_ref (context); +} + +/* Hooks for adding to the main loop */ + +/** + * g_source_new: + * @source_funcs: structure containing functions that implement + * the sources behavior. + * @struct_size: size of the #GSource structure to create. + * + * Creates a new #GSource structure. The size is specified to + * allow creating structures derived from #GSource that contain + * additional data. The size passed in must be at least + * sizeof (GSource). + * + * The source will not initially be associated with any #GMainContext + * and must be added to one with g_source_attach() before it will be + * executed. + * + * Return value: the newly-created #GSource. + **/ +GSource * +g_source_new (GSourceFuncs *source_funcs, + guint struct_size) +{ + GSource *source; + + g_return_val_if_fail (source_funcs != NULL, NULL); + g_return_val_if_fail (struct_size >= sizeof (GSource), NULL); + + source = (GSource*) g_malloc0 (struct_size); + + source->source_funcs = source_funcs; + source->ref_count = 1; + + source->priority = G_PRIORITY_DEFAULT; + + source->flags = G_HOOK_FLAG_ACTIVE; + + /* NULL/0 initialization for all other fields */ + + return source; +} + +/* Holds context's lock + */ +static void +g_source_list_add (GSource *source, + GMainContext *context) +{ + GSource *tmp_source, *last_source; + + if (source->priv && source->priv->parent_source) + { + /* Put the source immediately before its parent */ + tmp_source = source->priv->parent_source; + last_source = source->priv->parent_source->prev; + } + else + { + last_source = NULL; + tmp_source = context->source_list; + while (tmp_source && tmp_source->priority <= source->priority) + { + last_source = tmp_source; + tmp_source = tmp_source->next; + } + } + + source->next = tmp_source; + if (tmp_source) + tmp_source->prev = source; + + source->prev = last_source; + if (last_source) + last_source->next = source; + else + context->source_list = source; +} + +/* Holds context's lock + */ +static void +g_source_list_remove (GSource *source, + GMainContext *context) +{ + if (source->prev) + source->prev->next = source->next; + else + context->source_list = source->next; + + if (source->next) + source->next->prev = source->prev; + + source->prev = NULL; + source->next = NULL; +} + +static guint +g_source_attach_unlocked (GSource *source, + GMainContext *context) +{ + guint result = 0; + GSList *tmp_list; + + source->context = context; + result = source->source_id = context->next_id++; + + source->ref_count++; + g_source_list_add (source, context); + + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data); + tmp_list = tmp_list->next; + } + + if (source->priv) + { + tmp_list = source->priv->child_sources; + while (tmp_list) + { + g_source_attach_unlocked (tmp_list->data, context); + tmp_list = tmp_list->next; + } + } + + return result; +} + +/** + * g_source_attach: + * @source: a #GSource + * @context: (allow-none): a #GMainContext (if %NULL, the default context will be used) + * + * Adds a #GSource to a @context so that it will be executed within + * that context. Remove it by calling g_source_destroy(). + * + * Return value: the ID (greater than 0) for the source within the + * #GMainContext. + **/ +guint +g_source_attach (GSource *source, + GMainContext *context) +{ + guint result = 0; + + g_return_val_if_fail (source->context == NULL, 0); + g_return_val_if_fail (!SOURCE_DESTROYED (source), 0); + + if (!context) + context = g_main_context_default (); + + LOCK_CONTEXT (context); + + result = g_source_attach_unlocked (source, context); + + /* If another thread has acquired the context, wake it up since it + * might be in poll() right now. + */ + if (context->owner && context->owner != G_THREAD_SELF) + g_wakeup_signal (context->wakeup); + + UNLOCK_CONTEXT (context); + + return result; +} + +static void +g_source_destroy_internal (GSource *source, + GMainContext *context, + gboolean have_lock) +{ + if (!have_lock) + LOCK_CONTEXT (context); + + if (!SOURCE_DESTROYED (source)) + { + GSList *tmp_list; + gpointer old_cb_data; + GSourceCallbackFuncs *old_cb_funcs; + + source->flags &= ~G_HOOK_FLAG_ACTIVE; + + old_cb_data = source->callback_data; + old_cb_funcs = source->callback_funcs; + + source->callback_data = NULL; + source->callback_funcs = NULL; + + if (old_cb_funcs) + { + UNLOCK_CONTEXT (context); + old_cb_funcs->unref (old_cb_data); + LOCK_CONTEXT (context); + } + + if (!SOURCE_BLOCKED (source)) + { + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_remove_poll_unlocked (context, tmp_list->data); + tmp_list = tmp_list->next; + } + } + + if (source->priv && source->priv->child_sources) + { + /* This is safe because even if a child_source finalizer or + * closure notify tried to modify source->priv->child_sources + * from outside the lock, it would fail since + * SOURCE_DESTROYED(source) is now TRUE. + */ + tmp_list = source->priv->child_sources; + while (tmp_list) + { + g_source_destroy_internal (tmp_list->data, context, TRUE); + g_source_unref_internal (tmp_list->data, context, TRUE); + tmp_list = tmp_list->next; + } + g_slist_free (source->priv->child_sources); + source->priv->child_sources = NULL; + } + + g_source_unref_internal (source, context, TRUE); + } + + if (!have_lock) + UNLOCK_CONTEXT (context); +} + +/** + * g_source_destroy: + * @source: a #GSource + * + * Removes a source from its #GMainContext, if any, and mark it as + * destroyed. The source cannot be subsequently added to another + * context. + **/ +void +g_source_destroy (GSource *source) +{ + GMainContext *context; + + g_return_if_fail (source != NULL); + + context = source->context; + + if (context) + g_source_destroy_internal (source, context, FALSE); + else + source->flags &= ~G_HOOK_FLAG_ACTIVE; +} + +/** + * g_source_get_id: + * @source: a #GSource + * + * Returns the numeric ID for a particular source. The ID of a source + * is a positive integer which is unique within a particular main loop + * context. The reverse + * mapping from ID to source is done by g_main_context_find_source_by_id(). + * + * Return value: the ID (greater than 0) for the source + **/ +guint +g_source_get_id (GSource *source) +{ + guint result; + + g_return_val_if_fail (source != NULL, 0); + g_return_val_if_fail (source->context != NULL, 0); + + LOCK_CONTEXT (source->context); + result = source->source_id; + UNLOCK_CONTEXT (source->context); + + return result; +} + +/** + * g_source_get_context: + * @source: a #GSource + * + * Gets the #GMainContext with which the source is associated. + * Calling this function on a destroyed source is an error. + * + * Return value: (transfer none): the #GMainContext with which the + * source is associated, or %NULL if the context has not + * yet been added to a source. + **/ +GMainContext * +g_source_get_context (GSource *source) +{ + g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL); + + return source->context; +} + +/** + * g_source_add_poll: + * @source:a #GSource + * @fd: a #GPollFD structure holding information about a file + * descriptor to watch. + * + * Adds a file descriptor to the set of file descriptors polled for + * this source. This is usually combined with g_source_new() to add an + * event source. The event source's check function will typically test + * the @revents field in the #GPollFD struct and return %TRUE if events need + * to be processed. + **/ +void +g_source_add_poll (GSource *source, + GPollFD *fd) +{ + GMainContext *context; + + g_return_if_fail (source != NULL); + g_return_if_fail (fd != NULL); + g_return_if_fail (!SOURCE_DESTROYED (source)); + + context = source->context; + + if (context) + LOCK_CONTEXT (context); + + source->poll_fds = g_slist_prepend (source->poll_fds, fd); + + if (context) + { + if (!SOURCE_BLOCKED (source)) + g_main_context_add_poll_unlocked (context, source->priority, fd); + UNLOCK_CONTEXT (context); + } +} + +/** + * g_source_remove_poll: + * @source:a #GSource + * @fd: a #GPollFD structure previously passed to g_source_add_poll(). + * + * Removes a file descriptor from the set of file descriptors polled for + * this source. + **/ +void +g_source_remove_poll (GSource *source, + GPollFD *fd) +{ + GMainContext *context; + + g_return_if_fail (source != NULL); + g_return_if_fail (fd != NULL); + g_return_if_fail (!SOURCE_DESTROYED (source)); + + context = source->context; + + if (context) + LOCK_CONTEXT (context); + + source->poll_fds = g_slist_remove (source->poll_fds, fd); + + if (context) + { + if (!SOURCE_BLOCKED (source)) + g_main_context_remove_poll_unlocked (context, fd); + UNLOCK_CONTEXT (context); + } +} + +/** + * g_source_add_child_source: + * @source:a #GSource + * @child_source: a second #GSource that @source should "poll" + * + * Adds @child_source to @source as a "polled" source; when @source is + * added to a #GMainContext, @child_source will be automatically added + * with the same priority, when @child_source is triggered, it will + * cause @source to dispatch (in addition to calling its own + * callback), and when @source is destroyed, it will destroy + * @child_source as well. (@source will also still be dispatched if + * its own prepare/check functions indicate that it is ready.) + * + * If you don't need @child_source to do anything on its own when it + * triggers, you can call g_source_set_dummy_callback() on it to set a + * callback that does nothing (except return %TRUE if appropriate). + * + * @source will hold a reference on @child_source while @child_source + * is attached to it. + * + * Since: 2.28 + **/ +void +g_source_add_child_source (GSource *source, + GSource *child_source) +{ + GMainContext *context; + + g_return_if_fail (source != NULL); + g_return_if_fail (child_source != NULL); + g_return_if_fail (!SOURCE_DESTROYED (source)); + g_return_if_fail (!SOURCE_DESTROYED (child_source)); + g_return_if_fail (child_source->context == NULL); + g_return_if_fail (child_source->priv == NULL || child_source->priv->parent_source == NULL); + + context = source->context; + + if (context) + LOCK_CONTEXT (context); + + if (!source->priv) + source->priv = g_slice_new0 (GSourcePrivate); + if (!child_source->priv) + child_source->priv = g_slice_new0 (GSourcePrivate); + + source->priv->child_sources = g_slist_prepend (source->priv->child_sources, + g_source_ref (child_source)); + child_source->priv->parent_source = source; + g_source_set_priority_unlocked (child_source, NULL, source->priority); + + if (context) + { + UNLOCK_CONTEXT (context); + g_source_attach (child_source, context); + } +} + +/** + * g_source_remove_child_source: + * @source:a #GSource + * @child_source: a #GSource previously passed to + * g_source_add_child_source(). + * + * Detaches @child_source from @source and destroys it. + * + * Since: 2.28 + **/ +void +g_source_remove_child_source (GSource *source, + GSource *child_source) +{ + GMainContext *context; + + g_return_if_fail (source != NULL); + g_return_if_fail (child_source != NULL); + g_return_if_fail (child_source->priv != NULL && child_source->priv->parent_source == source); + g_return_if_fail (!SOURCE_DESTROYED (source)); + g_return_if_fail (!SOURCE_DESTROYED (child_source)); + + context = source->context; + + if (context) + LOCK_CONTEXT (context); + + source->priv->child_sources = g_slist_remove (source->priv->child_sources, child_source); + g_source_destroy_internal (child_source, context, TRUE); + g_source_unref_internal (child_source, context, TRUE); + + if (context) + UNLOCK_CONTEXT (context); +} + +/** + * g_source_set_callback_indirect: + * @source: the source + * @callback_data: pointer to callback data "object" + * @callback_funcs: functions for reference counting @callback_data + * and getting the callback and data + * + * Sets the callback function storing the data as a refcounted callback + * "object". This is used internally. Note that calling + * g_source_set_callback_indirect() assumes + * an initial reference count on @callback_data, and thus + * @callback_funcs->unref will eventually be called once more + * than @callback_funcs->ref. + **/ +void +g_source_set_callback_indirect (GSource *source, + gpointer callback_data, + GSourceCallbackFuncs *callback_funcs) +{ + GMainContext *context; + gpointer old_cb_data; + GSourceCallbackFuncs *old_cb_funcs; + + g_return_if_fail (source != NULL); + g_return_if_fail (callback_funcs != NULL || callback_data == NULL); + + context = source->context; + + if (context) + LOCK_CONTEXT (context); + + old_cb_data = source->callback_data; + old_cb_funcs = source->callback_funcs; + + source->callback_data = callback_data; + source->callback_funcs = callback_funcs; + + if (context) + UNLOCK_CONTEXT (context); + + if (old_cb_funcs) + old_cb_funcs->unref (old_cb_data); +} + +static void +g_source_callback_ref (gpointer cb_data) +{ + GSourceCallback *callback = cb_data; + + callback->ref_count++; +} + + +static void +g_source_callback_unref (gpointer cb_data) +{ + GSourceCallback *callback = cb_data; + + callback->ref_count--; + if (callback->ref_count == 0) + { + if (callback->notify) + callback->notify (callback->data); + g_free (callback); + } +} + +static void +g_source_callback_get (gpointer cb_data, + GSource *source, + GSourceFunc *func, + gpointer *data) +{ + GSourceCallback *callback = cb_data; + + *func = callback->func; + *data = callback->data; +} + +static GSourceCallbackFuncs g_source_callback_funcs = { + g_source_callback_ref, + g_source_callback_unref, + g_source_callback_get, +}; + +/** + * g_source_set_callback: + * @source: the source + * @func: a callback function + * @data: the data to pass to callback function + * @notify: a function to call when @data is no longer in use, or %NULL. + * + * Sets the callback function for a source. The callback for a source is + * called from the source's dispatch function. + * + * The exact type of @func depends on the type of source; ie. you + * should not count on @func being called with @data as its first + * parameter. + * + * Typically, you won't use this function. Instead use functions specific + * to the type of source you are using. + **/ +void +g_source_set_callback (GSource *source, + GSourceFunc func, + gpointer data, + GDestroyNotify notify) +{ + GSourceCallback *new_callback; + + g_return_if_fail (source != NULL); + + new_callback = g_new (GSourceCallback, 1); + + new_callback->ref_count = 1; + new_callback->func = func; + new_callback->data = data; + new_callback->notify = notify; + + g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs); +} + + +/** + * g_source_set_funcs: + * @source: a #GSource + * @funcs: the new #GSourceFuncs + * + * Sets the source functions (can be used to override + * default implementations) of an unattached source. + * + * Since: 2.12 + */ +void +g_source_set_funcs (GSource *source, + GSourceFuncs *funcs) +{ + g_return_if_fail (source != NULL); + g_return_if_fail (source->context == NULL); + g_return_if_fail (source->ref_count > 0); + g_return_if_fail (funcs != NULL); + + source->source_funcs = funcs; +} + +static void +g_source_set_priority_unlocked (GSource *source, + GMainContext *context, + gint priority) +{ + GSList *tmp_list; + + source->priority = priority; + + if (context) + { + /* Remove the source from the context's source and then + * add it back so it is sorted in the correct place + */ + g_source_list_remove (source, source->context); + g_source_list_add (source, source->context); + + if (!SOURCE_BLOCKED (source)) + { + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_remove_poll_unlocked (context, tmp_list->data); + g_main_context_add_poll_unlocked (context, priority, tmp_list->data); + + tmp_list = tmp_list->next; + } + } + } + + if (source->priv && source->priv->child_sources) + { + tmp_list = source->priv->child_sources; + while (tmp_list) + { + g_source_set_priority_unlocked (tmp_list->data, context, priority); + tmp_list = tmp_list->next; + } + } +} + +/** + * g_source_set_priority: + * @source: a #GSource + * @priority: the new priority. + * + * Sets the priority of a source. While the main loop is being run, a + * source will be dispatched if it is ready to be dispatched and no + * sources at a higher (numerically smaller) priority are ready to be + * dispatched. + **/ +void +g_source_set_priority (GSource *source, + gint priority) +{ + GMainContext *context; + + g_return_if_fail (source != NULL); + + context = source->context; + + if (context) + LOCK_CONTEXT (context); + g_source_set_priority_unlocked (source, context, priority); + if (context) + UNLOCK_CONTEXT (source->context); +} + +/** + * g_source_get_priority: + * @source: a #GSource + * + * Gets the priority of a source. + * + * Return value: the priority of the source + **/ +gint +g_source_get_priority (GSource *source) +{ + g_return_val_if_fail (source != NULL, 0); + + return source->priority; +} + +/** + * g_source_set_can_recurse: + * @source: a #GSource + * @can_recurse: whether recursion is allowed for this source + * + * Sets whether a source can be called recursively. If @can_recurse is + * %TRUE, then while the source is being dispatched then this source + * will be processed normally. Otherwise, all processing of this + * source is blocked until the dispatch function returns. + **/ +void +g_source_set_can_recurse (GSource *source, + gboolean can_recurse) +{ + GMainContext *context; + + g_return_if_fail (source != NULL); + + context = source->context; + + if (context) + LOCK_CONTEXT (context); + + if (can_recurse) + source->flags |= G_SOURCE_CAN_RECURSE; + else + source->flags &= ~G_SOURCE_CAN_RECURSE; + + if (context) + UNLOCK_CONTEXT (context); +} + +/** + * g_source_get_can_recurse: + * @source: a #GSource + * + * Checks whether a source is allowed to be called recursively. + * see g_source_set_can_recurse(). + * + * Return value: whether recursion is allowed. + **/ +gboolean +g_source_get_can_recurse (GSource *source) +{ + g_return_val_if_fail (source != NULL, FALSE); + + return (source->flags & G_SOURCE_CAN_RECURSE) != 0; +} + + +/** + * g_source_set_name: + * @source: a #GSource + * @name: debug name for the source + * + * Sets a name for the source, used in debugging and profiling. + * The name defaults to #NULL. + * + * The source name should describe in a human-readable way + * what the source does. For example, "X11 event queue" + * or "GTK+ repaint idle handler" or whatever it is. + * + * It is permitted to call this function multiple times, but is not + * recommended due to the potential performance impact. For example, + * one could change the name in the "check" function of a #GSourceFuncs + * to include details like the event type in the source name. + * + * Since: 2.26 + **/ +void +g_source_set_name (GSource *source, + const char *name) +{ + g_return_if_fail (source != NULL); + + /* setting back to NULL is allowed, just because it's + * weird if get_name can return NULL but you can't + * set that. + */ + + g_free (source->name); + source->name = g_strdup (name); +} + +/** + * g_source_get_name: + * @source: a #GSource + * + * Gets a name for the source, used in debugging and profiling. + * The name may be #NULL if it has never been set with + * g_source_set_name(). + * + * Return value: the name of the source + * Since: 2.26 + **/ +const char * +g_source_get_name (GSource *source) +{ + g_return_val_if_fail (source != NULL, NULL); + + return source->name; +} + +/** + * g_source_set_name_by_id: + * @tag: a #GSource ID + * @name: debug name for the source + * + * Sets the name of a source using its ID. + * + * This is a convenience utility to set source names from the return + * value of g_idle_add(), g_timeout_add(), etc. + * + * Since: 2.26 + **/ +void +g_source_set_name_by_id (guint tag, + const char *name) +{ + GSource *source; + + g_return_if_fail (tag > 0); + + source = g_main_context_find_source_by_id (NULL, tag); + if (source == NULL) + return; + + g_source_set_name (source, name); +} + + +/** + * g_source_ref: + * @source: a #GSource + * + * Increases the reference count on a source by one. + * + * Return value: @source + **/ +GSource * +g_source_ref (GSource *source) +{ + GMainContext *context; + + g_return_val_if_fail (source != NULL, NULL); + + context = source->context; + + if (context) + LOCK_CONTEXT (context); + + source->ref_count++; + + if (context) + UNLOCK_CONTEXT (context); + + return source; +} + +/* g_source_unref() but possible to call within context lock + */ +static void +g_source_unref_internal (GSource *source, + GMainContext *context, + gboolean have_lock) +{ + gpointer old_cb_data = NULL; + GSourceCallbackFuncs *old_cb_funcs = NULL; + + g_return_if_fail (source != NULL); + + if (!have_lock && context) + LOCK_CONTEXT (context); + + source->ref_count--; + if (source->ref_count == 0) + { + old_cb_data = source->callback_data; + old_cb_funcs = source->callback_funcs; + + source->callback_data = NULL; + source->callback_funcs = NULL; + + if (context) + { + if (!SOURCE_DESTROYED (source)) + g_warning (G_STRLOC ": ref_count == 0, but source was still attached to a context!"); + g_source_list_remove (source, context); + } + + if (source->source_funcs->finalize) + { + if (context) + UNLOCK_CONTEXT (context); + source->source_funcs->finalize (source); + if (context) + LOCK_CONTEXT (context); + } + + g_free (source->name); + source->name = NULL; + + g_slist_free (source->poll_fds); + source->poll_fds = NULL; + + if (source->priv) + { + g_slice_free (GSourcePrivate, source->priv); + source->priv = NULL; + } + + g_free (source); + } + + if (!have_lock && context) + UNLOCK_CONTEXT (context); + + if (old_cb_funcs) + { + if (have_lock) + UNLOCK_CONTEXT (context); + + old_cb_funcs->unref (old_cb_data); + + if (have_lock) + LOCK_CONTEXT (context); + } +} + +/** + * g_source_unref: + * @source: a #GSource + * + * Decreases the reference count of a source by one. If the + * resulting reference count is zero the source and associated + * memory will be destroyed. + **/ +void +g_source_unref (GSource *source) +{ + g_return_if_fail (source != NULL); + + g_source_unref_internal (source, source->context, FALSE); +} + +/** + * g_main_context_find_source_by_id: + * @context: a #GMainContext (if %NULL, the default context will be used) + * @source_id: the source ID, as returned by g_source_get_id(). + * + * Finds a #GSource given a pair of context and ID. + * + * Return value: (transfer none): the #GSource if found, otherwise, %NULL + **/ +GSource * +g_main_context_find_source_by_id (GMainContext *context, + guint source_id) +{ + GSource *source; + + g_return_val_if_fail (source_id > 0, NULL); + + if (context == NULL) + context = g_main_context_default (); + + LOCK_CONTEXT (context); + + source = context->source_list; + while (source) + { + if (!SOURCE_DESTROYED (source) && + source->source_id == source_id) + break; + source = source->next; + } + + UNLOCK_CONTEXT (context); + + return source; +} + +/** + * g_main_context_find_source_by_funcs_user_data: + * @context: a #GMainContext (if %NULL, the default context will be used). + * @funcs: the @source_funcs passed to g_source_new(). + * @user_data: the user data from the callback. + * + * Finds a source with the given source functions and user data. If + * multiple sources exist with the same source function and user data, + * the first one found will be returned. + * + * Return value: (transfer none): the source, if one was found, otherwise %NULL + **/ +GSource * +g_main_context_find_source_by_funcs_user_data (GMainContext *context, + GSourceFuncs *funcs, + gpointer user_data) +{ + GSource *source; + + g_return_val_if_fail (funcs != NULL, NULL); + + if (context == NULL) + context = g_main_context_default (); + + LOCK_CONTEXT (context); + + source = context->source_list; + while (source) + { + if (!SOURCE_DESTROYED (source) && + source->source_funcs == funcs && + source->callback_funcs) + { + GSourceFunc callback; + gpointer callback_data; + + source->callback_funcs->get (source->callback_data, source, &callback, &callback_data); + + if (callback_data == user_data) + break; + } + source = source->next; + } + + UNLOCK_CONTEXT (context); + + return source; +} + +/** + * g_main_context_find_source_by_user_data: + * @context: a #GMainContext + * @user_data: the user_data for the callback. + * + * Finds a source with the given user data for the callback. If + * multiple sources exist with the same user data, the first + * one found will be returned. + * + * Return value: (transfer none): the source, if one was found, otherwise %NULL + **/ +GSource * +g_main_context_find_source_by_user_data (GMainContext *context, + gpointer user_data) +{ + GSource *source; + + if (context == NULL) + context = g_main_context_default (); + + LOCK_CONTEXT (context); + + source = context->source_list; + while (source) + { + if (!SOURCE_DESTROYED (source) && + source->callback_funcs) + { + GSourceFunc callback; + gpointer callback_data = NULL; + + source->callback_funcs->get (source->callback_data, source, &callback, &callback_data); + + if (callback_data == user_data) + break; + } + source = source->next; + } + + UNLOCK_CONTEXT (context); + + return source; +} + +/** + * g_source_remove: + * @tag: the ID of the source to remove. + * + * Removes the source with the given id from the default main context. + * The id of + * a #GSource is given by g_source_get_id(), or will be returned by the + * functions g_source_attach(), g_idle_add(), g_idle_add_full(), + * g_timeout_add(), g_timeout_add_full(), g_child_watch_add(), + * g_child_watch_add_full(), g_io_add_watch(), and g_io_add_watch_full(). + * + * See also g_source_destroy(). You must use g_source_destroy() for sources + * added to a non-default main context. + * + * Return value: %TRUE if the source was found and removed. + **/ +gboolean +g_source_remove (guint tag) +{ + GSource *source; + + g_return_val_if_fail (tag > 0, FALSE); + + source = g_main_context_find_source_by_id (NULL, tag); + if (source) + g_source_destroy (source); + + return source != NULL; +} + +/** + * g_source_remove_by_user_data: + * @user_data: the user_data for the callback. + * + * Removes a source from the default main loop context given the user + * data for the callback. If multiple sources exist with the same user + * data, only one will be destroyed. + * + * Return value: %TRUE if a source was found and removed. + **/ +gboolean +g_source_remove_by_user_data (gpointer user_data) +{ + GSource *source; + + source = g_main_context_find_source_by_user_data (NULL, user_data); + if (source) + { + g_source_destroy (source); + return TRUE; + } + else + return FALSE; +} + +/** + * g_source_remove_by_funcs_user_data: + * @funcs: The @source_funcs passed to g_source_new() + * @user_data: the user data for the callback + * + * Removes a source from the default main loop context given the + * source functions and user data. If multiple sources exist with the + * same source functions and user data, only one will be destroyed. + * + * Return value: %TRUE if a source was found and removed. + **/ +gboolean +g_source_remove_by_funcs_user_data (GSourceFuncs *funcs, + gpointer user_data) +{ + GSource *source; + + g_return_val_if_fail (funcs != NULL, FALSE); + + source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data); + if (source) + { + g_source_destroy (source); + return TRUE; + } + else + return FALSE; +} + +/** + * g_get_current_time: + * @result: #GTimeVal structure in which to store current time. + * + * Equivalent to the UNIX gettimeofday() function, but portable. + * + * You may find g_get_real_time() to be more convenient. + **/ +void +g_get_current_time (GTimeVal *result) +{ +#ifndef G_OS_WIN32 + struct timeval r; + + g_return_if_fail (result != NULL); + + /*this is required on alpha, there the timeval structs are int's + not longs and a cast only would fail horribly*/ + gettimeofday (&r, NULL); + result->tv_sec = r.tv_sec; + result->tv_usec = r.tv_usec; +#else + FILETIME ft; + guint64 time64; + + g_return_if_fail (result != NULL); + + GetSystemTimeAsFileTime (&ft); + memmove (&time64, &ft, sizeof (FILETIME)); + + /* Convert from 100s of nanoseconds since 1601-01-01 + * to Unix epoch. Yes, this is Y2038 unsafe. + */ + time64 -= G_GINT64_CONSTANT (116444736000000000); + time64 /= 10; + + result->tv_sec = time64 / 1000000; + result->tv_usec = time64 % 1000000; +#endif +} + +/** + * g_get_real_time: + * + * Queries the system wall-clock time. + * + * This call is functionally equivalent to g_get_current_time() except + * that the return value is often more convenient than dealing with a + * #GTimeVal. + * + * You should only use this call if you are actually interested in the real + * wall-clock time. g_get_monotonic_time() is probably more useful for + * measuring intervals. + * + * Returns: the number of microseconds since January 1, 1970 UTC. + * + * Since: 2.28 + **/ +gint64 +g_get_real_time (void) +{ + GTimeVal tv; + + g_get_current_time (&tv); + + return (((gint64) tv.tv_sec) * 1000000) + tv.tv_usec; +} + +#ifdef G_OS_WIN32 +static ULONGLONG (*g_GetTickCount64) (void) = NULL; +static guint32 g_win32_tick_epoch = 0; + +G_GNUC_INTERNAL void +g_clock_win32_init (void) +{ + HMODULE kernel32; + + g_GetTickCount64 = NULL; + kernel32 = GetModuleHandle ("KERNEL32.DLL"); + if (kernel32 != NULL) + g_GetTickCount64 = (void *) GetProcAddress (kernel32, "GetTickCount64"); + g_win32_tick_epoch = ((guint32)GetTickCount()) >> 31; +} +#endif + +/** + * g_get_monotonic_time: + * + * Queries the system monotonic time, if available. + * + * On POSIX systems with clock_gettime() and CLOCK_MONOTONIC this call + * is a very shallow wrapper for that. Otherwise, we make a best effort + * that probably involves returning the wall clock time (with at least + * microsecond accuracy, subject to the limitations of the OS kernel). + * + * It's important to note that POSIX CLOCK_MONOTONIC does + * not count time spent while the machine is suspended. + * + * On Windows, "limitations of the OS kernel" is a rather substantial + * statement. Depending on the configuration of the system, the wall + * clock time is updated as infrequently as 64 times a second (which + * is approximately every 16ms). Also, on XP (but not on Vista or later) + * the monotonic clock is locally monotonic, but may differ in exact + * value between processes due to timer wrap handling. + * + * Returns: the monotonic time, in microseconds + * + * Since: 2.28 + **/ +gint64 +g_get_monotonic_time (void) +{ +#ifdef HAVE_CLOCK_GETTIME + /* librt clock_gettime() is our first choice */ + struct timespec ts; + +#ifdef CLOCK_MONOTONIC + clock_gettime (CLOCK_MONOTONIC, &ts); +#else + clock_gettime (CLOCK_REALTIME, &ts); +#endif + + /* In theory monotonic time can have any epoch. + * + * glib presently assumes the following: + * + * 1) The epoch comes some time after the birth of Jesus of Nazareth, but + * not more than 10000 years later. + * + * 2) The current time also falls sometime within this range. + * + * These two reasonable assumptions leave us with a maximum deviation from + * the epoch of 10000 years, or 315569520000000000 seconds. + * + * If we restrict ourselves to this range then the number of microseconds + * will always fit well inside the constraints of a int64 (by a factor of + * about 29). + * + * If you actually hit the following assertion, probably you should file a + * bug against your operating system for being excessively silly. + **/ + g_assert (G_GINT64_CONSTANT (-315569520000000000) < ts.tv_sec && + ts.tv_sec < G_GINT64_CONSTANT (315569520000000000)); + + return (((gint64) ts.tv_sec) * 1000000) + (ts.tv_nsec / 1000); + +#elif defined (G_OS_WIN32) + guint64 ticks; + guint32 ticks32; + + /* There are four sources for the monotonic time on Windows: + * + * Three are based on a (1 msec accuracy, but only read periodically) clock chip: + * - GetTickCount (GTC) + * 32bit msec counter, updated each ~15msec, wraps in ~50 days + * - GetTickCount64 (GTC64) + * Same as GetTickCount, but extended to 64bit, so no wrap + * Only availible in Vista or later + * - timeGetTime (TGT) + * similar to GetTickCount by default: 15msec, 50 day wrap. + * available in winmm.dll (thus known as the multimedia timers) + * However apps can raise the system timer clock frequency using timeBeginPeriod() + * increasing the accuracy up to 1 msec, at a cost in general system performance + * and battery use. + * + * One is based on high precision clocks: + * - QueryPrecisionCounter (QPC) + * This has much higher accuracy, but is not guaranteed monotonic, and + * has lots of complications like clock jumps and different times on different + * CPUs. It also has lower long term accuracy (i.e. it will drift compared to + * the low precision clocks. + * + * Additionally, the precision available in the timer-based wakeup such as + * MsgWaitForMultipleObjectsEx (which is what the mainloop is based on) is based + * on the TGT resolution, so by default it is ~15msec, but can be increased by apps. + * + * The QPC timer has too many issues to be used as is. The only way it could be used + * is to use it to interpolate the lower precision clocks. Firefox does something like + * this: + * https://bugzilla.mozilla.org/show_bug.cgi?id=363258 + * + * However this seems quite complicated, so we're not doing this right now. + * + * The approach we take instead is to use the TGT timer, extending it to 64bit + * either by using the GTC64 value, or if that is not availible, a process local + * time epoch that we increment when we detect a timer wrap (assumes that we read + * the time at least once every 50 days). + * + * This means that: + * - We have a globally consistent monotonic clock on Vista and later + * - We have a locally monotonic clock on XP + * - Apps that need higher precision in timeouts and clock reads can call + * timeBeginPeriod() to increase it as much as they want + */ + + if (g_GetTickCount64 != NULL) + { + guint32 ticks_as_32bit; + + ticks = g_GetTickCount64 (); + ticks32 = timeGetTime(); + + /* GTC64 and TGT are sampled at different times, however they + * have the same base and source (msecs since system boot). + * They can differ by as much as -16 to +16 msecs. + * We can't just inject the low bits into the 64bit counter + * as one of the counters can have wrapped in 32bit space and + * the other not. Instead we calculate the signed difference + * in 32bit space and apply that difference to the 64bit counter. + */ + ticks_as_32bit = (guint32)ticks; + + /* We could do some 2's complement hack, but we play it safe */ + if (ticks32 - ticks_as_32bit <= G_MAXINT32) + ticks += ticks32 - ticks_as_32bit; + else + ticks -= ticks_as_32bit - ticks32; + } + else + { + guint32 epoch; + + epoch = g_atomic_int_get (&g_win32_tick_epoch); + + /* Must read ticks after the epoch. Then we're guaranteed + * that the ticks value we read is higher or equal to any + * previous ones that lead to the writing of the epoch. + */ + ticks32 = timeGetTime(); + + /* We store the MSB of the current time as the LSB + * of the epoch. Comparing these bits lets us detect when + * the 32bit counter has wrapped so we can increase the + * epoch. + * + * This will work as long as this function is called at + * least once every ~24 days, which is half the wrap time + * of a 32bit msec counter. I think this is pretty likely. + * + * Note that g_win32_tick_epoch is a process local state, + * so the monotonic clock will not be the same between + * processes. + */ + if ((ticks32 >> 31) != (epoch & 1)) + { + epoch++; + g_atomic_int_set (&g_win32_tick_epoch, epoch); + } + + + ticks = (guint64)ticks32 | ((guint64)epoch) << 31; + } + + return ticks * 1000; + +#else /* !HAVE_CLOCK_GETTIME && ! G_OS_WIN32*/ + + GTimeVal tv; + + g_get_current_time (&tv); + + return (((gint64) tv.tv_sec) * 1000000) + tv.tv_usec; +#endif +} + +static void +g_main_dispatch_free (gpointer dispatch) +{ + g_slice_free (GMainDispatch, dispatch); +} + +/* Running the main loop */ + +static GMainDispatch * +get_dispatch (void) +{ + static GPrivate depth_private = G_PRIVATE_INIT (g_main_dispatch_free); + GMainDispatch *dispatch; + + dispatch = g_private_get (&depth_private); + + if (!dispatch) + { + dispatch = g_slice_new0 (GMainDispatch); + g_private_set (&depth_private, dispatch); + } + + return dispatch; +} + +/** + * g_main_depth: + * + * Returns the depth of the stack of calls to + * g_main_context_dispatch() on any #GMainContext in the current thread. + * That is, when called from the toplevel, it gives 0. When + * called from within a callback from g_main_context_iteration() + * (or g_main_loop_run(), etc.) it returns 1. When called from within + * a callback to a recursive call to g_main_context_iteration(), + * it returns 2. And so forth. + * + * This function is useful in a situation like the following: + * Imagine an extremely simple "garbage collected" system. + * + * |[ + * static GList *free_list; + * + * gpointer + * allocate_memory (gsize size) + * { + * gpointer result = g_malloc (size); + * free_list = g_list_prepend (free_list, result); + * return result; + * } + * + * void + * free_allocated_memory (void) + * { + * GList *l; + * for (l = free_list; l; l = l->next); + * g_free (l->data); + * g_list_free (free_list); + * free_list = NULL; + * } + * + * [...] + * + * while (TRUE); + * { + * g_main_context_iteration (NULL, TRUE); + * free_allocated_memory(); + * } + * ]| + * + * This works from an application, however, if you want to do the same + * thing from a library, it gets more difficult, since you no longer + * control the main loop. You might think you can simply use an idle + * function to make the call to free_allocated_memory(), but that + * doesn't work, since the idle function could be called from a + * recursive callback. This can be fixed by using g_main_depth() + * + * |[ + * gpointer + * allocate_memory (gsize size) + * { + * FreeListBlock *block = g_new (FreeListBlock, 1); + * block->mem = g_malloc (size); + * block->depth = g_main_depth (); + * free_list = g_list_prepend (free_list, block); + * return block->mem; + * } + * + * void + * free_allocated_memory (void) + * { + * GList *l; + * + * int depth = g_main_depth (); + * for (l = free_list; l; ); + * { + * GList *next = l->next; + * FreeListBlock *block = l->data; + * if (block->depth > depth) + * { + * g_free (block->mem); + * g_free (block); + * free_list = g_list_delete_link (free_list, l); + * } + * + * l = next; + * } + * } + * ]| + * + * There is a temptation to use g_main_depth() to solve + * problems with reentrancy. For instance, while waiting for data + * to be received from the network in response to a menu item, + * the menu item might be selected again. It might seem that + * one could make the menu item's callback return immediately + * and do nothing if g_main_depth() returns a value greater than 1. + * However, this should be avoided since the user then sees selecting + * the menu item do nothing. Furthermore, you'll find yourself adding + * these checks all over your code, since there are doubtless many, + * many things that the user could do. Instead, you can use the + * following techniques: + * + * + * + * + * Use gtk_widget_set_sensitive() or modal dialogs to prevent + * the user from interacting with elements while the main + * loop is recursing. + * + * + * + * + * Avoid main loop recursion in situations where you can't handle + * arbitrary callbacks. Instead, structure your code so that you + * simply return to the main loop and then get called again when + * there is more work to do. + * + * + * + * + * Return value: The main loop recursion level in the current thread + **/ +int +g_main_depth (void) +{ + GMainDispatch *dispatch = get_dispatch (); + return dispatch->depth; +} + +/** + * g_main_current_source: + * + * Returns the currently firing source for this thread. + * + * Return value: (transfer none): The currently firing source or %NULL. + * + * Since: 2.12 + */ +GSource * +g_main_current_source (void) +{ + GMainDispatch *dispatch = get_dispatch (); + return dispatch->dispatching_sources ? dispatch->dispatching_sources->data : NULL; +} + +/** + * g_source_is_destroyed: + * @source: a #GSource + * + * Returns whether @source has been destroyed. + * + * This is important when you operate upon your objects + * from within idle handlers, but may have freed the object + * before the dispatch of your idle handler. + * + * |[ + * static gboolean + * idle_callback (gpointer data) + * { + * SomeWidget *self = data; + * + * GDK_THREADS_ENTER (); + * /* do stuff with self */ + * self->idle_id = 0; + * GDK_THREADS_LEAVE (); + * + * return G_SOURCE_REMOVE; + * } + * + * static void + * some_widget_do_stuff_later (SomeWidget *self) + * { + * self->idle_id = g_idle_add (idle_callback, self); + * } + * + * static void + * some_widget_finalize (GObject *object) + * { + * SomeWidget *self = SOME_WIDGET (object); + * + * if (self->idle_id) + * g_source_remove (self->idle_id); + * + * G_OBJECT_CLASS (parent_class)->finalize (object); + * } + * ]| + * + * This will fail in a multi-threaded application if the + * widget is destroyed before the idle handler fires due + * to the use after free in the callback. A solution, to + * this particular problem, is to check to if the source + * has already been destroy within the callback. + * + * |[ + * static gboolean + * idle_callback (gpointer data) + * { + * SomeWidget *self = data; + * + * GDK_THREADS_ENTER (); + * if (!g_source_is_destroyed (g_main_current_source ())) + * { + * /* do stuff with self */ + * } + * GDK_THREADS_LEAVE (); + * + * return FALSE; + * } + * ]| + * + * Return value: %TRUE if the source has been destroyed + * + * Since: 2.12 + */ +gboolean +g_source_is_destroyed (GSource *source) +{ + return SOURCE_DESTROYED (source); +} + +/* Temporarily remove all this source's file descriptors from the + * poll(), so that if data comes available for one of the file descriptors + * we don't continually spin in the poll() + */ +/* HOLDS: source->context's lock */ +static void +block_source (GSource *source) +{ + GSList *tmp_list; + + g_return_if_fail (!SOURCE_BLOCKED (source)); + + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_remove_poll_unlocked (source->context, tmp_list->data); + tmp_list = tmp_list->next; + } +} + +/* HOLDS: source->context's lock */ +static void +unblock_source (GSource *source) +{ + GSList *tmp_list; + + g_return_if_fail (!SOURCE_BLOCKED (source)); /* Source already unblocked */ + g_return_if_fail (!SOURCE_DESTROYED (source)); + + tmp_list = source->poll_fds; + while (tmp_list) + { + g_main_context_add_poll_unlocked (source->context, source->priority, tmp_list->data); + tmp_list = tmp_list->next; + } +} + +/* HOLDS: context's lock */ +static void +g_main_dispatch (GMainContext *context) +{ + GMainDispatch *current = get_dispatch (); + guint i; + + for (i = 0; i < context->pending_dispatches->len; i++) + { + GSource *source = context->pending_dispatches->pdata[i]; + + context->pending_dispatches->pdata[i] = NULL; + g_assert (source); + + source->flags &= ~G_SOURCE_READY; + + if (!SOURCE_DESTROYED (source)) + { + gboolean was_in_call; + gpointer user_data = NULL; + GSourceFunc callback = NULL; + GSourceCallbackFuncs *cb_funcs; + gpointer cb_data; + gboolean need_destroy; + + gboolean (*dispatch) (GSource *, + GSourceFunc, + gpointer); + GSList current_source_link; + + dispatch = source->source_funcs->dispatch; + cb_funcs = source->callback_funcs; + cb_data = source->callback_data; + + if (cb_funcs) + cb_funcs->ref (cb_data); + + if ((source->flags & G_SOURCE_CAN_RECURSE) == 0) + block_source (source); + + was_in_call = source->flags & G_HOOK_FLAG_IN_CALL; + source->flags |= G_HOOK_FLAG_IN_CALL; + + if (cb_funcs) + cb_funcs->get (cb_data, source, &callback, &user_data); + + UNLOCK_CONTEXT (context); + + current->depth++; + /* The on-stack allocation of the GSList is unconventional, but + * we know that the lifetime of the link is bounded to this + * function as the link is kept in a thread specific list and + * not manipulated outside of this function and its descendants. + * Avoiding the overhead of a g_slist_alloc() is useful as many + * applications do little more than dispatch events. + * + * This is a performance hack - do not revert to g_slist_prepend()! + */ + current_source_link.data = source; + current_source_link.next = current->dispatching_sources; + current->dispatching_sources = ¤t_source_link; + need_destroy = ! dispatch (source, + callback, + user_data); + g_assert (current->dispatching_sources == ¤t_source_link); + current->dispatching_sources = current_source_link.next; + current->depth--; + + if (cb_funcs) + cb_funcs->unref (cb_data); + + LOCK_CONTEXT (context); + + if (!was_in_call) + source->flags &= ~G_HOOK_FLAG_IN_CALL; + + if ((source->flags & G_SOURCE_CAN_RECURSE) == 0 && + !SOURCE_DESTROYED (source)) + unblock_source (source); + + /* Note: this depends on the fact that we can't switch + * sources from one main context to another + */ + if (need_destroy && !SOURCE_DESTROYED (source)) + { + g_assert (source->context == context); + g_source_destroy_internal (source, context, TRUE); + } + } + + SOURCE_UNREF (source, context); + } + + g_ptr_array_set_size (context->pending_dispatches, 0); +} + +/* Holds context's lock */ +static inline GSource * +next_valid_source (GMainContext *context, + GSource *source) +{ + GSource *new_source = source ? source->next : context->source_list; + + while (new_source) + { + if (!SOURCE_DESTROYED (new_source)) + { + new_source->ref_count++; + break; + } + + new_source = new_source->next; + } + + if (source) + SOURCE_UNREF (source, context); + + return new_source; +} + +/** + * g_main_context_acquire: + * @context: a #GMainContext + * + * Tries to become the owner of the specified context. + * If some other thread is the owner of the context, + * returns %FALSE immediately. Ownership is properly + * recursive: the owner can require ownership again + * and will release ownership when g_main_context_release() + * is called as many times as g_main_context_acquire(). + * + * You must be the owner of a context before you + * can call g_main_context_prepare(), g_main_context_query(), + * g_main_context_check(), g_main_context_dispatch(). + * + * Return value: %TRUE if the operation succeeded, and + * this thread is now the owner of @context. + **/ +gboolean +g_main_context_acquire (GMainContext *context) +{ + gboolean result = FALSE; + GThread *self = G_THREAD_SELF; + + if (context == NULL) + context = g_main_context_default (); + + LOCK_CONTEXT (context); + + if (!context->owner) + { + context->owner = self; + g_assert (context->owner_count == 0); + } + + if (context->owner == self) + { + context->owner_count++; + result = TRUE; + } + + UNLOCK_CONTEXT (context); + + return result; +} + +/** + * g_main_context_release: + * @context: a #GMainContext + * + * Releases ownership of a context previously acquired by this thread + * with g_main_context_acquire(). If the context was acquired multiple + * times, the ownership will be released only when g_main_context_release() + * is called as many times as it was acquired. + **/ +void +g_main_context_release (GMainContext *context) +{ + if (context == NULL) + context = g_main_context_default (); + + LOCK_CONTEXT (context); + + context->owner_count--; + if (context->owner_count == 0) + { + context->owner = NULL; + + if (context->waiters) + { + GMainWaiter *waiter = context->waiters->data; + gboolean loop_internal_waiter = (waiter->mutex == &context->mutex); + context->waiters = g_slist_delete_link (context->waiters, + context->waiters); + if (!loop_internal_waiter) + g_mutex_lock (waiter->mutex); + + g_cond_signal (waiter->cond); + + if (!loop_internal_waiter) + g_mutex_unlock (waiter->mutex); + } + } + + UNLOCK_CONTEXT (context); +} + +/** + * g_main_context_wait: + * @context: a #GMainContext + * @cond: a condition variable + * @mutex: a mutex, currently held + * + * Tries to become the owner of the specified context, + * as with g_main_context_acquire(). But if another thread + * is the owner, atomically drop @mutex and wait on @cond until + * that owner releases ownership or until @cond is signaled, then + * try again (once) to become the owner. + * + * Return value: %TRUE if the operation succeeded, and + * this thread is now the owner of @context. + **/ +gboolean +g_main_context_wait (GMainContext *context, + GCond *cond, + GMutex *mutex) +{ + gboolean result = FALSE; + GThread *self = G_THREAD_SELF; + gboolean loop_internal_waiter; + + if (context == NULL) + context = g_main_context_default (); + + loop_internal_waiter = (mutex == &context->mutex); + + if (!loop_internal_waiter) + LOCK_CONTEXT (context); + + if (context->owner && context->owner != self) + { + GMainWaiter waiter; + + waiter.cond = cond; + waiter.mutex = mutex; + + context->waiters = g_slist_append (context->waiters, &waiter); + + if (!loop_internal_waiter) + UNLOCK_CONTEXT (context); + g_cond_wait (cond, mutex); + if (!loop_internal_waiter) + LOCK_CONTEXT (context); + + context->waiters = g_slist_remove (context->waiters, &waiter); + } + + if (!context->owner) + { + context->owner = self; + g_assert (context->owner_count == 0); + } + + if (context->owner == self) + { + context->owner_count++; + result = TRUE; + } + + if (!loop_internal_waiter) + UNLOCK_CONTEXT (context); + + return result; +} + +/** + * g_main_context_prepare: + * @context: a #GMainContext + * @priority: location to store priority of highest priority + * source already ready. + * + * Prepares to poll sources within a main loop. The resulting information + * for polling is determined by calling g_main_context_query (). + * + * Return value: %TRUE if some source is ready to be dispatched + * prior to polling. + **/ +gboolean +g_main_context_prepare (GMainContext *context, + gint *priority) +{ + gint i; + gint n_ready = 0; + gint current_priority = G_MAXINT; + GSource *source; + + if (context == NULL) + context = g_main_context_default (); + + LOCK_CONTEXT (context); + + context->time_is_fresh = FALSE; + + if (context->in_check_or_prepare) + { + g_warning ("g_main_context_prepare() called recursively from within a source's check() or " + "prepare() member."); + UNLOCK_CONTEXT (context); + return FALSE; + } + +#if 0 + /* If recursing, finish up current dispatch, before starting over */ + if (context->pending_dispatches) + { + if (dispatch) + g_main_dispatch (context, ¤t_time); + + UNLOCK_CONTEXT (context); + return TRUE; + } +#endif + + /* If recursing, clear list of pending dispatches */ + + for (i = 0; i < context->pending_dispatches->len; i++) + { + if (context->pending_dispatches->pdata[i]) + SOURCE_UNREF ((GSource *)context->pending_dispatches->pdata[i], context); + } + g_ptr_array_set_size (context->pending_dispatches, 0); + + /* Prepare all sources */ + + context->timeout = -1; + + source = next_valid_source (context, NULL); + while (source) + { + gint source_timeout = -1; + + if ((n_ready > 0) && (source->priority > current_priority)) + { + SOURCE_UNREF (source, context); + break; + } + if (SOURCE_BLOCKED (source)) + goto next; + + if (!(source->flags & G_SOURCE_READY)) + { + gboolean result; + gboolean (*prepare) (GSource *source, + gint *timeout); + + prepare = source->source_funcs->prepare; + context->in_check_or_prepare++; + UNLOCK_CONTEXT (context); + + result = (*prepare) (source, &source_timeout); + + LOCK_CONTEXT (context); + context->in_check_or_prepare--; + + if (result) + { + GSource *ready_source = source; + + while (ready_source) + { + ready_source->flags |= G_SOURCE_READY; + ready_source = ready_source->priv ? ready_source->priv->parent_source : NULL; + } + } + } + + if (source->flags & G_SOURCE_READY) + { + n_ready++; + current_priority = source->priority; + context->timeout = 0; + } + + if (source_timeout >= 0) + { + if (context->timeout < 0) + context->timeout = source_timeout; + else + context->timeout = MIN (context->timeout, source_timeout); + } + + next: + source = next_valid_source (context, source); + } + + UNLOCK_CONTEXT (context); + + if (priority) + *priority = current_priority; + + return (n_ready > 0); +} + +/** + * g_main_context_query: + * @context: a #GMainContext + * @max_priority: maximum priority source to check + * @timeout_: (out): location to store timeout to be used in polling + * @fds: (out caller-allocates) (array length=n_fds): location to + * store #GPollFD records that need to be polled. + * @n_fds: length of @fds. + * + * Determines information necessary to poll this main loop. + * + * Return value: the number of records actually stored in @fds, + * or, if more than @n_fds records need to be stored, the number + * of records that need to be stored. + **/ +gint +g_main_context_query (GMainContext *context, + gint max_priority, + gint *timeout, + GPollFD *fds, + gint n_fds) +{ + gint n_poll; + GPollRec *pollrec; + + LOCK_CONTEXT (context); + + pollrec = context->poll_records; + n_poll = 0; + while (pollrec && max_priority >= pollrec->priority) + { + /* We need to include entries with fd->events == 0 in the array because + * otherwise if the application changes fd->events behind our back and + * makes it non-zero, we'll be out of sync when we check the fds[] array. + * (Changing fd->events after adding an FD wasn't an anticipated use of + * this API, but it occurs in practice.) */ + if (n_poll < n_fds) + { + fds[n_poll].fd = pollrec->fd->fd; + /* In direct contradiction to the Unix98 spec, IRIX runs into + * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL + * flags in the events field of the pollfd while it should + * just ignoring them. So we mask them out here. + */ + fds[n_poll].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL); + fds[n_poll].revents = 0; + } + + pollrec = pollrec->next; + n_poll++; + } + + context->poll_changed = FALSE; + + if (timeout) + { + *timeout = context->timeout; + if (*timeout != 0) + context->time_is_fresh = FALSE; + } + + UNLOCK_CONTEXT (context); + + return n_poll; +} + +/** + * g_main_context_check: + * @context: a #GMainContext + * @max_priority: the maximum numerical priority of sources to check + * @fds: (array length=n_fds): array of #GPollFD's that was passed to + * the last call to g_main_context_query() + * @n_fds: return value of g_main_context_query() + * + * Passes the results of polling back to the main loop. + * + * Return value: %TRUE if some sources are ready to be dispatched. + **/ +gboolean +g_main_context_check (GMainContext *context, + gint max_priority, + GPollFD *fds, + gint n_fds) +{ + GSource *source; + GPollRec *pollrec; + gint n_ready = 0; + gint i; + + LOCK_CONTEXT (context); + + if (context->in_check_or_prepare) + { + g_warning ("g_main_context_check() called recursively from within a source's check() or " + "prepare() member."); + UNLOCK_CONTEXT (context); + return FALSE; + } + + if (context->wake_up_rec.events) + g_wakeup_acknowledge (context->wakeup); + + /* If the set of poll file descriptors changed, bail out + * and let the main loop rerun + */ + if (context->poll_changed) + { + UNLOCK_CONTEXT (context); + return FALSE; + } + + pollrec = context->poll_records; + i = 0; + while (i < n_fds) + { + if (pollrec->fd->events) + pollrec->fd->revents = fds[i].revents; + + pollrec = pollrec->next; + i++; + } + + source = next_valid_source (context, NULL); + while (source) + { + if ((n_ready > 0) && (source->priority > max_priority)) + { + SOURCE_UNREF (source, context); + break; + } + if (SOURCE_BLOCKED (source)) + goto next; + + if (!(source->flags & G_SOURCE_READY)) + { + gboolean result; + gboolean (*check) (GSource *source); + + check = source->source_funcs->check; + + context->in_check_or_prepare++; + UNLOCK_CONTEXT (context); + + result = (*check) (source); + + LOCK_CONTEXT (context); + context->in_check_or_prepare--; + + if (result) + { + GSource *ready_source = source; + + while (ready_source) + { + ready_source->flags |= G_SOURCE_READY; + ready_source = ready_source->priv ? ready_source->priv->parent_source : NULL; + } + } + } + + if (source->flags & G_SOURCE_READY) + { + source->ref_count++; + g_ptr_array_add (context->pending_dispatches, source); + + n_ready++; + + /* never dispatch sources with less priority than the first + * one we choose to dispatch + */ + max_priority = source->priority; + } + + next: + source = next_valid_source (context, source); + } + + UNLOCK_CONTEXT (context); + + return n_ready > 0; +} + +/** + * g_main_context_dispatch: + * @context: a #GMainContext + * + * Dispatches all pending sources. + **/ +void +g_main_context_dispatch (GMainContext *context) +{ + LOCK_CONTEXT (context); + + if (context->pending_dispatches->len > 0) + { + g_main_dispatch (context); + } + + UNLOCK_CONTEXT (context); +} + +/* HOLDS context lock */ +static gboolean +g_main_context_iterate (GMainContext *context, + gboolean block, + gboolean dispatch, + GThread *self) +{ + gint max_priority; + gint timeout; + gboolean some_ready; + gint nfds, allocated_nfds; + GPollFD *fds = NULL; + + UNLOCK_CONTEXT (context); + + if (!g_main_context_acquire (context)) + { + gboolean got_ownership; + + LOCK_CONTEXT (context); + + if (!block) + return FALSE; + + got_ownership = g_main_context_wait (context, + &context->cond, + &context->mutex); + + if (!got_ownership) + return FALSE; + } + else + LOCK_CONTEXT (context); + + if (!context->cached_poll_array) + { + context->cached_poll_array_size = context->n_poll_records; + context->cached_poll_array = g_new (GPollFD, context->n_poll_records); + } + + allocated_nfds = context->cached_poll_array_size; + fds = context->cached_poll_array; + + UNLOCK_CONTEXT (context); + + g_main_context_prepare (context, &max_priority); + + while ((nfds = g_main_context_query (context, max_priority, &timeout, fds, + allocated_nfds)) > allocated_nfds) + { + LOCK_CONTEXT (context); + g_free (fds); + context->cached_poll_array_size = allocated_nfds = nfds; + context->cached_poll_array = fds = g_new (GPollFD, nfds); + UNLOCK_CONTEXT (context); + } + + if (!block) + timeout = 0; + + g_main_context_poll (context, timeout, max_priority, fds, nfds); + + some_ready = g_main_context_check (context, max_priority, fds, nfds); + + if (dispatch) + g_main_context_dispatch (context); + + g_main_context_release (context); + + LOCK_CONTEXT (context); + + return some_ready; +} + +/** + * g_main_context_pending: + * @context: a #GMainContext (if %NULL, the default context will be used) + * + * Checks if any sources have pending events for the given context. + * + * Return value: %TRUE if events are pending. + **/ +gboolean +g_main_context_pending (GMainContext *context) +{ + gboolean retval; + + if (!context) + context = g_main_context_default(); + + LOCK_CONTEXT (context); + retval = g_main_context_iterate (context, FALSE, FALSE, G_THREAD_SELF); + UNLOCK_CONTEXT (context); + + return retval; +} + +/** + * g_main_context_iteration: + * @context: a #GMainContext (if %NULL, the default context will be used) + * @may_block: whether the call may block. + * + * Runs a single iteration for the given main loop. This involves + * checking to see if any event sources are ready to be processed, + * then if no events sources are ready and @may_block is %TRUE, waiting + * for a source to become ready, then dispatching the highest priority + * events sources that are ready. Otherwise, if @may_block is %FALSE + * sources are not waited to become ready, only those highest priority + * events sources will be dispatched (if any), that are ready at this + * given moment without further waiting. + * + * Note that even when @may_block is %TRUE, it is still possible for + * g_main_context_iteration() to return %FALSE, since the the wait may + * be interrupted for other reasons than an event source becoming ready. + * + * Return value: %TRUE if events were dispatched. + **/ +gboolean +g_main_context_iteration (GMainContext *context, gboolean may_block) +{ + gboolean retval; + + if (!context) + context = g_main_context_default(); + + LOCK_CONTEXT (context); + retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF); + UNLOCK_CONTEXT (context); + + return retval; +} + +/** + * g_main_loop_new: + * @context: (allow-none): a #GMainContext (if %NULL, the default context will be used). + * @is_running: set to %TRUE to indicate that the loop is running. This + * is not very important since calling g_main_loop_run() will set this to + * %TRUE anyway. + * + * Creates a new #GMainLoop structure. + * + * Return value: a new #GMainLoop. + **/ +GMainLoop * +g_main_loop_new (GMainContext *context, + gboolean is_running) +{ + GMainLoop *loop; + + if (!context) + context = g_main_context_default(); + + g_main_context_ref (context); + + loop = g_new0 (GMainLoop, 1); + loop->context = context; + loop->is_running = is_running != FALSE; + loop->ref_count = 1; + + return loop; +} + +/** + * g_main_loop_ref: + * @loop: a #GMainLoop + * + * Increases the reference count on a #GMainLoop object by one. + * + * Return value: @loop + **/ +GMainLoop * +g_main_loop_ref (GMainLoop *loop) +{ + g_return_val_if_fail (loop != NULL, NULL); + g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL); + + g_atomic_int_inc (&loop->ref_count); + + return loop; +} + +/** + * g_main_loop_unref: + * @loop: a #GMainLoop + * + * Decreases the reference count on a #GMainLoop object by one. If + * the result is zero, free the loop and free all associated memory. + **/ +void +g_main_loop_unref (GMainLoop *loop) +{ + g_return_if_fail (loop != NULL); + g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); + + if (!g_atomic_int_dec_and_test (&loop->ref_count)) + return; + + g_main_context_unref (loop->context); + g_free (loop); +} + +/** + * g_main_loop_run: + * @loop: a #GMainLoop + * + * Runs a main loop until g_main_loop_quit() is called on the loop. + * If this is called for the thread of the loop's #GMainContext, + * it will process events from the loop, otherwise it will + * simply wait. + **/ +void +g_main_loop_run (GMainLoop *loop) +{ + GThread *self = G_THREAD_SELF; + + g_return_if_fail (loop != NULL); + g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); + + if (!g_main_context_acquire (loop->context)) + { + gboolean got_ownership = FALSE; + + /* Another thread owns this context */ + LOCK_CONTEXT (loop->context); + + g_atomic_int_inc (&loop->ref_count); + + if (!loop->is_running) + loop->is_running = TRUE; + + while (loop->is_running && !got_ownership) + got_ownership = g_main_context_wait (loop->context, + &loop->context->cond, + &loop->context->mutex); + + if (!loop->is_running) + { + UNLOCK_CONTEXT (loop->context); + if (got_ownership) + g_main_context_release (loop->context); + g_main_loop_unref (loop); + return; + } + + g_assert (got_ownership); + } + else + LOCK_CONTEXT (loop->context); + + if (loop->context->in_check_or_prepare) + { + g_warning ("g_main_loop_run(): called recursively from within a source's " + "check() or prepare() member, iteration not possible."); + return; + } + + g_atomic_int_inc (&loop->ref_count); + loop->is_running = TRUE; + while (loop->is_running) + g_main_context_iterate (loop->context, TRUE, TRUE, self); + + UNLOCK_CONTEXT (loop->context); + + g_main_context_release (loop->context); + + g_main_loop_unref (loop); +} + +/** + * g_main_loop_quit: + * @loop: a #GMainLoop + * + * Stops a #GMainLoop from running. Any calls to g_main_loop_run() + * for the loop will return. + * + * Note that sources that have already been dispatched when + * g_main_loop_quit() is called will still be executed. + **/ +void +g_main_loop_quit (GMainLoop *loop) +{ + g_return_if_fail (loop != NULL); + g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0); + + LOCK_CONTEXT (loop->context); + loop->is_running = FALSE; + g_wakeup_signal (loop->context->wakeup); + + g_cond_broadcast (&loop->context->cond); + + UNLOCK_CONTEXT (loop->context); +} + +/** + * g_main_loop_is_running: + * @loop: a #GMainLoop. + * + * Checks to see if the main loop is currently being run via g_main_loop_run(). + * + * Return value: %TRUE if the mainloop is currently being run. + **/ +gboolean +g_main_loop_is_running (GMainLoop *loop) +{ + g_return_val_if_fail (loop != NULL, FALSE); + g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE); + + return loop->is_running; +} + +/** + * g_main_loop_get_context: + * @loop: a #GMainLoop. + * + * Returns the #GMainContext of @loop. + * + * Return value: (transfer none): the #GMainContext of @loop + **/ +GMainContext * +g_main_loop_get_context (GMainLoop *loop) +{ + g_return_val_if_fail (loop != NULL, NULL); + g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL); + + return loop->context; +} + +/* HOLDS: context's lock */ +static void +g_main_context_poll (GMainContext *context, + gint timeout, + gint priority, + GPollFD *fds, + gint n_fds) +{ +#ifdef G_MAIN_POLL_DEBUG + GTimer *poll_timer; + GPollRec *pollrec; + gint i; +#endif + + GPollFunc poll_func; + + if (n_fds || timeout != 0) + { +#ifdef G_MAIN_POLL_DEBUG + if (_g_main_poll_debug) + { + g_print ("polling context=%p n=%d timeout=%d\n", + context, n_fds, timeout); + poll_timer = g_timer_new (); + } +#endif + + LOCK_CONTEXT (context); + + poll_func = context->poll_func; + + UNLOCK_CONTEXT (context); + if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR) + { +#ifndef G_OS_WIN32 + g_warning ("poll(2) failed due to: %s.", + g_strerror (errno)); +#else + /* If g_poll () returns -1, it has already called g_warning() */ +#endif + } + +#ifdef G_MAIN_POLL_DEBUG + if (_g_main_poll_debug) + { + LOCK_CONTEXT (context); + + g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds", + n_fds, + timeout, + g_timer_elapsed (poll_timer, NULL)); + g_timer_destroy (poll_timer); + pollrec = context->poll_records; + + while (pollrec != NULL) + { + i = 0; + while (i < n_fds) + { + if (fds[i].fd == pollrec->fd->fd && + pollrec->fd->events && + fds[i].revents) + { + g_print (" [" G_POLLFD_FORMAT " :", fds[i].fd); + if (fds[i].revents & G_IO_IN) + g_print ("i"); + if (fds[i].revents & G_IO_OUT) + g_print ("o"); + if (fds[i].revents & G_IO_PRI) + g_print ("p"); + if (fds[i].revents & G_IO_ERR) + g_print ("e"); + if (fds[i].revents & G_IO_HUP) + g_print ("h"); + if (fds[i].revents & G_IO_NVAL) + g_print ("n"); + g_print ("]"); + } + i++; + } + pollrec = pollrec->next; + } + g_print ("\n"); + + UNLOCK_CONTEXT (context); + } +#endif + } /* if (n_fds || timeout != 0) */ +} + +/** + * g_main_context_add_poll: + * @context: a #GMainContext (or %NULL for the default context) + * @fd: a #GPollFD structure holding information about a file + * descriptor to watch. + * @priority: the priority for this file descriptor which should be + * the same as the priority used for g_source_attach() to ensure that the + * file descriptor is polled whenever the results may be needed. + * + * Adds a file descriptor to the set of file descriptors polled for + * this context. This will very seldom be used directly. Instead + * a typical event source will use g_source_add_poll() instead. + **/ +void +g_main_context_add_poll (GMainContext *context, + GPollFD *fd, + gint priority) +{ + if (!context) + context = g_main_context_default (); + + g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); + g_return_if_fail (fd); + + LOCK_CONTEXT (context); + g_main_context_add_poll_unlocked (context, priority, fd); + UNLOCK_CONTEXT (context); +} + +/* HOLDS: main_loop_lock */ +static void +g_main_context_add_poll_unlocked (GMainContext *context, + gint priority, + GPollFD *fd) +{ + GPollRec *prevrec, *nextrec; + GPollRec *newrec = g_slice_new (GPollRec); + + /* This file descriptor may be checked before we ever poll */ + fd->revents = 0; + newrec->fd = fd; + newrec->priority = priority; + + prevrec = context->poll_records_tail; + nextrec = NULL; + while (prevrec && priority < prevrec->priority) + { + nextrec = prevrec; + prevrec = prevrec->prev; + } + + if (prevrec) + prevrec->next = newrec; + else + context->poll_records = newrec; + + newrec->prev = prevrec; + newrec->next = nextrec; + + if (nextrec) + nextrec->prev = newrec; + else + context->poll_records_tail = newrec; + + context->n_poll_records++; + + context->poll_changed = TRUE; + + /* Now wake up the main loop if it is waiting in the poll() */ + g_wakeup_signal (context->wakeup); +} + +/** + * g_main_context_remove_poll: + * @context:a #GMainContext + * @fd: a #GPollFD descriptor previously added with g_main_context_add_poll() + * + * Removes file descriptor from the set of file descriptors to be + * polled for a particular context. + **/ +void +g_main_context_remove_poll (GMainContext *context, + GPollFD *fd) +{ + if (!context) + context = g_main_context_default (); + + g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); + g_return_if_fail (fd); + + LOCK_CONTEXT (context); + g_main_context_remove_poll_unlocked (context, fd); + UNLOCK_CONTEXT (context); +} + +static void +g_main_context_remove_poll_unlocked (GMainContext *context, + GPollFD *fd) +{ + GPollRec *pollrec, *prevrec, *nextrec; + + prevrec = NULL; + pollrec = context->poll_records; + + while (pollrec) + { + nextrec = pollrec->next; + if (pollrec->fd == fd) + { + if (prevrec != NULL) + prevrec->next = nextrec; + else + context->poll_records = nextrec; + + if (nextrec != NULL) + nextrec->prev = prevrec; + else + context->poll_records_tail = prevrec; + + g_slice_free (GPollRec, pollrec); + + context->n_poll_records--; + break; + } + prevrec = pollrec; + pollrec = nextrec; + } + + context->poll_changed = TRUE; + + /* Now wake up the main loop if it is waiting in the poll() */ + g_wakeup_signal (context->wakeup); +} + +/** + * g_source_get_current_time: + * @source: a #GSource + * @timeval: #GTimeVal structure in which to store current time. + * + * This function ignores @source and is otherwise the same as + * g_get_current_time(). + * + * Deprecated: 2.28: use g_source_get_time() instead + **/ +void +g_source_get_current_time (GSource *source, + GTimeVal *timeval) +{ + g_get_current_time (timeval); +} + +/** + * g_source_get_time: + * @source: a #GSource + * + * Gets the time to be used when checking this source. The advantage of + * calling this function over calling g_get_monotonic_time() directly is + * that when checking multiple sources, GLib can cache a single value + * instead of having to repeatedly get the system monotonic time. + * + * The time here is the system monotonic time, if available, or some + * other reasonable alternative otherwise. See g_get_monotonic_time(). + * + * Returns: the monotonic time in microseconds + * + * Since: 2.28 + **/ +gint64 +g_source_get_time (GSource *source) +{ + GMainContext *context; + gint64 result; + + g_return_val_if_fail (source->context != NULL, 0); + + context = source->context; + + LOCK_CONTEXT (context); + + if (!context->time_is_fresh) + { + context->time = g_get_monotonic_time (); + context->time_is_fresh = TRUE; + } + + result = context->time; + + UNLOCK_CONTEXT (context); + + return result; +} + +/** + * g_main_context_set_poll_func: + * @context: a #GMainContext + * @func: the function to call to poll all file descriptors + * + * Sets the function to use to handle polling of file descriptors. It + * will be used instead of the poll() system call + * (or GLib's replacement function, which is used where + * poll() isn't available). + * + * This function could possibly be used to integrate the GLib event + * loop with an external event loop. + **/ +void +g_main_context_set_poll_func (GMainContext *context, + GPollFunc func) +{ + if (!context) + context = g_main_context_default (); + + g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); + + LOCK_CONTEXT (context); + + if (func) + context->poll_func = func; + else + context->poll_func = g_poll; + + UNLOCK_CONTEXT (context); +} + +/** + * g_main_context_get_poll_func: + * @context: a #GMainContext + * + * Gets the poll function set by g_main_context_set_poll_func(). + * + * Return value: the poll function + **/ +GPollFunc +g_main_context_get_poll_func (GMainContext *context) +{ + GPollFunc result; + + if (!context) + context = g_main_context_default (); + + g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL); + + LOCK_CONTEXT (context); + result = context->poll_func; + UNLOCK_CONTEXT (context); + + return result; +} + +/** + * g_main_context_wakeup: + * @context: a #GMainContext + * + * If @context is currently waiting in a poll(), interrupt + * the poll(), and continue the iteration process. + **/ +void +g_main_context_wakeup (GMainContext *context) +{ + if (!context) + context = g_main_context_default (); + + g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); + + g_wakeup_signal (context->wakeup); +} + +/** + * g_main_context_is_owner: + * @context: a #GMainContext + * + * Determines whether this thread holds the (recursive) + * ownership of this #GMainContext. This is useful to + * know before waiting on another thread that may be + * blocking to get ownership of @context. + * + * Returns: %TRUE if current thread is owner of @context. + * + * Since: 2.10 + **/ +gboolean +g_main_context_is_owner (GMainContext *context) +{ + gboolean is_owner; + + if (!context) + context = g_main_context_default (); + + LOCK_CONTEXT (context); + is_owner = context->owner == G_THREAD_SELF; + UNLOCK_CONTEXT (context); + + return is_owner; +} + +/* Timeouts */ + +static void +g_timeout_set_expiration (GTimeoutSource *timeout_source, + gint64 current_time) +{ + timeout_source->expiration = current_time + + (guint64) timeout_source->interval * 1000; + + if (timeout_source->seconds) + { + gint64 remainder; + static gint timer_perturb = -1; + + if (timer_perturb == -1) + { + /* + * we want a per machine/session unique 'random' value; try the dbus + * address first, that has a UUID in it. If there is no dbus, use the + * hostname for hashing. + */ + const char *session_bus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS"); + if (!session_bus_address) + session_bus_address = g_getenv ("HOSTNAME"); + if (session_bus_address) + timer_perturb = ABS ((gint) g_str_hash (session_bus_address)) % 1000000; + else + timer_perturb = 0; + } + + /* We want the microseconds part of the timeout to land on the + * 'timer_perturb' mark, but we need to make sure we don't try to + * set the timeout in the past. We do this by ensuring that we + * always only *increase* the expiration time by adding a full + * second in the case that the microsecond portion decreases. + */ + timeout_source->expiration -= timer_perturb; + + remainder = timeout_source->expiration % 1000000; + if (remainder >= 1000000/4) + timeout_source->expiration += 1000000; + + timeout_source->expiration -= remainder; + timeout_source->expiration += timer_perturb; + } +} + +static gboolean +g_timeout_prepare (GSource *source, + gint *timeout) +{ + GTimeoutSource *timeout_source = (GTimeoutSource *) source; + gint64 now = g_source_get_time (source); + + if (now < timeout_source->expiration) + { + /* Round up to ensure that we don't try again too early */ + *timeout = (timeout_source->expiration - now + 999) / 1000; + return FALSE; + } + + *timeout = 0; + return TRUE; +} + +static gboolean +g_timeout_check (GSource *source) +{ + GTimeoutSource *timeout_source = (GTimeoutSource *) source; + gint64 now = g_source_get_time (source); + + return timeout_source->expiration <= now; +} + +static gboolean +g_timeout_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GTimeoutSource *timeout_source = (GTimeoutSource *)source; + gboolean again; + + if (!callback) + { + g_warning ("Timeout source dispatched without callback\n" + "You must call g_source_set_callback()."); + return FALSE; + } + + again = callback (user_data); + + if (again) + g_timeout_set_expiration (timeout_source, g_source_get_time (source)); + + return again; +} + +/** + * g_timeout_source_new: + * @interval: the timeout interval in milliseconds. + * + * Creates a new timeout source. + * + * The source will not initially be associated with any #GMainContext + * and must be added to one with g_source_attach() before it will be + * executed. + * + * The interval given is in terms of monotonic time, not wall clock + * time. See g_get_monotonic_time(). + * + * Return value: the newly-created timeout source + **/ +GSource * +g_timeout_source_new (guint interval) +{ + GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource)); + GTimeoutSource *timeout_source = (GTimeoutSource *)source; + + timeout_source->interval = interval; + g_timeout_set_expiration (timeout_source, g_get_monotonic_time ()); + + return source; +} + +/** + * g_timeout_source_new_seconds: + * @interval: the timeout interval in seconds + * + * Creates a new timeout source. + * + * The source will not initially be associated with any #GMainContext + * and must be added to one with g_source_attach() before it will be + * executed. + * + * The scheduling granularity/accuracy of this timeout source will be + * in seconds. + * + * The interval given in terms of monotonic time, not wall clock time. + * See g_get_monotonic_time(). + * + * Return value: the newly-created timeout source + * + * Since: 2.14 + **/ +GSource * +g_timeout_source_new_seconds (guint interval) +{ + GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource)); + GTimeoutSource *timeout_source = (GTimeoutSource *)source; + + timeout_source->interval = 1000 * interval; + timeout_source->seconds = TRUE; + + g_timeout_set_expiration (timeout_source, g_get_monotonic_time ()); + + return source; +} + + +/** + * g_timeout_add_full: + * @priority: the priority of the timeout source. Typically this will be in + * the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH. + * @interval: the time between calls to the function, in milliseconds + * (1/1000ths of a second) + * @function: function to call + * @data: data to pass to @function + * @notify: function to call when the timeout is removed, or %NULL + * + * Sets a function to be called at regular intervals, with the given + * priority. The function is called repeatedly until it returns + * %FALSE, at which point the timeout is automatically destroyed and + * the function will not be called again. The @notify function is + * called when the timeout is destroyed. The first call to the + * function will be at the end of the first @interval. + * + * Note that timeout functions may be delayed, due to the processing of other + * event sources. Thus they should not be relied on for precise timing. + * After each call to the timeout function, the time of the next + * timeout is recalculated based on the current time and the given interval + * (it does not try to 'catch up' time lost in delays). + * + * This internally creates a main loop source using g_timeout_source_new() + * and attaches it to the main loop context using g_source_attach(). You can + * do these steps manually if you need greater control. + * + * The interval given in terms of monotonic time, not wall clock time. + * See g_get_monotonic_time(). + * + * Return value: the ID (greater than 0) of the event source. + * Rename to: g_timeout_add + **/ +guint +g_timeout_add_full (gint priority, + guint interval, + GSourceFunc function, + gpointer data, + GDestroyNotify notify) +{ + GSource *source; + guint id; + + g_return_val_if_fail (function != NULL, 0); + + source = g_timeout_source_new (interval); + + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority (source, priority); + + g_source_set_callback (source, function, data, notify); + id = g_source_attach (source, NULL); + g_source_unref (source); + + return id; +} + +/** + * g_timeout_add: + * @interval: the time between calls to the function, in milliseconds + * (1/1000ths of a second) + * @function: function to call + * @data: data to pass to @function + * + * Sets a function to be called at regular intervals, with the default + * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly + * until it returns %FALSE, at which point the timeout is automatically + * destroyed and the function will not be called again. The first call + * to the function will be at the end of the first @interval. + * + * Note that timeout functions may be delayed, due to the processing of other + * event sources. Thus they should not be relied on for precise timing. + * After each call to the timeout function, the time of the next + * timeout is recalculated based on the current time and the given interval + * (it does not try to 'catch up' time lost in delays). + * + * If you want to have a timer in the "seconds" range and do not care + * about the exact time of the first call of the timer, use the + * g_timeout_add_seconds() function; this function allows for more + * optimizations and more efficient system power usage. + * + * This internally creates a main loop source using g_timeout_source_new() + * and attaches it to the main loop context using g_source_attach(). You can + * do these steps manually if you need greater control. + * + * The interval given is in terms of monotonic time, not wall clock + * time. See g_get_monotonic_time(). + * + * Return value: the ID (greater than 0) of the event source. + **/ +guint +g_timeout_add (guint32 interval, + GSourceFunc function, + gpointer data) +{ + return g_timeout_add_full (G_PRIORITY_DEFAULT, + interval, function, data, NULL); +} + +/** + * g_timeout_add_seconds_full: + * @priority: the priority of the timeout source. Typically this will be in + * the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH. + * @interval: the time between calls to the function, in seconds + * @function: function to call + * @data: data to pass to @function + * @notify: function to call when the timeout is removed, or %NULL + * + * Sets a function to be called at regular intervals, with @priority. + * The function is called repeatedly until it returns %FALSE, at which + * point the timeout is automatically destroyed and the function will + * not be called again. + * + * Unlike g_timeout_add(), this function operates at whole second granularity. + * The initial starting point of the timer is determined by the implementation + * and the implementation is expected to group multiple timers together so that + * they fire all at the same time. + * To allow this grouping, the @interval to the first timer is rounded + * and can deviate up to one second from the specified interval. + * Subsequent timer iterations will generally run at the specified interval. + * + * Note that timeout functions may be delayed, due to the processing of other + * event sources. Thus they should not be relied on for precise timing. + * After each call to the timeout function, the time of the next + * timeout is recalculated based on the current time and the given @interval + * + * If you want timing more precise than whole seconds, use g_timeout_add() + * instead. + * + * The grouping of timers to fire at the same time results in a more power + * and CPU efficient behavior so if your timer is in multiples of seconds + * and you don't require the first timer exactly one second from now, the + * use of g_timeout_add_seconds() is preferred over g_timeout_add(). + * + * This internally creates a main loop source using + * g_timeout_source_new_seconds() and attaches it to the main loop context + * using g_source_attach(). You can do these steps manually if you need + * greater control. + * + * The interval given is in terms of monotonic time, not wall clock + * time. See g_get_monotonic_time(). + * + * Return value: the ID (greater than 0) of the event source. + * + * Rename to: g_timeout_add_seconds + * Since: 2.14 + **/ +guint +g_timeout_add_seconds_full (gint priority, + guint32 interval, + GSourceFunc function, + gpointer data, + GDestroyNotify notify) +{ + GSource *source; + guint id; + + g_return_val_if_fail (function != NULL, 0); + + source = g_timeout_source_new_seconds (interval); + + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority (source, priority); + + g_source_set_callback (source, function, data, notify); + id = g_source_attach (source, NULL); + g_source_unref (source); + + return id; +} + +/** + * g_timeout_add_seconds: + * @interval: the time between calls to the function, in seconds + * @function: function to call + * @data: data to pass to @function + * + * Sets a function to be called at regular intervals with the default + * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly until + * it returns %FALSE, at which point the timeout is automatically destroyed + * and the function will not be called again. + * + * This internally creates a main loop source using + * g_timeout_source_new_seconds() and attaches it to the main loop context + * using g_source_attach(). You can do these steps manually if you need + * greater control. Also see g_timeout_add_seconds_full(). + * + * Note that the first call of the timer may not be precise for timeouts + * of one second. If you need finer precision and have such a timeout, + * you may want to use g_timeout_add() instead. + * + * The interval given is in terms of monotonic time, not wall clock + * time. See g_get_monotonic_time(). + * + * Return value: the ID (greater than 0) of the event source. + * + * Since: 2.14 + **/ +guint +g_timeout_add_seconds (guint interval, + GSourceFunc function, + gpointer data) +{ + g_return_val_if_fail (function != NULL, 0); + + return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL); +} + +/* Child watch functions */ + +#ifdef G_OS_WIN32 + +static gboolean +g_child_watch_prepare (GSource *source, + gint *timeout) +{ + *timeout = -1; + return FALSE; +} + +static gboolean +g_child_watch_check (GSource *source) +{ + GChildWatchSource *child_watch_source; + gboolean child_exited; + + child_watch_source = (GChildWatchSource *) source; + + child_exited = child_watch_source->poll.revents & G_IO_IN; + + if (child_exited) + { + DWORD child_status; + + /* + * Note: We do _not_ check for the special value of STILL_ACTIVE + * since we know that the process has exited and doing so runs into + * problems if the child process "happens to return STILL_ACTIVE(259)" + * as Microsoft's Platform SDK puts it. + */ + if (!GetExitCodeProcess (child_watch_source->pid, &child_status)) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg); + g_free (emsg); + + child_watch_source->child_status = -1; + } + else + child_watch_source->child_status = child_status; + } + + return child_exited; +} + +static void +g_child_watch_finalize (GSource *source) +{ +} + +#else /* G_OS_WIN32 */ + +static void +wake_source (GSource *source) +{ + GMainContext *context; + + /* This should be thread-safe: + * + * - if the source is currently being added to a context, that + * context will be woken up anyway + * + * - if the source is currently being destroyed, we simply need not + * to crash: + * + * - the memory for the source will remain valid until after the + * source finalize function was called (which would remove the + * source from the global list which we are currently holding the + * lock for) + * + * - the GMainContext will either be NULL or point to a live + * GMainContext + * + * - the GMainContext will remain valid since we hold the + * main_context_list lock + * + * Since we are holding a lot of locks here, don't try to enter any + * more GMainContext functions for fear of dealock -- just hit the + * GWakeup and run. Even if that's safe now, it could easily become + * unsafe with some very minor changes in the future, and signal + * handling is not the most well-tested codepath. + */ + G_LOCK(main_context_list); + context = source->context; + if (context) + g_wakeup_signal (context->wakeup); + G_UNLOCK(main_context_list); +} + +static void +dispatch_unix_signals (void) +{ + GSList *node; + + /* clear this first incase another one arrives while we're processing */ + any_unix_signal_pending = FALSE; + + G_LOCK(unix_signal_lock); + + /* handle GChildWatchSource instances */ + if (unix_signal_pending[SIGCHLD]) + { + unix_signal_pending[SIGCHLD] = FALSE; + + /* The only way we can do this is to scan all of the children. + * + * The docs promise that we will not reap children that we are not + * explicitly watching, so that ties our hands from calling + * waitpid(-1). We also can't use siginfo's si_pid field since if + * multiple SIGCHLD arrive at the same time, one of them can be + * dropped (since a given UNIX signal can only be pending once). + */ + for (node = unix_child_watches; node; node = node->next) + { + GChildWatchSource *source = node->data; + + if (!source->child_exited) + { + if (waitpid (source->pid, &source->child_status, WNOHANG) > 0) + { + source->child_exited = TRUE; + + wake_source ((GSource *) source); + } + } + } + } + + /* handle GUnixSignalWatchSource instances */ + for (node = unix_signal_watches; node; node = node->next) + { + GUnixSignalWatchSource *source = node->data; + + if (!source->pending) + { + if (unix_signal_pending[source->signum]) + { + unix_signal_pending[source->signum] = FALSE; + source->pending = TRUE; + + wake_source ((GSource *) source); + } + } + } + + G_UNLOCK(unix_signal_lock); +} + +static gboolean +g_child_watch_prepare (GSource *source, + gint *timeout) +{ + GChildWatchSource *child_watch_source; + + child_watch_source = (GChildWatchSource *) source; + + return child_watch_source->child_exited; +} + +static gboolean +g_child_watch_check (GSource *source) +{ + GChildWatchSource *child_watch_source; + + child_watch_source = (GChildWatchSource *) source; + + return child_watch_source->child_exited; +} + +static gboolean +g_unix_signal_watch_prepare (GSource *source, + gint *timeout) +{ + GUnixSignalWatchSource *unix_signal_source; + + unix_signal_source = (GUnixSignalWatchSource *) source; + + return unix_signal_source->pending; +} + +static gboolean +g_unix_signal_watch_check (GSource *source) +{ + GUnixSignalWatchSource *unix_signal_source; + + unix_signal_source = (GUnixSignalWatchSource *) source; + + return unix_signal_source->pending; +} + +static gboolean +g_unix_signal_watch_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GUnixSignalWatchSource *unix_signal_source; + + unix_signal_source = (GUnixSignalWatchSource *) source; + + if (!callback) + { + g_warning ("Unix signal source dispatched without callback\n" + "You must call g_source_set_callback()."); + return FALSE; + } + + (callback) (user_data); + + unix_signal_source->pending = FALSE; + + return TRUE; +} + +static void +ensure_unix_signal_handler_installed_unlocked (int signum) +{ + static sigset_t installed_signal_mask; + static gboolean initialized; + struct sigaction action; + + if (!initialized) + { + sigemptyset (&installed_signal_mask); + g_get_worker_context (); + initialized = TRUE; + } + + if (sigismember (&installed_signal_mask, signum)) + return; + + sigaddset (&installed_signal_mask, signum); + + action.sa_handler = g_unix_signal_handler; + sigemptyset (&action.sa_mask); + action.sa_flags = SA_RESTART | SA_NOCLDSTOP; + sigaction (signum, &action, NULL); +} + +GSource * +_g_main_create_unix_signal_watch (int signum) +{ + GSource *source; + GUnixSignalWatchSource *unix_signal_source; + + source = g_source_new (&g_unix_signal_funcs, sizeof (GUnixSignalWatchSource)); + unix_signal_source = (GUnixSignalWatchSource *) source; + + unix_signal_source->signum = signum; + unix_signal_source->pending = FALSE; + + G_LOCK (unix_signal_lock); + ensure_unix_signal_handler_installed_unlocked (signum); + unix_signal_watches = g_slist_prepend (unix_signal_watches, unix_signal_source); + if (unix_signal_pending[signum]) + unix_signal_source->pending = TRUE; + unix_signal_pending[signum] = FALSE; + G_UNLOCK (unix_signal_lock); + + return source; +} + +static void +g_unix_signal_watch_finalize (GSource *source) +{ + G_LOCK (unix_signal_lock); + unix_signal_watches = g_slist_remove (unix_signal_watches, source); + G_UNLOCK (unix_signal_lock); +} + +static void +g_child_watch_finalize (GSource *source) +{ + G_LOCK (unix_signal_lock); + unix_child_watches = g_slist_remove (unix_child_watches, source); + G_UNLOCK (unix_signal_lock); +} + +#endif /* G_OS_WIN32 */ + +static gboolean +g_child_watch_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + GChildWatchSource *child_watch_source; + GChildWatchFunc child_watch_callback = (GChildWatchFunc) callback; + + child_watch_source = (GChildWatchSource *) source; + + if (!callback) + { + g_warning ("Child watch source dispatched without callback\n" + "You must call g_source_set_callback()."); + return FALSE; + } + + (child_watch_callback) (child_watch_source->pid, child_watch_source->child_status, user_data); + + /* We never keep a child watch source around as the child is gone */ + return FALSE; +} + +#ifndef G_OS_WIN32 + +static void +g_unix_signal_handler (int signum) +{ + unix_signal_pending[signum] = TRUE; + any_unix_signal_pending = TRUE; + + g_wakeup_signal (glib_worker_context->wakeup); +} + +#endif /* !G_OS_WIN32 */ + +/** + * g_child_watch_source_new: + * @pid: process to watch. On POSIX the pid of a child process. On + * Windows a handle for a process (which doesn't have to be a child). + * + * Creates a new child_watch source. + * + * The source will not initially be associated with any #GMainContext + * and must be added to one with g_source_attach() before it will be + * executed. + * + * Note that child watch sources can only be used in conjunction with + * g_spawn... when the %G_SPAWN_DO_NOT_REAP_CHILD + * flag is used. + * + * Note that on platforms where #GPid must be explicitly closed + * (see g_spawn_close_pid()) @pid must not be closed while the + * source is still active. Typically, you will want to call + * g_spawn_close_pid() in the callback function for the source. + * + * Note further that using g_child_watch_source_new() is not + * compatible with calling waitpid(-1) in + * the application. Calling waitpid() for individual pids will + * still work fine. + * + * Return value: the newly-created child watch source + * + * Since: 2.4 + **/ +GSource * +g_child_watch_source_new (GPid pid) +{ + GSource *source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource)); + GChildWatchSource *child_watch_source = (GChildWatchSource *)source; + + child_watch_source->pid = pid; + +#ifdef G_OS_WIN32 + child_watch_source->poll.fd = (gintptr) pid; + child_watch_source->poll.events = G_IO_IN; + + g_source_add_poll (source, &child_watch_source->poll); +#else /* G_OS_WIN32 */ + G_LOCK (unix_signal_lock); + ensure_unix_signal_handler_installed_unlocked (SIGCHLD); + unix_child_watches = g_slist_prepend (unix_child_watches, child_watch_source); + if (waitpid (pid, &child_watch_source->child_status, WNOHANG) > 0) + child_watch_source->child_exited = TRUE; + G_UNLOCK (unix_signal_lock); +#endif /* G_OS_WIN32 */ + + return source; +} + +/** + * g_child_watch_add_full: + * @priority: the priority of the idle source. Typically this will be in the + * range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE. + * @pid: process to watch. On POSIX the pid of a child process. On + * Windows a handle for a process (which doesn't have to be a child). + * @function: function to call + * @data: data to pass to @function + * @notify: function to call when the idle is removed, or %NULL + * + * Sets a function to be called when the child indicated by @pid + * exits, at the priority @priority. + * + * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes() + * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to + * the spawn function for the child watching to work. + * + * Note that on platforms where #GPid must be explicitly closed + * (see g_spawn_close_pid()) @pid must not be closed while the + * source is still active. Typically, you will want to call + * g_spawn_close_pid() in the callback function for the source. + * + * GLib supports only a single callback per process id. + * + * This internally creates a main loop source using + * g_child_watch_source_new() and attaches it to the main loop context + * using g_source_attach(). You can do these steps manually if you + * need greater control. + * + * Return value: the ID (greater than 0) of the event source. + * + * Rename to: g_child_watch_add + * Since: 2.4 + **/ +guint +g_child_watch_add_full (gint priority, + GPid pid, + GChildWatchFunc function, + gpointer data, + GDestroyNotify notify) +{ + GSource *source; + guint id; + + g_return_val_if_fail (function != NULL, 0); + + source = g_child_watch_source_new (pid); + + if (priority != G_PRIORITY_DEFAULT) + g_source_set_priority (source, priority); + + g_source_set_callback (source, (GSourceFunc) function, data, notify); + id = g_source_attach (source, NULL); + g_source_unref (source); + + return id; +} + +/** + * g_child_watch_add: + * @pid: process id to watch. On POSIX the pid of a child process. On + * Windows a handle for a process (which doesn't have to be a child). + * @function: function to call + * @data: data to pass to @function + * + * Sets a function to be called when the child indicated by @pid + * exits, at a default priority, #G_PRIORITY_DEFAULT. + * + * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes() + * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to + * the spawn function for the child watching to work. + * + * Note that on platforms where #GPid must be explicitly closed + * (see g_spawn_close_pid()) @pid must not be closed while the + * source is still active. Typically, you will want to call + * g_spawn_close_pid() in the callback function for the source. + * + * GLib supports only a single callback per process id. + * + * This internally creates a main loop source using + * g_child_watch_source_new() and attaches it to the main loop context + * using g_source_attach(). You can do these steps manually if you + * need greater control. + * + * Return value: the ID (greater than 0) of the event source. + * + * Since: 2.4 + **/ +guint +g_child_watch_add (GPid pid, + GChildWatchFunc function, + gpointer data) +{ + return g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, function, data, NULL); +} + + +/* Idle functions */ + +static gboolean +g_idle_prepare (GSource *source, + gint *timeout) +{ + *timeout = 0; + + return TRUE; +} + +static gboolean +g_idle_check (GSource *source) +{ + return TRUE; +} + +static gboolean +g_idle_dispatch (GSource *source, + GSourceFunc callback, + gpointer user_data) +{ + if (!callback) + { + g_warning ("Idle source dispatched without callback\n" + "You must call g_source_set_callback()."); + return FALSE; + } + + return callback (user_data); +} + +/** + * g_idle_source_new: + * + * Creates a new idle source. + * + * The source will not initially be associated with any #GMainContext + * and must be added to one with g_source_attach() before it will be + * executed. Note that the default priority for idle sources is + * %G_PRIORITY_DEFAULT_IDLE, as compared to other sources which + * have a default priority of %G_PRIORITY_DEFAULT. + * + * Return value: the newly-created idle source + **/ +GSource * +g_idle_source_new (void) +{ + GSource *source; + + source = g_source_new (&g_idle_funcs, sizeof (GSource)); + g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE); + + return source; +} + +/** + * g_idle_add_full: + * @priority: the priority of the idle source. Typically this will be in the + * range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE. + * @function: function to call + * @data: data to pass to @function + * @notify: function to call when the idle is removed, or %NULL + * + * Adds a function to be called whenever there are no higher priority + * events pending. If the function returns %FALSE it is automatically + * removed from the list of event sources and will not be called again. + * + * This internally creates a main loop source using g_idle_source_new() + * and attaches it to the main loop context using g_source_attach(). + * You can do these steps manually if you need greater control. + * + * Return value: the ID (greater than 0) of the event source. + * Rename to: g_idle_add + **/ +guint +g_idle_add_full (gint priority, + GSourceFunc function, + gpointer data, + GDestroyNotify notify) +{ + GSource *source; + guint id; + + g_return_val_if_fail (function != NULL, 0); + + source = g_idle_source_new (); + + if (priority != G_PRIORITY_DEFAULT_IDLE) + g_source_set_priority (source, priority); + + g_source_set_callback (source, function, data, notify); + id = g_source_attach (source, NULL); + g_source_unref (source); + + return id; +} + +/** + * g_idle_add: + * @function: function to call + * @data: data to pass to @function. + * + * Adds a function to be called whenever there are no higher priority + * events pending to the default main loop. The function is given the + * default idle priority, #G_PRIORITY_DEFAULT_IDLE. If the function + * returns %FALSE it is automatically removed from the list of event + * sources and will not be called again. + * + * This internally creates a main loop source using g_idle_source_new() + * and attaches it to the main loop context using g_source_attach(). + * You can do these steps manually if you need greater control. + * + * Return value: the ID (greater than 0) of the event source. + **/ +guint +g_idle_add (GSourceFunc function, + gpointer data) +{ + return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL); +} + +/** + * g_idle_remove_by_data: + * @data: the data for the idle source's callback. + * + * Removes the idle function with the given data. + * + * Return value: %TRUE if an idle source was found and removed. + **/ +gboolean +g_idle_remove_by_data (gpointer data) +{ + return g_source_remove_by_funcs_user_data (&g_idle_funcs, data); +} + +/** + * g_main_context_invoke: + * @context: (allow-none): a #GMainContext, or %NULL + * @function: function to call + * @data: data to pass to @function + * + * Invokes a function in such a way that @context is owned during the + * invocation of @function. + * + * If @context is %NULL then the global default main context — as + * returned by g_main_context_default() — is used. + * + * If @context is owned by the current thread, @function is called + * directly. Otherwise, if @context is the thread-default main context + * of the current thread and g_main_context_acquire() succeeds, then + * @function is called and g_main_context_release() is called + * afterwards. + * + * In any other case, an idle source is created to call @function and + * that source is attached to @context (presumably to be run in another + * thread). The idle source is attached with #G_PRIORITY_DEFAULT + * priority. If you want a different priority, use + * g_main_context_invoke_full(). + * + * Note that, as with normal idle functions, @function should probably + * return %FALSE. If it returns %TRUE, it will be continuously run in a + * loop (and may prevent this call from returning). + * + * Since: 2.28 + **/ +void +g_main_context_invoke (GMainContext *context, + GSourceFunc function, + gpointer data) +{ + g_main_context_invoke_full (context, + G_PRIORITY_DEFAULT, + function, data, NULL); +} + +/** + * g_main_context_invoke_full: + * @context: (allow-none): a #GMainContext, or %NULL + * @priority: the priority at which to run @function + * @function: function to call + * @data: data to pass to @function + * @notify: a function to call when @data is no longer in use, or %NULL. + * + * Invokes a function in such a way that @context is owned during the + * invocation of @function. + * + * This function is the same as g_main_context_invoke() except that it + * lets you specify the priority incase @function ends up being + * scheduled as an idle and also lets you give a #GDestroyNotify for @data. + * + * @notify should not assume that it is called from any particular + * thread or with any particular context acquired. + * + * Since: 2.28 + **/ +void +g_main_context_invoke_full (GMainContext *context, + gint priority, + GSourceFunc function, + gpointer data, + GDestroyNotify notify) +{ + g_return_if_fail (function != NULL); + + if (!context) + context = g_main_context_default (); + + if (g_main_context_is_owner (context)) + { + while (function (data)); + if (notify != NULL) + notify (data); + } + + else + { + GMainContext *thread_default; + + thread_default = g_main_context_get_thread_default (); + + if (!thread_default) + thread_default = g_main_context_default (); + + if (thread_default == context && g_main_context_acquire (context)) + { + while (function (data)); + + g_main_context_release (context); + + if (notify != NULL) + notify (data); + } + else + { + GSource *source; + + source = g_idle_source_new (); + g_source_set_priority (source, priority); + g_source_set_callback (source, function, data, notify); + g_source_attach (source, context); + g_source_unref (source); + } + } +} + +static gpointer +glib_worker_main (gpointer data) +{ + while (TRUE) + { + g_main_context_iteration (glib_worker_context, TRUE); + +#ifdef G_OS_UNIX + if (any_unix_signal_pending) + dispatch_unix_signals (); +#endif + } + + return NULL; /* worst GCC warning message ever... */ +} + +GMainContext * +g_get_worker_context (void) +{ + static gsize initialised; + + if (g_once_init_enter (&initialised)) + { + /* mask all signals in the worker thread */ +#ifdef G_OS_UNIX + sigset_t prev_mask; + sigset_t all; + + sigfillset (&all); + pthread_sigmask (SIG_SETMASK, &all, &prev_mask); +#endif + glib_worker_context = g_main_context_new (); + g_thread_new ("gmain", glib_worker_main, NULL); +#ifdef G_OS_UNIX + pthread_sigmask (SIG_SETMASK, &prev_mask, NULL); +#endif + g_once_init_leave (&initialised, TRUE); + } + + return glib_worker_context; +} diff --git a/glib/glib/gmain.h b/glib/glib/gmain.h new file mode 100644 index 0000000..cba45fd --- /dev/null +++ b/glib/glib/gmain.h @@ -0,0 +1,491 @@ +/* gmain.h - the GLib Main loop + * Copyright (C) 1998-2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_MAIN_H__ +#define __G_MAIN_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +/** + * GMainContext: + * + * The GMainContext struct is an opaque data + * type representing a set of sources to be handled in a main loop. + */ +typedef struct _GMainContext GMainContext; + +/** + * GMainLoop: + * + * The GMainLoop struct is an opaque data type + * representing the main event loop of a GLib or GTK+ application. + */ +typedef struct _GMainLoop GMainLoop; + +/** + * GSource: + * + * The GSource struct is an opaque data type + * representing an event source. + */ +typedef struct _GSource GSource; +typedef struct _GSourcePrivate GSourcePrivate; + +/** + * GSourceCallbackFuncs: + * @ref: Called when a reference is added to the callback object + * @unref: Called when a reference to the callback object is dropped + * @get: Called to extract the callback function and data from the + * callback object. + + * The GSourceCallbackFuncs struct contains + * functions for managing callback objects. + */ +typedef struct _GSourceCallbackFuncs GSourceCallbackFuncs; + +/** + * GSourceFuncs: + * @prepare: Called before all the file descriptors are polled. If the + * source can determine that it is ready here (without waiting for the + * results of the poll() call) it should return %TRUE. It can also return + * a @timeout_ value which should be the maximum timeout (in milliseconds) + * which should be passed to the poll() call. The actual timeout used will + * be -1 if all sources returned -1, or it will be the minimum of all the + * @timeout_ values returned which were >= 0. + * @check: Called after all the file descriptors are polled. The source + * should return %TRUE if it is ready to be dispatched. Note that some + * time may have passed since the previous prepare function was called, + * so the source should be checked again here. + * @dispatch: Called to dispatch the event source, after it has returned + * %TRUE in either its @prepare or its @check function. The @dispatch + * function is passed in a callback function and data. The callback + * function may be %NULL if the source was never connected to a callback + * using g_source_set_callback(). The @dispatch function should call the + * callback function with @user_data and whatever additional parameters + * are needed for this type of event source. + * @finalize: Called when the source is finalized. + * + * The GSourceFuncs struct contains a table of + * functions used to handle event sources in a generic manner. + * + * For idle sources, the prepare and check functions always return %TRUE + * to indicate that the source is always ready to be processed. The prepare + * function also returns a timeout value of 0 to ensure that the poll() call + * doesn't block (since that would be time wasted which could have been spent + * running the idle function). + * + * For timeout sources, the prepare and check functions both return %TRUE + * if the timeout interval has expired. The prepare function also returns + * a timeout value to ensure that the poll() call doesn't block too long + * and miss the next timeout. + * + * For file descriptor sources, the prepare function typically returns %FALSE, + * since it must wait until poll() has been called before it knows whether + * any events need to be processed. It sets the returned timeout to -1 to + * indicate that it doesn't mind how long the poll() call blocks. In the + * check function, it tests the results of the poll() call to see if the + * required condition has been met, and returns %TRUE if so. + */ +typedef struct _GSourceFuncs GSourceFuncs; + +/** + * GPid: + * + * A type which is used to hold a process identification. + * + * On UNIX, processes are identified by a process id (an integer), + * while Windows uses process handles (which are pointers). + * + * GPid is used in GLib only for descendant processes spawned with + * the g_spawn functions. + */ + +/** + * GSourceFunc: + * @user_data: data passed to the function, set when the source was + * created with one of the above functions + * + * Specifies the type of function passed to g_timeout_add(), + * g_timeout_add_full(), g_idle_add(), and g_idle_add_full(). + * + * Returns: %FALSE if the source should be removed + */ +typedef gboolean (*GSourceFunc) (gpointer user_data); + +/** + * GChildWatchFunc: + * @pid: the process id of the child process + * @status: Status information about the child process, + * see waitpid(2) for more information about this field + * @user_data: user data passed to g_child_watch_add() + * + * The type of functions to be called when a child exists. + */ +typedef void (*GChildWatchFunc) (GPid pid, + gint status, + gpointer user_data); +struct _GSource +{ + /*< private >*/ + gpointer callback_data; + GSourceCallbackFuncs *callback_funcs; + + GSourceFuncs *source_funcs; + guint ref_count; + + GMainContext *context; + + gint priority; + guint flags; + guint source_id; + + GSList *poll_fds; + + GSource *prev; + GSource *next; + + char *name; + + GSourcePrivate *priv; +}; + +struct _GSourceCallbackFuncs +{ + void (*ref) (gpointer cb_data); + void (*unref) (gpointer cb_data); + void (*get) (gpointer cb_data, + GSource *source, + GSourceFunc *func, + gpointer *data); +}; + +/** + * GSourceDummyMarshal: + * + * This is just a placeholder for #GClosureMarshal, + * which cannot be used here for dependency reasons. + */ +typedef void (*GSourceDummyMarshal) (void); + +struct _GSourceFuncs +{ + gboolean (*prepare) (GSource *source, + gint *timeout_); + gboolean (*check) (GSource *source); + gboolean (*dispatch) (GSource *source, + GSourceFunc callback, + gpointer user_data); + void (*finalize) (GSource *source); /* Can be NULL */ + + /*< private >*/ + /* For use by g_source_set_closure */ + GSourceFunc closure_callback; + GSourceDummyMarshal closure_marshal; /* Really is of type GClosureMarshal */ +}; + +/* Standard priorities */ + +/** + * G_PRIORITY_HIGH: + * + * Use this for high priority event sources. + * + * It is not used within GLib or GTK+. + */ +#define G_PRIORITY_HIGH -100 + +/** + * G_PRIORITY_DEFAULT: + * + * Use this for default priority event sources. + * + * In GLib this priority is used when adding timeout functions + * with g_timeout_add(). In GDK this priority is used for events + * from the X server. + */ +#define G_PRIORITY_DEFAULT 0 + +/** + * G_PRIORITY_HIGH_IDLE: + * + * Use this for high priority idle functions. + * + * GTK+ uses #G_PRIORITY_HIGH_IDLE + 10 for resizing operations, + * and #G_PRIORITY_HIGH_IDLE + 20 for redrawing operations. (This is + * done to ensure that any pending resizes are processed before any + * pending redraws, so that widgets are not redrawn twice unnecessarily.) + */ +#define G_PRIORITY_HIGH_IDLE 100 + +/** + * G_PRIORITY_DEFAULT_IDLE: + * + * Use this for default priority idle functions. + * + * In GLib this priority is used when adding idle functions with + * g_idle_add(). + */ +#define G_PRIORITY_DEFAULT_IDLE 200 + +/** + * G_PRIORITY_LOW: + * + * Use this for very low priority background tasks. + * + * It is not used within GLib or GTK+. + */ +#define G_PRIORITY_LOW 300 + +/** + * G_SOURCE_REMOVE: + * + * Use this macro as the return value of a #GSourceFunc to remove + * the #GSource from the main loop. + * + * Since: 2.28 + */ +#define G_SOURCE_REMOVE FALSE + +/** + * G_SOURCE_CONTINUE: + * + * Use this macro as the return value of a #GSourceFunc to leave + * the #GSource in the main loop. + * + * Since: 2.28 + */ +#define G_SOURCE_CONTINUE TRUE + +/* GMainContext: */ + +GMainContext *g_main_context_new (void); +GMainContext *g_main_context_ref (GMainContext *context); +void g_main_context_unref (GMainContext *context); +GMainContext *g_main_context_default (void); + +gboolean g_main_context_iteration (GMainContext *context, + gboolean may_block); +gboolean g_main_context_pending (GMainContext *context); + +/* For implementation of legacy interfaces + */ +GSource *g_main_context_find_source_by_id (GMainContext *context, + guint source_id); +GSource *g_main_context_find_source_by_user_data (GMainContext *context, + gpointer user_data); +GSource *g_main_context_find_source_by_funcs_user_data (GMainContext *context, + GSourceFuncs *funcs, + gpointer user_data); + +/* Low level functions for implementing custom main loops. + */ +void g_main_context_wakeup (GMainContext *context); +gboolean g_main_context_acquire (GMainContext *context); +void g_main_context_release (GMainContext *context); +gboolean g_main_context_is_owner (GMainContext *context); +gboolean g_main_context_wait (GMainContext *context, + GCond *cond, + GMutex *mutex); + +gboolean g_main_context_prepare (GMainContext *context, + gint *priority); +gint g_main_context_query (GMainContext *context, + gint max_priority, + gint *timeout_, + GPollFD *fds, + gint n_fds); +gint g_main_context_check (GMainContext *context, + gint max_priority, + GPollFD *fds, + gint n_fds); +void g_main_context_dispatch (GMainContext *context); + +void g_main_context_set_poll_func (GMainContext *context, + GPollFunc func); +GPollFunc g_main_context_get_poll_func (GMainContext *context); + +/* Low level functions for use by source implementations + */ +void g_main_context_add_poll (GMainContext *context, + GPollFD *fd, + gint priority); +void g_main_context_remove_poll (GMainContext *context, + GPollFD *fd); + +gint g_main_depth (void); +GSource *g_main_current_source (void); + +/* GMainContexts for other threads + */ +void g_main_context_push_thread_default (GMainContext *context); +void g_main_context_pop_thread_default (GMainContext *context); +GMainContext *g_main_context_get_thread_default (void); +GMainContext *g_main_context_ref_thread_default (void); + +/* GMainLoop: */ + +GMainLoop *g_main_loop_new (GMainContext *context, + gboolean is_running); +void g_main_loop_run (GMainLoop *loop); +void g_main_loop_quit (GMainLoop *loop); +GMainLoop *g_main_loop_ref (GMainLoop *loop); +void g_main_loop_unref (GMainLoop *loop); +gboolean g_main_loop_is_running (GMainLoop *loop); +GMainContext *g_main_loop_get_context (GMainLoop *loop); + +/* GSource: */ + +GSource *g_source_new (GSourceFuncs *source_funcs, + guint struct_size); +GSource *g_source_ref (GSource *source); +void g_source_unref (GSource *source); + +guint g_source_attach (GSource *source, + GMainContext *context); +void g_source_destroy (GSource *source); + +void g_source_set_priority (GSource *source, + gint priority); +gint g_source_get_priority (GSource *source); +void g_source_set_can_recurse (GSource *source, + gboolean can_recurse); +gboolean g_source_get_can_recurse (GSource *source); +guint g_source_get_id (GSource *source); + +GMainContext *g_source_get_context (GSource *source); + +void g_source_set_callback (GSource *source, + GSourceFunc func, + gpointer data, + GDestroyNotify notify); + +void g_source_set_funcs (GSource *source, + GSourceFuncs *funcs); +gboolean g_source_is_destroyed (GSource *source); + +void g_source_set_name (GSource *source, + const char *name); +const char * g_source_get_name (GSource *source); +void g_source_set_name_by_id (guint tag, + const char *name); + + +/* Used to implement g_source_connect_closure and internally*/ +void g_source_set_callback_indirect (GSource *source, + gpointer callback_data, + GSourceCallbackFuncs *callback_funcs); + +void g_source_add_poll (GSource *source, + GPollFD *fd); +void g_source_remove_poll (GSource *source, + GPollFD *fd); + +void g_source_add_child_source (GSource *source, + GSource *child_source); +void g_source_remove_child_source (GSource *source, + GSource *child_source); + +GLIB_DEPRECATED_IN_2_28_FOR(g_source_get_time) +void g_source_get_current_time (GSource *source, + GTimeVal *timeval); + +gint64 g_source_get_time (GSource *source); + + /* void g_source_connect_closure (GSource *source, + GClosure *closure); + */ + +/* Specific source types + */ +GSource *g_idle_source_new (void); +GSource *g_child_watch_source_new (GPid pid); +GSource *g_timeout_source_new (guint interval); +GSource *g_timeout_source_new_seconds (guint interval); + +/* Miscellaneous functions + */ +void g_get_current_time (GTimeVal *result); +gint64 g_get_monotonic_time (void); +gint64 g_get_real_time (void); + + +/* Source manipulation by ID */ +gboolean g_source_remove (guint tag); +gboolean g_source_remove_by_user_data (gpointer user_data); +gboolean g_source_remove_by_funcs_user_data (GSourceFuncs *funcs, + gpointer user_data); + +/* Idles, child watchers and timeouts */ +guint g_timeout_add_full (gint priority, + guint interval, + GSourceFunc function, + gpointer data, + GDestroyNotify notify); +guint g_timeout_add (guint interval, + GSourceFunc function, + gpointer data); +guint g_timeout_add_seconds_full (gint priority, + guint interval, + GSourceFunc function, + gpointer data, + GDestroyNotify notify); +guint g_timeout_add_seconds (guint interval, + GSourceFunc function, + gpointer data); +guint g_child_watch_add_full (gint priority, + GPid pid, + GChildWatchFunc function, + gpointer data, + GDestroyNotify notify); +guint g_child_watch_add (GPid pid, + GChildWatchFunc function, + gpointer data); +guint g_idle_add (GSourceFunc function, + gpointer data); +guint g_idle_add_full (gint priority, + GSourceFunc function, + gpointer data, + GDestroyNotify notify); +gboolean g_idle_remove_by_data (gpointer data); + +void g_main_context_invoke_full (GMainContext *context, + gint priority, + GSourceFunc function, + gpointer data, + GDestroyNotify notify); +void g_main_context_invoke (GMainContext *context, + GSourceFunc function, + gpointer data); + +/* Hook for GClosure / GSource integration. Don't touch */ +GLIB_VAR GSourceFuncs g_timeout_funcs; +GLIB_VAR GSourceFuncs g_child_watch_funcs; +GLIB_VAR GSourceFuncs g_idle_funcs; + +G_END_DECLS + +#endif /* __G_MAIN_H__ */ diff --git a/glib/glib/gmappedfile.c b/glib/glib/gmappedfile.c new file mode 100644 index 0000000..b541870 --- /dev/null +++ b/glib/glib/gmappedfile.c @@ -0,0 +1,402 @@ +/* GLIB - Library of useful routines for C programming + * gmappedfile.c: Simplified wrapper around the mmap() function. + * + * Copyright 2005 Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_MMAP +#include +#endif + +#include "glibconfig.h" + +#ifdef G_OS_WIN32 +#include +#include + +#define fstat(a,b) _fstati64(a,b) +#define stat _stati64 + +#ifndef S_ISREG +#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG) +#endif + +#endif + +#include "gconvert.h" +#include "gerror.h" +#include "gfileutils.h" +#include "gmappedfile.h" +#include "gmem.h" +#include "gmessages.h" +#include "gstdio.h" +#include "gstrfuncs.h" +#include "gatomic.h" + +#include "glibintl.h" + + +#ifndef _O_BINARY +#define _O_BINARY 0 +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *) -1) +#endif + +/** + * GMappedFile: + * + * The #GMappedFile represents a file mapping created with + * g_mapped_file_new(). It has only private members and should + * not be accessed directly. + */ + +struct _GMappedFile +{ + gchar *contents; + gsize length; + gpointer free_func; + int ref_count; +#ifdef G_OS_WIN32 + HANDLE mapping; +#endif +}; + +static void +g_mapped_file_destroy (GMappedFile *file) +{ + if (file->length) + { +#ifdef HAVE_MMAP + munmap (file->contents, file->length); +#endif +#ifdef G_OS_WIN32 + UnmapViewOfFile (file->contents); + CloseHandle (file->mapping); +#endif + } + + g_slice_free (GMappedFile, file); +} + +static GMappedFile* +mapped_file_new_from_fd (int fd, + gboolean writable, + const gchar *filename, + GError **error) +{ + GMappedFile *file; + struct stat st; + + file = g_slice_new0 (GMappedFile); + file->ref_count = 1; + file->free_func = g_mapped_file_destroy; + + if (fstat (fd, &st) == -1) + { + int save_errno = errno; + gchar *display_filename = filename ? g_filename_display_name (filename) : NULL; + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to get attributes of file '%s%s%s%s': fstat() failed: %s"), + display_filename ? display_filename : "fd", + display_filename ? "' " : "", + display_filename ? display_filename : "", + display_filename ? "'" : "", + g_strerror (save_errno)); + g_free (display_filename); + goto out; + } + + /* mmap() on size 0 will fail with EINVAL, so we avoid calling mmap() + * in that case -- but only if we have a regular file; we still want + * attempts to mmap a character device to fail, for example. + */ + if (st.st_size == 0 && S_ISREG (st.st_mode)) + { + file->length = 0; + file->contents = NULL; + return file; + } + + file->contents = MAP_FAILED; + +#ifdef HAVE_MMAP + if (st.st_size > G_MAXSIZE) + { + errno = EINVAL; + } + else + { + file->length = (gsize) st.st_size; + file->contents = (gchar *) mmap (NULL, file->length, + writable ? PROT_READ|PROT_WRITE : PROT_READ, + MAP_PRIVATE, fd, 0); + } +#endif +#ifdef G_OS_WIN32 + file->length = st.st_size; + file->mapping = CreateFileMapping ((HANDLE) _get_osfhandle (fd), NULL, + writable ? PAGE_WRITECOPY : PAGE_READONLY, + 0, 0, + NULL); + if (file->mapping != NULL) + { + file->contents = MapViewOfFile (file->mapping, + writable ? FILE_MAP_COPY : FILE_MAP_READ, + 0, 0, + 0); + if (file->contents == NULL) + { + file->contents = MAP_FAILED; + CloseHandle (file->mapping); + file->mapping = NULL; + } + } +#endif + + + if (file->contents == MAP_FAILED) + { + int save_errno = errno; + gchar *display_filename = filename ? g_filename_display_name (filename) : NULL; + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to map %s%s%s%s: mmap() failed: %s"), + display_filename ? display_filename : "fd", + display_filename ? "' " : "", + display_filename ? display_filename : "", + display_filename ? "'" : "", + g_strerror (save_errno)); + g_free (display_filename); + goto out; + } + + return file; + + out: + g_slice_free (GMappedFile, file); + + return NULL; +} + +/** + * g_mapped_file_new: + * @filename: The path of the file to load, in the GLib filename encoding + * @writable: whether the mapping should be writable + * @error: return location for a #GError, or %NULL + * + * Maps a file into memory. On UNIX, this is using the mmap() function. + * + * If @writable is %TRUE, the mapped buffer may be modified, otherwise + * it is an error to modify the mapped buffer. Modifications to the buffer + * are not visible to other processes mapping the same file, and are not + * written back to the file. + * + * Note that modifications of the underlying file might affect the contents + * of the #GMappedFile. Therefore, mapping should only be used if the file + * will not be modified, or if all modifications of the file are done + * atomically (e.g. using g_file_set_contents()). + * + * If @filename is the name of an empty, regular file, the function + * will successfully return an empty #GMappedFile. In other cases of + * size 0 (e.g. device files such as /dev/null), @error will be set + * to the #GFileError value #G_FILE_ERROR_INVAL. + * + * Return value: a newly allocated #GMappedFile which must be unref'd + * with g_mapped_file_unref(), or %NULL if the mapping failed. + * + * Since: 2.8 + */ +GMappedFile * +g_mapped_file_new (const gchar *filename, + gboolean writable, + GError **error) +{ + GMappedFile *file; + int fd; + + g_return_val_if_fail (filename != NULL, NULL); + g_return_val_if_fail (!error || *error == NULL, NULL); + + fd = g_open (filename, (writable ? O_RDWR : O_RDONLY) | _O_BINARY, 0); + if (fd == -1) + { + int save_errno = errno; + gchar *display_filename = g_filename_display_name (filename); + + g_set_error (error, + G_FILE_ERROR, + g_file_error_from_errno (save_errno), + _("Failed to open file '%s': open() failed: %s"), + display_filename, + g_strerror (save_errno)); + g_free (display_filename); + return NULL; + } + + file = mapped_file_new_from_fd (fd, writable, filename, error); + + close (fd); + + return file; +} + + +/** + * g_mapped_file_new_from_fd: + * @fd: The file descriptor of the file to load + * @writable: whether the mapping should be writable + * @error: return location for a #GError, or %NULL + * + * Maps a file into memory. On UNIX, this is using the mmap() function. + * + * If @writable is %TRUE, the mapped buffer may be modified, otherwise + * it is an error to modify the mapped buffer. Modifications to the buffer + * are not visible to other processes mapping the same file, and are not + * written back to the file. + * + * Note that modifications of the underlying file might affect the contents + * of the #GMappedFile. Therefore, mapping should only be used if the file + * will not be modified, or if all modifications of the file are done + * atomically (e.g. using g_file_set_contents()). + * + * Return value: a newly allocated #GMappedFile which must be unref'd + * with g_mapped_file_unref(), or %NULL if the mapping failed. + * + * Since: 2.32 + */ +GMappedFile * +g_mapped_file_new_from_fd (gint fd, + gboolean writable, + GError **error) +{ + return mapped_file_new_from_fd (fd, writable, NULL, error); +} + +/** + * g_mapped_file_get_length: + * @file: a #GMappedFile + * + * Returns the length of the contents of a #GMappedFile. + * + * Returns: the length of the contents of @file. + * + * Since: 2.8 + */ +gsize +g_mapped_file_get_length (GMappedFile *file) +{ + g_return_val_if_fail (file != NULL, 0); + + return file->length; +} + +/** + * g_mapped_file_get_contents: + * @file: a #GMappedFile + * + * Returns the contents of a #GMappedFile. + * + * Note that the contents may not be zero-terminated, + * even if the #GMappedFile is backed by a text file. + * + * If the file is empty then %NULL is returned. + * + * Returns: the contents of @file, or %NULL. + * + * Since: 2.8 + */ +gchar * +g_mapped_file_get_contents (GMappedFile *file) +{ + g_return_val_if_fail (file != NULL, NULL); + + return file->contents; +} + +/** + * g_mapped_file_free: + * @file: a #GMappedFile + * + * This call existed before #GMappedFile had refcounting and is currently + * exactly the same as g_mapped_file_unref(). + * + * Since: 2.8 + * Deprecated:2.22: Use g_mapped_file_unref() instead. + */ +void +g_mapped_file_free (GMappedFile *file) +{ + g_mapped_file_unref (file); +} + +/** + * g_mapped_file_ref: + * @file: a #GMappedFile + * + * Increments the reference count of @file by one. It is safe to call + * this function from any thread. + * + * Return value: the passed in #GMappedFile. + * + * Since: 2.22 + **/ +GMappedFile * +g_mapped_file_ref (GMappedFile *file) +{ + g_return_val_if_fail (file != NULL, NULL); + + g_atomic_int_inc (&file->ref_count); + + return file; +} + +/** + * g_mapped_file_unref: + * @file: a #GMappedFile + * + * Decrements the reference count of @file by one. If the reference count + * drops to 0, unmaps the buffer of @file and frees it. + * + * It is safe to call this function from any thread. + * + * Since 2.22 + **/ +void +g_mapped_file_unref (GMappedFile *file) +{ + g_return_if_fail (file != NULL); + + if (g_atomic_int_dec_and_test (&file->ref_count)) + g_mapped_file_destroy (file); +} diff --git a/glib/glib/gmappedfile.h b/glib/glib/gmappedfile.h new file mode 100644 index 0000000..52ba31d --- /dev/null +++ b/glib/glib/gmappedfile.h @@ -0,0 +1,52 @@ +/* GLIB - Library of useful routines for C programming + * gmappedfile.h: Simplified wrapper around the mmap function + * + * Copyright 2005 Matthias Clasen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_MAPPED_FILE_H__ +#define __G_MAPPED_FILE_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GMappedFile GMappedFile; + +GMappedFile *g_mapped_file_new (const gchar *filename, + gboolean writable, + GError **error) G_GNUC_MALLOC; +GMappedFile *g_mapped_file_new_from_fd (gint fd, + gboolean writable, + GError **error) G_GNUC_MALLOC; +gsize g_mapped_file_get_length (GMappedFile *file); +gchar *g_mapped_file_get_contents (GMappedFile *file); +GMappedFile *g_mapped_file_ref (GMappedFile *file); +void g_mapped_file_unref (GMappedFile *file); + +GLIB_DEPRECATED_FOR(g_mapped_file_unref) +void g_mapped_file_free (GMappedFile *file); + +G_END_DECLS + +#endif /* __G_MAPPED_FILE_H__ */ diff --git a/glib/glib/gmarkup.c b/glib/glib/gmarkup.c new file mode 100644 index 0000000..b0c28a9 --- /dev/null +++ b/glib/glib/gmarkup.c @@ -0,0 +1,2824 @@ +/* gmarkup.c - Simple XML-like parser + * + * Copyright 2000, 2003 Red Hat, Inc. + * Copyright 2007, 2008 Ryan Lortie + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "gmarkup.h" + +#include "gslice.h" +#include "galloca.h" +#include "gstrfuncs.h" +#include "gstring.h" +#include "gtestutils.h" +#include "glibintl.h" + +/** + * SECTION:markup + * @Title: Simple XML Subset Parser + * @Short_description: parses a subset of XML + * @See_also: XML + * Specification + * + * The "GMarkup" parser is intended to parse a simple markup format + * that's a subset of XML. This is a small, efficient, easy-to-use + * parser. It should not be used if you expect to interoperate with + * other applications generating full-scale XML. However, it's very + * useful for application data files, config files, etc. where you + * know your application will be the only one writing the file. + * Full-scale XML parsers should be able to parse the subset used by + * GMarkup, so you can easily migrate to full-scale XML at a later + * time if the need arises. + * + * GMarkup is not guaranteed to signal an error on all invalid XML; + * the parser may accept documents that an XML parser would not. + * However, XML documents which are not well-formedBeing wellformed is a weaker condition than being + * valid. See the XML + * specification for definitions of these terms. + * are not considered valid GMarkup documents. + * + * Simplifications to XML include: + * + * Only UTF-8 encoding is allowed + * No user-defined entities + * Processing instructions, comments and the doctype declaration + * are "passed through" but are not interpreted in any way + * No DTD or validation. + * + * + * The markup format does support: + * + * Elements + * Attributes + * 5 standard entities: + * &amp; &lt; &gt; &quot; &apos; + * + * Character references + * Sections marked as CDATA + * + */ + +GQuark +g_markup_error_quark (void) +{ + return g_quark_from_static_string ("g-markup-error-quark"); +} + +typedef enum +{ + STATE_START, + STATE_AFTER_OPEN_ANGLE, + STATE_AFTER_CLOSE_ANGLE, + STATE_AFTER_ELISION_SLASH, /* the slash that obviates need for end element */ + STATE_INSIDE_OPEN_TAG_NAME, + STATE_INSIDE_ATTRIBUTE_NAME, + STATE_AFTER_ATTRIBUTE_NAME, + STATE_BETWEEN_ATTRIBUTES, + STATE_AFTER_ATTRIBUTE_EQUALS_SIGN, + STATE_INSIDE_ATTRIBUTE_VALUE_SQ, + STATE_INSIDE_ATTRIBUTE_VALUE_DQ, + STATE_INSIDE_TEXT, + STATE_AFTER_CLOSE_TAG_SLASH, + STATE_INSIDE_CLOSE_TAG_NAME, + STATE_AFTER_CLOSE_TAG_NAME, + STATE_INSIDE_PASSTHROUGH, + STATE_ERROR +} GMarkupParseState; + +typedef struct +{ + const char *prev_element; + const GMarkupParser *prev_parser; + gpointer prev_user_data; +} GMarkupRecursionTracker; + +struct _GMarkupParseContext +{ + const GMarkupParser *parser; + + GMarkupParseFlags flags; + + gint line_number; + gint char_number; + + GMarkupParseState state; + + gpointer user_data; + GDestroyNotify dnotify; + + /* A piece of character data or an element that + * hasn't "ended" yet so we haven't yet called + * the callback for it. + */ + GString *partial_chunk; + GSList *spare_chunks; + + GSList *tag_stack; + GSList *tag_stack_gstr; + GSList *spare_list_nodes; + + GString **attr_names; + GString **attr_values; + gint cur_attr; + gint alloc_attrs; + + const gchar *current_text; + gssize current_text_len; + const gchar *current_text_end; + + /* used to save the start of the last interesting thingy */ + const gchar *start; + + const gchar *iter; + + guint document_empty : 1; + guint parsing : 1; + guint awaiting_pop : 1; + gint balance; + + /* subparser support */ + GSList *subparser_stack; /* (GMarkupRecursionTracker *) */ + const char *subparser_element; + gpointer held_user_data; +}; + +/* + * Helpers to reduce our allocation overhead, we have + * a well defined allocation lifecycle. + */ +static GSList * +get_list_node (GMarkupParseContext *context, gpointer data) +{ + GSList *node; + if (context->spare_list_nodes != NULL) + { + node = context->spare_list_nodes; + context->spare_list_nodes = g_slist_remove_link (context->spare_list_nodes, node); + } + else + node = g_slist_alloc(); + node->data = data; + return node; +} + +static void +free_list_node (GMarkupParseContext *context, GSList *node) +{ + node->data = NULL; + context->spare_list_nodes = g_slist_concat (node, context->spare_list_nodes); +} + +static inline void +string_blank (GString *string) +{ + string->str[0] = '\0'; + string->len = 0; +} + +/** + * g_markup_parse_context_new: + * @parser: a #GMarkupParser + * @flags: one or more #GMarkupParseFlags + * @user_data: user data to pass to #GMarkupParser functions + * @user_data_dnotify: user data destroy notifier called when + * the parse context is freed + * + * Creates a new parse context. A parse context is used to parse + * marked-up documents. You can feed any number of documents into + * a context, as long as no errors occur; once an error occurs, + * the parse context can't continue to parse text (you have to + * free it and create a new parse context). + * + * Return value: a new #GMarkupParseContext + **/ +GMarkupParseContext * +g_markup_parse_context_new (const GMarkupParser *parser, + GMarkupParseFlags flags, + gpointer user_data, + GDestroyNotify user_data_dnotify) +{ + GMarkupParseContext *context; + + g_return_val_if_fail (parser != NULL, NULL); + + context = g_new (GMarkupParseContext, 1); + + context->parser = parser; + context->flags = flags; + context->user_data = user_data; + context->dnotify = user_data_dnotify; + + context->line_number = 1; + context->char_number = 1; + + context->partial_chunk = NULL; + context->spare_chunks = NULL; + context->spare_list_nodes = NULL; + + context->state = STATE_START; + context->tag_stack = NULL; + context->tag_stack_gstr = NULL; + context->attr_names = NULL; + context->attr_values = NULL; + context->cur_attr = -1; + context->alloc_attrs = 0; + + context->current_text = NULL; + context->current_text_len = -1; + context->current_text_end = NULL; + + context->start = NULL; + context->iter = NULL; + + context->document_empty = TRUE; + context->parsing = FALSE; + + context->awaiting_pop = FALSE; + context->subparser_stack = NULL; + context->subparser_element = NULL; + + /* this is only looked at if awaiting_pop = TRUE. initialise anyway. */ + context->held_user_data = NULL; + + context->balance = 0; + + return context; +} + +static void +string_full_free (gpointer ptr) +{ + g_string_free (ptr, TRUE); +} + +static void clear_attributes (GMarkupParseContext *context); + +/** + * g_markup_parse_context_free: + * @context: a #GMarkupParseContext + * + * Frees a #GMarkupParseContext. + * + * This function can't be called from inside one of the + * #GMarkupParser functions or while a subparser is pushed. + */ +void +g_markup_parse_context_free (GMarkupParseContext *context) +{ + g_return_if_fail (context != NULL); + g_return_if_fail (!context->parsing); + g_return_if_fail (!context->subparser_stack); + g_return_if_fail (!context->awaiting_pop); + + if (context->dnotify) + (* context->dnotify) (context->user_data); + + clear_attributes (context); + g_free (context->attr_names); + g_free (context->attr_values); + + g_slist_free_full (context->tag_stack_gstr, string_full_free); + g_slist_free (context->tag_stack); + + g_slist_free_full (context->spare_chunks, string_full_free); + g_slist_free (context->spare_list_nodes); + + if (context->partial_chunk) + g_string_free (context->partial_chunk, TRUE); + + g_free (context); +} + +static void pop_subparser_stack (GMarkupParseContext *context); + +static void +mark_error (GMarkupParseContext *context, + GError *error) +{ + context->state = STATE_ERROR; + + if (context->parser->error) + (*context->parser->error) (context, error, context->user_data); + + /* report the error all the way up to free all the user-data */ + while (context->subparser_stack) + { + pop_subparser_stack (context); + context->awaiting_pop = FALSE; /* already been freed */ + + if (context->parser->error) + (*context->parser->error) (context, error, context->user_data); + } +} + +static void +set_error (GMarkupParseContext *context, + GError **error, + GMarkupError code, + const gchar *format, + ...) G_GNUC_PRINTF (4, 5); + +static void +set_error_literal (GMarkupParseContext *context, + GError **error, + GMarkupError code, + const gchar *message) +{ + GError *tmp_error; + + tmp_error = g_error_new_literal (G_MARKUP_ERROR, code, message); + + g_prefix_error (&tmp_error, + _("Error on line %d char %d: "), + context->line_number, + context->char_number); + + mark_error (context, tmp_error); + + g_propagate_error (error, tmp_error); +} + +static void +set_error (GMarkupParseContext *context, + GError **error, + GMarkupError code, + const gchar *format, + ...) +{ + gchar *s; + gchar *s_valid; + va_list args; + + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); + + /* Make sure that the GError message is valid UTF-8 + * even if it is complaining about invalid UTF-8 in the markup + */ + s_valid = _g_utf8_make_valid (s); + set_error_literal (context, error, code, s); + + g_free (s); + g_free (s_valid); +} + +static void +propagate_error (GMarkupParseContext *context, + GError **dest, + GError *src) +{ + if (context->flags & G_MARKUP_PREFIX_ERROR_POSITION) + g_prefix_error (&src, + _("Error on line %d char %d: "), + context->line_number, + context->char_number); + + mark_error (context, src); + + g_propagate_error (dest, src); +} + +#define IS_COMMON_NAME_END_CHAR(c) \ + ((c) == '=' || (c) == '/' || (c) == '>' || (c) == ' ') + +static gboolean +slow_name_validate (GMarkupParseContext *context, + const gchar *name, + GError **error) +{ + const gchar *p = name; + + if (!g_utf8_validate (name, strlen (name), NULL)) + { + set_error (context, error, G_MARKUP_ERROR_BAD_UTF8, + _("Invalid UTF-8 encoded text in name - not valid '%s'"), name); + return FALSE; + } + + if (!(g_ascii_isalpha (*p) || + (!IS_COMMON_NAME_END_CHAR (*p) && + (*p == '_' || + *p == ':' || + g_unichar_isalpha (g_utf8_get_char (p)))))) + { + set_error (context, error, G_MARKUP_ERROR_PARSE, + _("'%s' is not a valid name "), name); + return FALSE; + } + + for (p = g_utf8_next_char (name); *p != '\0'; p = g_utf8_next_char (p)) + { + /* is_name_char */ + if (!(g_ascii_isalnum (*p) || + (!IS_COMMON_NAME_END_CHAR (*p) && + (*p == '.' || + *p == '-' || + *p == '_' || + *p == ':' || + g_unichar_isalpha (g_utf8_get_char (p)))))) + { + set_error (context, error, G_MARKUP_ERROR_PARSE, + _("'%s' is not a valid name: '%c' "), name, *p); + return FALSE; + } + } + return TRUE; +} + +/* + * Use me for elements, attributes etc. + */ +static gboolean +name_validate (GMarkupParseContext *context, + const gchar *name, + GError **error) +{ + char mask; + const char *p; + + /* name start char */ + p = name; + if (G_UNLIKELY (IS_COMMON_NAME_END_CHAR (*p) || + !(g_ascii_isalpha (*p) || *p == '_' || *p == ':'))) + goto slow_validate; + + for (mask = *p++; *p != '\0'; p++) + { + mask |= *p; + + /* is_name_char */ + if (G_UNLIKELY (!(g_ascii_isalnum (*p) || + (!IS_COMMON_NAME_END_CHAR (*p) && + (*p == '.' || + *p == '-' || + *p == '_' || + *p == ':'))))) + goto slow_validate; + } + + if (mask & 0x80) /* un-common / non-ascii */ + goto slow_validate; + + return TRUE; + + slow_validate: + return slow_name_validate (context, name, error); +} + +static gboolean +text_validate (GMarkupParseContext *context, + const gchar *p, + gint len, + GError **error) +{ + if (!g_utf8_validate (p, len, NULL)) + { + set_error (context, error, G_MARKUP_ERROR_BAD_UTF8, + _("Invalid UTF-8 encoded text in name - not valid '%s'"), p); + return FALSE; + } + else + return TRUE; +} + +static gchar* +char_str (gunichar c, + gchar *buf) +{ + memset (buf, 0, 8); + g_unichar_to_utf8 (c, buf); + return buf; +} + +static gchar* +utf8_str (const gchar *utf8, + gchar *buf) +{ + char_str (g_utf8_get_char (utf8), buf); + return buf; +} + +static void +set_unescape_error (GMarkupParseContext *context, + GError **error, + const gchar *remaining_text, + GMarkupError code, + const gchar *format, + ...) +{ + GError *tmp_error; + gchar *s; + va_list args; + gint remaining_newlines; + const gchar *p; + + remaining_newlines = 0; + p = remaining_text; + while (*p != '\0') + { + if (*p == '\n') + ++remaining_newlines; + ++p; + } + + va_start (args, format); + s = g_strdup_vprintf (format, args); + va_end (args); + + tmp_error = g_error_new (G_MARKUP_ERROR, + code, + _("Error on line %d: %s"), + context->line_number - remaining_newlines, + s); + + g_free (s); + + mark_error (context, tmp_error); + + g_propagate_error (error, tmp_error); +} + +/* + * re-write the GString in-place, unescaping anything that escaped. + * most XML does not contain entities, or escaping. + */ +static gboolean +unescape_gstring_inplace (GMarkupParseContext *context, + GString *string, + gboolean *is_ascii, + GError **error) +{ + char mask, *to; + int line_num = 1; + const char *from; + gboolean normalize_attribute; + + *is_ascii = FALSE; + + /* are we unescaping an attribute or not ? */ + if (context->state == STATE_INSIDE_ATTRIBUTE_VALUE_SQ || + context->state == STATE_INSIDE_ATTRIBUTE_VALUE_DQ) + normalize_attribute = TRUE; + else + normalize_attribute = FALSE; + + /* + * Meeks' theorum: unescaping can only shrink text. + * for < etc. this is obvious, for ￿ more + * thought is required, but this is patently so. + */ + mask = 0; + for (from = to = string->str; *from != '\0'; from++, to++) + { + *to = *from; + + mask |= *to; + if (*to == '\n') + line_num++; + if (normalize_attribute && (*to == '\t' || *to == '\n')) + *to = ' '; + if (*to == '\r') + { + *to = normalize_attribute ? ' ' : '\n'; + if (from[1] == '\n') + from++; + } + if (*from == '&') + { + from++; + if (*from == '#') + { + gboolean is_hex = FALSE; + gulong l; + gchar *end = NULL; + + from++; + + if (*from == 'x') + { + is_hex = TRUE; + from++; + } + + /* digit is between start and p */ + errno = 0; + if (is_hex) + l = strtoul (from, &end, 16); + else + l = strtoul (from, &end, 10); + + if (end == from || errno != 0) + { + set_unescape_error (context, error, + from, G_MARKUP_ERROR_PARSE, + _("Failed to parse '%-.*s', which " + "should have been a digit " + "inside a character reference " + "(ê for example) - perhaps " + "the digit is too large"), + end - from, from); + return FALSE; + } + else if (*end != ';') + { + set_unescape_error (context, error, + from, G_MARKUP_ERROR_PARSE, + _("Character reference did not end with a " + "semicolon; " + "most likely you used an ampersand " + "character without intending to start " + "an entity - escape ampersand as &")); + return FALSE; + } + else + { + /* characters XML 1.1 permits */ + if ((0 < l && l <= 0xD7FF) || + (0xE000 <= l && l <= 0xFFFD) || + (0x10000 <= l && l <= 0x10FFFF)) + { + gchar buf[8]; + char_str (l, buf); + strcpy (to, buf); + to += strlen (buf) - 1; + from = end; + if (l >= 0x80) /* not ascii */ + mask |= 0x80; + } + else + { + set_unescape_error (context, error, + from, G_MARKUP_ERROR_PARSE, + _("Character reference '%-.*s' does not " + "encode a permitted character"), + end - from, from); + return FALSE; + } + } + } + + else if (strncmp (from, "lt;", 3) == 0) + { + *to = '<'; + from += 2; + } + else if (strncmp (from, "gt;", 3) == 0) + { + *to = '>'; + from += 2; + } + else if (strncmp (from, "amp;", 4) == 0) + { + *to = '&'; + from += 3; + } + else if (strncmp (from, "quot;", 5) == 0) + { + *to = '"'; + from += 4; + } + else if (strncmp (from, "apos;", 5) == 0) + { + *to = '\''; + from += 4; + } + else + { + if (*from == ';') + set_unescape_error (context, error, + from, G_MARKUP_ERROR_PARSE, + _("Empty entity '&;' seen; valid " + "entities are: & " < > '")); + else + { + const char *end = strchr (from, ';'); + if (end) + set_unescape_error (context, error, + from, G_MARKUP_ERROR_PARSE, + _("Entity name '%-.*s' is not known"), + end-from, from); + else + set_unescape_error (context, error, + from, G_MARKUP_ERROR_PARSE, + _("Entity did not end with a semicolon; " + "most likely you used an ampersand " + "character without intending to start " + "an entity - escape ampersand as &")); + } + return FALSE; + } + } + } + + g_assert (to - string->str <= string->len); + if (to - string->str != string->len) + g_string_truncate (string, to - string->str); + + *is_ascii = !(mask & 0x80); + + return TRUE; +} + +static inline gboolean +advance_char (GMarkupParseContext *context) +{ + context->iter++; + context->char_number++; + + if (G_UNLIKELY (context->iter == context->current_text_end)) + return FALSE; + + else if (G_UNLIKELY (*context->iter == '\n')) + { + context->line_number++; + context->char_number = 1; + } + + return TRUE; +} + +static inline gboolean +xml_isspace (char c) +{ + return c == ' ' || c == '\t' || c == '\n' || c == '\r'; +} + +static void +skip_spaces (GMarkupParseContext *context) +{ + do + { + if (!xml_isspace (*context->iter)) + return; + } + while (advance_char (context)); +} + +static void +advance_to_name_end (GMarkupParseContext *context) +{ + do + { + if (IS_COMMON_NAME_END_CHAR (*(context->iter))) + return; + if (xml_isspace (*(context->iter))) + return; + } + while (advance_char (context)); +} + +static void +release_chunk (GMarkupParseContext *context, GString *str) +{ + GSList *node; + if (!str) + return; + if (str->allocated_len > 256) + { /* large strings are unusual and worth freeing */ + g_string_free (str, TRUE); + return; + } + string_blank (str); + node = get_list_node (context, str); + context->spare_chunks = g_slist_concat (node, context->spare_chunks); +} + +static void +add_to_partial (GMarkupParseContext *context, + const gchar *text_start, + const gchar *text_end) +{ + if (context->partial_chunk == NULL) + { /* allocate a new chunk to parse into */ + + if (context->spare_chunks != NULL) + { + GSList *node = context->spare_chunks; + context->spare_chunks = g_slist_remove_link (context->spare_chunks, node); + context->partial_chunk = node->data; + free_list_node (context, node); + } + else + context->partial_chunk = g_string_sized_new (MAX (28, text_end - text_start)); + } + + if (text_start != text_end) + g_string_insert_len (context->partial_chunk, -1, + text_start, text_end - text_start); +} + +static inline void +truncate_partial (GMarkupParseContext *context) +{ + if (context->partial_chunk != NULL) + string_blank (context->partial_chunk); +} + +static inline const gchar* +current_element (GMarkupParseContext *context) +{ + return context->tag_stack->data; +} + +static void +pop_subparser_stack (GMarkupParseContext *context) +{ + GMarkupRecursionTracker *tracker; + + g_assert (context->subparser_stack); + + tracker = context->subparser_stack->data; + + context->awaiting_pop = TRUE; + context->held_user_data = context->user_data; + + context->user_data = tracker->prev_user_data; + context->parser = tracker->prev_parser; + context->subparser_element = tracker->prev_element; + g_slice_free (GMarkupRecursionTracker, tracker); + + context->subparser_stack = g_slist_delete_link (context->subparser_stack, + context->subparser_stack); +} + +static void +push_partial_as_tag (GMarkupParseContext *context) +{ + GString *str = context->partial_chunk; + /* sadly, this is exported by gmarkup_get_element_stack as-is */ + context->tag_stack = g_slist_concat (get_list_node (context, str->str), context->tag_stack); + context->tag_stack_gstr = g_slist_concat (get_list_node (context, str), context->tag_stack_gstr); + context->partial_chunk = NULL; +} + +static void +pop_tag (GMarkupParseContext *context) +{ + GSList *nodea, *nodeb; + + nodea = context->tag_stack; + nodeb = context->tag_stack_gstr; + release_chunk (context, nodeb->data); + context->tag_stack = g_slist_remove_link (context->tag_stack, nodea); + context->tag_stack_gstr = g_slist_remove_link (context->tag_stack_gstr, nodeb); + free_list_node (context, nodea); + free_list_node (context, nodeb); +} + +static void +possibly_finish_subparser (GMarkupParseContext *context) +{ + if (current_element (context) == context->subparser_element) + pop_subparser_stack (context); +} + +static void +ensure_no_outstanding_subparser (GMarkupParseContext *context) +{ + if (context->awaiting_pop) + g_critical ("During the first end_element call after invoking a " + "subparser you must pop the subparser stack and handle " + "the freeing of the subparser user_data. This can be " + "done by calling the end function of the subparser. " + "Very probably, your program just leaked memory."); + + /* let valgrind watch the pointer disappear... */ + context->held_user_data = NULL; + context->awaiting_pop = FALSE; +} + +static const gchar* +current_attribute (GMarkupParseContext *context) +{ + g_assert (context->cur_attr >= 0); + return context->attr_names[context->cur_attr]->str; +} + +static void +add_attribute (GMarkupParseContext *context, GString *str) +{ + if (context->cur_attr + 2 >= context->alloc_attrs) + { + context->alloc_attrs += 5; /* silly magic number */ + context->attr_names = g_realloc (context->attr_names, sizeof(GString*)*context->alloc_attrs); + context->attr_values = g_realloc (context->attr_values, sizeof(GString*)*context->alloc_attrs); + } + context->cur_attr++; + context->attr_names[context->cur_attr] = str; + context->attr_values[context->cur_attr] = NULL; + context->attr_names[context->cur_attr+1] = NULL; + context->attr_values[context->cur_attr+1] = NULL; +} + +static void +clear_attributes (GMarkupParseContext *context) +{ + /* Go ahead and free the attributes. */ + for (; context->cur_attr >= 0; context->cur_attr--) + { + int pos = context->cur_attr; + release_chunk (context, context->attr_names[pos]); + release_chunk (context, context->attr_values[pos]); + context->attr_names[pos] = context->attr_values[pos] = NULL; + } + g_assert (context->cur_attr == -1); + g_assert (context->attr_names == NULL || + context->attr_names[0] == NULL); + g_assert (context->attr_values == NULL || + context->attr_values[0] == NULL); +} + +/* This has to be a separate function to ensure the alloca's + * are unwound on exit - otherwise we grow & blow the stack + * with large documents + */ +static inline void +emit_start_element (GMarkupParseContext *context, + GError **error) +{ + int i; + const gchar *start_name; + const gchar **attr_names; + const gchar **attr_values; + GError *tmp_error; + + attr_names = g_newa (const gchar *, context->cur_attr + 2); + attr_values = g_newa (const gchar *, context->cur_attr + 2); + for (i = 0; i < context->cur_attr + 1; i++) + { + attr_names[i] = context->attr_names[i]->str; + attr_values[i] = context->attr_values[i]->str; + } + attr_names[i] = NULL; + attr_values[i] = NULL; + + /* Call user callback for element start */ + tmp_error = NULL; + start_name = current_element (context); + + if (context->parser->start_element && + name_validate (context, start_name, error)) + (* context->parser->start_element) (context, + start_name, + (const gchar **)attr_names, + (const gchar **)attr_values, + context->user_data, + &tmp_error); + clear_attributes (context); + + if (tmp_error != NULL) + propagate_error (context, error, tmp_error); +} + +/** + * g_markup_parse_context_parse: + * @context: a #GMarkupParseContext + * @text: chunk of text to parse + * @text_len: length of @text in bytes + * @error: return location for a #GError + * + * Feed some data to the #GMarkupParseContext. + * + * The data need not be valid UTF-8; an error will be signaled if + * it's invalid. The data need not be an entire document; you can + * feed a document into the parser incrementally, via multiple calls + * to this function. Typically, as you receive data from a network + * connection or file, you feed each received chunk of data into this + * function, aborting the process if an error occurs. Once an error + * is reported, no further data may be fed to the #GMarkupParseContext; + * all errors are fatal. + * + * Return value: %FALSE if an error occurred, %TRUE on success + */ +gboolean +g_markup_parse_context_parse (GMarkupParseContext *context, + const gchar *text, + gssize text_len, + GError **error) +{ + g_return_val_if_fail (context != NULL, FALSE); + g_return_val_if_fail (text != NULL, FALSE); + g_return_val_if_fail (context->state != STATE_ERROR, FALSE); + g_return_val_if_fail (!context->parsing, FALSE); + + if (text_len < 0) + text_len = strlen (text); + + if (text_len == 0) + return TRUE; + + context->parsing = TRUE; + + + context->current_text = text; + context->current_text_len = text_len; + context->current_text_end = context->current_text + text_len; + context->iter = context->current_text; + context->start = context->iter; + + while (context->iter != context->current_text_end) + { + switch (context->state) + { + case STATE_START: + /* Possible next state: AFTER_OPEN_ANGLE */ + + g_assert (context->tag_stack == NULL); + + /* whitespace is ignored outside of any elements */ + skip_spaces (context); + + if (context->iter != context->current_text_end) + { + if (*context->iter == '<') + { + /* Move after the open angle */ + advance_char (context); + + context->state = STATE_AFTER_OPEN_ANGLE; + + /* this could start a passthrough */ + context->start = context->iter; + + /* document is now non-empty */ + context->document_empty = FALSE; + } + else + { + set_error_literal (context, + error, + G_MARKUP_ERROR_PARSE, + _("Document must begin with an element (e.g. )")); + } + } + break; + + case STATE_AFTER_OPEN_ANGLE: + /* Possible next states: INSIDE_OPEN_TAG_NAME, + * AFTER_CLOSE_TAG_SLASH, INSIDE_PASSTHROUGH + */ + if (*context->iter == '?' || + *context->iter == '!') + { + /* include < in the passthrough */ + const gchar *openangle = "<"; + add_to_partial (context, openangle, openangle + 1); + context->start = context->iter; + context->balance = 1; + context->state = STATE_INSIDE_PASSTHROUGH; + } + else if (*context->iter == '/') + { + /* move after it */ + advance_char (context); + + context->state = STATE_AFTER_CLOSE_TAG_SLASH; + } + else if (!IS_COMMON_NAME_END_CHAR (*(context->iter))) + { + context->state = STATE_INSIDE_OPEN_TAG_NAME; + + /* start of tag name */ + context->start = context->iter; + } + else + { + gchar buf[8]; + + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("'%s' is not a valid character following " + "a '<' character; it may not begin an " + "element name"), + utf8_str (context->iter, buf)); + } + break; + + /* The AFTER_CLOSE_ANGLE state is actually sort of + * broken, because it doesn't correspond to a range + * of characters in the input stream as the others do, + * and thus makes things harder to conceptualize + */ + case STATE_AFTER_CLOSE_ANGLE: + /* Possible next states: INSIDE_TEXT, STATE_START */ + if (context->tag_stack == NULL) + { + context->start = NULL; + context->state = STATE_START; + } + else + { + context->start = context->iter; + context->state = STATE_INSIDE_TEXT; + } + break; + + case STATE_AFTER_ELISION_SLASH: + /* Possible next state: AFTER_CLOSE_ANGLE */ + + { + /* We need to pop the tag stack and call the end_element + * function, since this is the close tag + */ + GError *tmp_error = NULL; + + g_assert (context->tag_stack != NULL); + + possibly_finish_subparser (context); + + tmp_error = NULL; + if (context->parser->end_element) + (* context->parser->end_element) (context, + current_element (context), + context->user_data, + &tmp_error); + + ensure_no_outstanding_subparser (context); + + if (tmp_error) + { + mark_error (context, tmp_error); + g_propagate_error (error, tmp_error); + } + else + { + if (*context->iter == '>') + { + /* move after the close angle */ + advance_char (context); + context->state = STATE_AFTER_CLOSE_ANGLE; + } + else + { + gchar buf[8]; + + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("Odd character '%s', expected a '>' character " + "to end the empty-element tag '%s'"), + utf8_str (context->iter, buf), + current_element (context)); + } + } + pop_tag (context); + } + break; + + case STATE_INSIDE_OPEN_TAG_NAME: + /* Possible next states: BETWEEN_ATTRIBUTES */ + + /* if there's a partial chunk then it's the first part of the + * tag name. If there's a context->start then it's the start + * of the tag name in current_text, the partial chunk goes + * before that start though. + */ + advance_to_name_end (context); + + if (context->iter == context->current_text_end) + { + /* The name hasn't necessarily ended. Merge with + * partial chunk, leave state unchanged. + */ + add_to_partial (context, context->start, context->iter); + } + else + { + /* The name has ended. Combine it with the partial chunk + * if any; push it on the stack; enter next state. + */ + add_to_partial (context, context->start, context->iter); + push_partial_as_tag (context); + + context->state = STATE_BETWEEN_ATTRIBUTES; + context->start = NULL; + } + break; + + case STATE_INSIDE_ATTRIBUTE_NAME: + /* Possible next states: AFTER_ATTRIBUTE_NAME */ + + advance_to_name_end (context); + add_to_partial (context, context->start, context->iter); + + /* read the full name, if we enter the equals sign state + * then add the attribute to the list (without the value), + * otherwise store a partial chunk to be prepended later. + */ + if (context->iter != context->current_text_end) + context->state = STATE_AFTER_ATTRIBUTE_NAME; + break; + + case STATE_AFTER_ATTRIBUTE_NAME: + /* Possible next states: AFTER_ATTRIBUTE_EQUALS_SIGN */ + + skip_spaces (context); + + if (context->iter != context->current_text_end) + { + /* The name has ended. Combine it with the partial chunk + * if any; push it on the stack; enter next state. + */ + if (!name_validate (context, context->partial_chunk->str, error)) + break; + + add_attribute (context, context->partial_chunk); + + context->partial_chunk = NULL; + context->start = NULL; + + if (*context->iter == '=') + { + advance_char (context); + context->state = STATE_AFTER_ATTRIBUTE_EQUALS_SIGN; + } + else + { + gchar buf[8]; + + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("Odd character '%s', expected a '=' after " + "attribute name '%s' of element '%s'"), + utf8_str (context->iter, buf), + current_attribute (context), + current_element (context)); + + } + } + break; + + case STATE_BETWEEN_ATTRIBUTES: + /* Possible next states: AFTER_CLOSE_ANGLE, + * AFTER_ELISION_SLASH, INSIDE_ATTRIBUTE_NAME + */ + skip_spaces (context); + + if (context->iter != context->current_text_end) + { + if (*context->iter == '/') + { + advance_char (context); + context->state = STATE_AFTER_ELISION_SLASH; + } + else if (*context->iter == '>') + { + advance_char (context); + context->state = STATE_AFTER_CLOSE_ANGLE; + } + else if (!IS_COMMON_NAME_END_CHAR (*(context->iter))) + { + context->state = STATE_INSIDE_ATTRIBUTE_NAME; + /* start of attribute name */ + context->start = context->iter; + } + else + { + gchar buf[8]; + + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("Odd character '%s', expected a '>' or '/' " + "character to end the start tag of " + "element '%s', or optionally an attribute; " + "perhaps you used an invalid character in " + "an attribute name"), + utf8_str (context->iter, buf), + current_element (context)); + } + + /* If we're done with attributes, invoke + * the start_element callback + */ + if (context->state == STATE_AFTER_ELISION_SLASH || + context->state == STATE_AFTER_CLOSE_ANGLE) + emit_start_element (context, error); + } + break; + + case STATE_AFTER_ATTRIBUTE_EQUALS_SIGN: + /* Possible next state: INSIDE_ATTRIBUTE_VALUE_[SQ/DQ] */ + + skip_spaces (context); + + if (context->iter != context->current_text_end) + { + if (*context->iter == '"') + { + advance_char (context); + context->state = STATE_INSIDE_ATTRIBUTE_VALUE_DQ; + context->start = context->iter; + } + else if (*context->iter == '\'') + { + advance_char (context); + context->state = STATE_INSIDE_ATTRIBUTE_VALUE_SQ; + context->start = context->iter; + } + else + { + gchar buf[8]; + + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("Odd character '%s', expected an open quote mark " + "after the equals sign when giving value for " + "attribute '%s' of element '%s'"), + utf8_str (context->iter, buf), + current_attribute (context), + current_element (context)); + } + } + break; + + case STATE_INSIDE_ATTRIBUTE_VALUE_SQ: + case STATE_INSIDE_ATTRIBUTE_VALUE_DQ: + /* Possible next states: BETWEEN_ATTRIBUTES */ + { + gchar delim; + + if (context->state == STATE_INSIDE_ATTRIBUTE_VALUE_SQ) + { + delim = '\''; + } + else + { + delim = '"'; + } + + do + { + if (*context->iter == delim) + break; + } + while (advance_char (context)); + } + if (context->iter == context->current_text_end) + { + /* The value hasn't necessarily ended. Merge with + * partial chunk, leave state unchanged. + */ + add_to_partial (context, context->start, context->iter); + } + else + { + gboolean is_ascii; + /* The value has ended at the quote mark. Combine it + * with the partial chunk if any; set it for the current + * attribute. + */ + add_to_partial (context, context->start, context->iter); + + g_assert (context->cur_attr >= 0); + + if (unescape_gstring_inplace (context, context->partial_chunk, &is_ascii, error) && + (is_ascii || text_validate (context, context->partial_chunk->str, + context->partial_chunk->len, error))) + { + /* success, advance past quote and set state. */ + context->attr_values[context->cur_attr] = context->partial_chunk; + context->partial_chunk = NULL; + advance_char (context); + context->state = STATE_BETWEEN_ATTRIBUTES; + context->start = NULL; + } + + truncate_partial (context); + } + break; + + case STATE_INSIDE_TEXT: + /* Possible next states: AFTER_OPEN_ANGLE */ + do + { + if (*context->iter == '<') + break; + } + while (advance_char (context)); + + /* The text hasn't necessarily ended. Merge with + * partial chunk, leave state unchanged. + */ + + add_to_partial (context, context->start, context->iter); + + if (context->iter != context->current_text_end) + { + gboolean is_ascii; + + /* The text has ended at the open angle. Call the text + * callback. + */ + if (unescape_gstring_inplace (context, context->partial_chunk, &is_ascii, error) && + (is_ascii || text_validate (context, context->partial_chunk->str, + context->partial_chunk->len, error))) + { + GError *tmp_error = NULL; + + if (context->parser->text) + (*context->parser->text) (context, + context->partial_chunk->str, + context->partial_chunk->len, + context->user_data, + &tmp_error); + + if (tmp_error == NULL) + { + /* advance past open angle and set state. */ + advance_char (context); + context->state = STATE_AFTER_OPEN_ANGLE; + /* could begin a passthrough */ + context->start = context->iter; + } + else + propagate_error (context, error, tmp_error); + } + + truncate_partial (context); + } + break; + + case STATE_AFTER_CLOSE_TAG_SLASH: + /* Possible next state: INSIDE_CLOSE_TAG_NAME */ + if (!IS_COMMON_NAME_END_CHAR (*(context->iter))) + { + context->state = STATE_INSIDE_CLOSE_TAG_NAME; + + /* start of tag name */ + context->start = context->iter; + } + else + { + gchar buf[8]; + + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("'%s' is not a valid character following " + "the characters 'iter, buf), + utf8_str (context->iter, buf)); + } + break; + + case STATE_INSIDE_CLOSE_TAG_NAME: + /* Possible next state: AFTER_CLOSE_TAG_NAME */ + advance_to_name_end (context); + add_to_partial (context, context->start, context->iter); + + if (context->iter != context->current_text_end) + context->state = STATE_AFTER_CLOSE_TAG_NAME; + break; + + case STATE_AFTER_CLOSE_TAG_NAME: + /* Possible next state: AFTER_CLOSE_TAG_SLASH */ + + skip_spaces (context); + + if (context->iter != context->current_text_end) + { + GString *close_name; + + close_name = context->partial_chunk; + context->partial_chunk = NULL; + + if (*context->iter != '>') + { + gchar buf[8]; + + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("'%s' is not a valid character following " + "the close element name '%s'; the allowed " + "character is '>'"), + utf8_str (context->iter, buf), + close_name->str); + } + else if (context->tag_stack == NULL) + { + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("Element '%s' was closed, no element " + "is currently open"), + close_name->str); + } + else if (strcmp (close_name->str, current_element (context)) != 0) + { + set_error (context, + error, + G_MARKUP_ERROR_PARSE, + _("Element '%s' was closed, but the currently " + "open element is '%s'"), + close_name->str, + current_element (context)); + } + else + { + GError *tmp_error; + advance_char (context); + context->state = STATE_AFTER_CLOSE_ANGLE; + context->start = NULL; + + possibly_finish_subparser (context); + + /* call the end_element callback */ + tmp_error = NULL; + if (context->parser->end_element) + (* context->parser->end_element) (context, + close_name->str, + context->user_data, + &tmp_error); + + ensure_no_outstanding_subparser (context); + pop_tag (context); + + if (tmp_error) + propagate_error (context, error, tmp_error); + } + context->partial_chunk = close_name; + truncate_partial (context); + } + break; + + case STATE_INSIDE_PASSTHROUGH: + /* Possible next state: AFTER_CLOSE_ANGLE */ + do + { + if (*context->iter == '<') + context->balance++; + if (*context->iter == '>') + { + gchar *str; + gsize len; + + context->balance--; + add_to_partial (context, context->start, context->iter); + context->start = context->iter; + + str = context->partial_chunk->str; + len = context->partial_chunk->len; + + if (str[1] == '?' && str[len - 1] == '?') + break; + if (strncmp (str, "s, which makes it easy to + * incorporate options from multiple sources. The intended use for this is + * to let applications collect option groups from the libraries it uses, + * add them to their #GOptionContext, and parse all options by a single call + * to g_option_context_parse(). See gtk_get_option_group() for an example. + * + * If an option is declared to be of type string or filename, GOption takes + * care of converting it to the right encoding; strings are returned in + * UTF-8, filenames are returned in the GLib filename encoding. Note that + * this only works if setlocale() has been called before + * g_option_context_parse(). + * + * Here is a complete example of setting up GOption to parse the example + * commandline above and produce the example help output. + * + * + * static gint repeats = 2; + * static gint max_size = 8; + * static gboolean verbose = FALSE; + * static gboolean beep = FALSE; + * static gboolean rand = FALSE; + * + * static GOptionEntry entries[] = + * { + * { "repeats", 'r', 0, G_OPTION_ARG_INT, &repeats, "Average over N repetitions", "N" }, + * { "max-size", 'm', 0, G_OPTION_ARG_INT, &max_size, "Test up to 2^M items", "M" }, + * { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL }, + * { "beep", 'b', 0, G_OPTION_ARG_NONE, &beep, "Beep when done", NULL }, + * { "rand", 0, 0, G_OPTION_ARG_NONE, &rand, "Randomize the data", NULL }, + * { NULL } + * }; + * + * int + * main (int argc, char *argv[]) + * { + * GError *error = NULL; + * GOptionContext *context; + * + * context = g_option_context_new ("- test tree model performance"); + * g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); + * g_option_context_add_group (context, gtk_get_option_group (TRUE)); + * if (!g_option_context_parse (context, &argc, &argv, &error)) + * { + * g_print ("option parsing failed: %s\n", error->message); + * exit (1); + * } + * + * /* ... */ + * + * } + * + */ + +#include "config.h" + +#include +#include +#include +#include + +#if defined __OpenBSD__ +#include +#include +#include +#include +#endif + +#include "goption.h" + +#include "gprintf.h" +#include "glibintl.h" + +#define TRANSLATE(group, str) (((group)->translate_func ? (* (group)->translate_func) ((str), (group)->translate_data) : (str))) + +#define NO_ARG(entry) ((entry)->arg == G_OPTION_ARG_NONE || \ + ((entry)->arg == G_OPTION_ARG_CALLBACK && \ + ((entry)->flags & G_OPTION_FLAG_NO_ARG))) + +#define OPTIONAL_ARG(entry) ((entry)->arg == G_OPTION_ARG_CALLBACK && \ + (entry)->flags & G_OPTION_FLAG_OPTIONAL_ARG) + +typedef struct +{ + GOptionArg arg_type; + gpointer arg_data; + union + { + gboolean bool; + gint integer; + gchar *str; + gchar **array; + gdouble dbl; + gint64 int64; + } prev; + union + { + gchar *str; + struct + { + gint len; + gchar **data; + } array; + } allocated; +} Change; + +typedef struct +{ + gchar **ptr; + gchar *value; +} PendingNull; + +struct _GOptionContext +{ + GList *groups; + + gchar *parameter_string; + gchar *summary; + gchar *description; + + GTranslateFunc translate_func; + GDestroyNotify translate_notify; + gpointer translate_data; + + guint help_enabled : 1; + guint ignore_unknown : 1; + + GOptionGroup *main_group; + + /* We keep a list of change so we can revert them */ + GList *changes; + + /* We also keep track of all argv elements + * that should be NULLed or modified. + */ + GList *pending_nulls; +}; + +struct _GOptionGroup +{ + gchar *name; + gchar *description; + gchar *help_description; + + GDestroyNotify destroy_notify; + gpointer user_data; + + GTranslateFunc translate_func; + GDestroyNotify translate_notify; + gpointer translate_data; + + GOptionEntry *entries; + gint n_entries; + + GOptionParseFunc pre_parse_func; + GOptionParseFunc post_parse_func; + GOptionErrorFunc error_func; +}; + +static void free_changes_list (GOptionContext *context, + gboolean revert); +static void free_pending_nulls (GOptionContext *context, + gboolean perform_nulls); + + +static int +_g_unichar_get_width (gunichar c) +{ + if (G_UNLIKELY (g_unichar_iszerowidth (c))) + return 0; + + /* we ignore the fact that we should call g_unichar_iswide_cjk() under + * some locales (legacy East Asian ones) */ + if (g_unichar_iswide (c)) + return 2; + + return 1; +} + +static glong +_g_utf8_strwidth (const gchar *p, + gssize max) +{ + glong len = 0; + const gchar *start = p; + g_return_val_if_fail (p != NULL || max == 0, 0); + + if (max < 0) + { + while (*p) + { + len += _g_unichar_get_width (g_utf8_get_char (p)); + p = g_utf8_next_char (p); + } + } + else + { + if (max == 0 || !*p) + return 0; + + /* this case may not be quite correct */ + + len += _g_unichar_get_width (g_utf8_get_char (p)); + p = g_utf8_next_char (p); + + while (p - start < max && *p) + { + len += _g_unichar_get_width (g_utf8_get_char (p)); + p = g_utf8_next_char (p); + } + } + + return len; +} + + +GQuark +g_option_error_quark (void) +{ + return g_quark_from_static_string ("g-option-context-error-quark"); +} + +/** + * g_option_context_new: + * @parameter_string: a string which is displayed in + * the first line of output, after the + * usage summary + * programname [OPTION...] + * + * Creates a new option context. + * + * The @parameter_string can serve multiple purposes. It can be used + * to add descriptions for "rest" arguments, which are not parsed by + * the #GOptionContext, typically something like "FILES" or + * "FILE1 FILE2...". If you are using #G_OPTION_REMAINING for + * collecting "rest" arguments, GLib handles this automatically by + * using the @arg_description of the corresponding #GOptionEntry in + * the usage summary. + * + * Another usage is to give a short summary of the program + * functionality, like " - frob the strings", which will be displayed + * in the same line as the usage. For a longer description of the + * program functionality that should be displayed as a paragraph + * below the usage line, use g_option_context_set_summary(). + * + * Note that the @parameter_string is translated using the + * function set with g_option_context_set_translate_func(), so + * it should normally be passed untranslated. + * + * Returns: a newly created #GOptionContext, which must be + * freed with g_option_context_free() after use. + * + * Since: 2.6 + */ +GOptionContext * +g_option_context_new (const gchar *parameter_string) + +{ + GOptionContext *context; + + context = g_new0 (GOptionContext, 1); + + context->parameter_string = g_strdup (parameter_string); + context->help_enabled = TRUE; + context->ignore_unknown = FALSE; + + return context; +} + +/** + * g_option_context_free: + * @context: a #GOptionContext + * + * Frees context and all the groups which have been + * added to it. + * + * Please note that parsed arguments need to be freed separately (see + * #GOptionEntry). + * + * Since: 2.6 + */ +void g_option_context_free (GOptionContext *context) +{ + g_return_if_fail (context != NULL); + + g_list_free_full (context->groups, (GDestroyNotify) g_option_group_free); + + if (context->main_group) + g_option_group_free (context->main_group); + + free_changes_list (context, FALSE); + free_pending_nulls (context, FALSE); + + g_free (context->parameter_string); + g_free (context->summary); + g_free (context->description); + + if (context->translate_notify) + (* context->translate_notify) (context->translate_data); + + g_free (context); +} + + +/** + * g_option_context_set_help_enabled: + * @context: a #GOptionContext + * @help_enabled: %TRUE to enable , %FALSE to disable it + * + * Enables or disables automatic generation of + * output. By default, g_option_context_parse() recognizes + * , , + * , + * and groupname and creates + * suitable output to stdout. + * + * Since: 2.6 + */ +void g_option_context_set_help_enabled (GOptionContext *context, + gboolean help_enabled) + +{ + g_return_if_fail (context != NULL); + + context->help_enabled = help_enabled; +} + +/** + * g_option_context_get_help_enabled: + * @context: a #GOptionContext + * + * Returns whether automatic generation + * is turned on for @context. See g_option_context_set_help_enabled(). + * + * Returns: %TRUE if automatic help generation is turned on. + * + * Since: 2.6 + */ +gboolean +g_option_context_get_help_enabled (GOptionContext *context) +{ + g_return_val_if_fail (context != NULL, FALSE); + + return context->help_enabled; +} + +/** + * g_option_context_set_ignore_unknown_options: + * @context: a #GOptionContext + * @ignore_unknown: %TRUE to ignore unknown options, %FALSE to produce + * an error when unknown options are met + * + * Sets whether to ignore unknown options or not. If an argument is + * ignored, it is left in the @argv array after parsing. By default, + * g_option_context_parse() treats unknown options as error. + * + * This setting does not affect non-option arguments (i.e. arguments + * which don't start with a dash). But note that GOption cannot reliably + * determine whether a non-option belongs to a preceding unknown option. + * + * Since: 2.6 + **/ +void +g_option_context_set_ignore_unknown_options (GOptionContext *context, + gboolean ignore_unknown) +{ + g_return_if_fail (context != NULL); + + context->ignore_unknown = ignore_unknown; +} + +/** + * g_option_context_get_ignore_unknown_options: + * @context: a #GOptionContext + * + * Returns whether unknown options are ignored or not. See + * g_option_context_set_ignore_unknown_options(). + * + * Returns: %TRUE if unknown options are ignored. + * + * Since: 2.6 + **/ +gboolean +g_option_context_get_ignore_unknown_options (GOptionContext *context) +{ + g_return_val_if_fail (context != NULL, FALSE); + + return context->ignore_unknown; +} + +/** + * g_option_context_add_group: + * @context: a #GOptionContext + * @group: the group to add + * + * Adds a #GOptionGroup to the @context, so that parsing with @context + * will recognize the options in the group. Note that the group will + * be freed together with the context when g_option_context_free() is + * called, so you must not free the group yourself after adding it + * to a context. + * + * Since: 2.6 + **/ +void +g_option_context_add_group (GOptionContext *context, + GOptionGroup *group) +{ + GList *list; + + g_return_if_fail (context != NULL); + g_return_if_fail (group != NULL); + g_return_if_fail (group->name != NULL); + g_return_if_fail (group->description != NULL); + g_return_if_fail (group->help_description != NULL); + + for (list = context->groups; list; list = list->next) + { + GOptionGroup *g = (GOptionGroup *)list->data; + + if ((group->name == NULL && g->name == NULL) || + (group->name && g->name && strcmp (group->name, g->name) == 0)) + g_warning ("A group named \"%s\" is already part of this GOptionContext", + group->name); + } + + context->groups = g_list_append (context->groups, group); +} + +/** + * g_option_context_set_main_group: + * @context: a #GOptionContext + * @group: the group to set as main group + * + * Sets a #GOptionGroup as main group of the @context. + * This has the same effect as calling g_option_context_add_group(), + * the only difference is that the options in the main group are + * treated differently when generating output. + * + * Since: 2.6 + **/ +void +g_option_context_set_main_group (GOptionContext *context, + GOptionGroup *group) +{ + g_return_if_fail (context != NULL); + g_return_if_fail (group != NULL); + + if (context->main_group) + { + g_warning ("This GOptionContext already has a main group"); + + return; + } + + context->main_group = group; +} + +/** + * g_option_context_get_main_group: + * @context: a #GOptionContext + * + * Returns a pointer to the main group of @context. + * + * Return value: the main group of @context, or %NULL if @context doesn't + * have a main group. Note that group belongs to @context and should + * not be modified or freed. + * + * Since: 2.6 + **/ +GOptionGroup * +g_option_context_get_main_group (GOptionContext *context) +{ + g_return_val_if_fail (context != NULL, NULL); + + return context->main_group; +} + +/** + * g_option_context_add_main_entries: + * @context: a #GOptionContext + * @entries: a %NULL-terminated array of #GOptionEntrys + * @translation_domain: a translation domain to use for translating + * the output for the options in @entries + * with gettext(), or %NULL + * + * A convenience function which creates a main group if it doesn't + * exist, adds the @entries to it and sets the translation domain. + * + * Since: 2.6 + **/ +void +g_option_context_add_main_entries (GOptionContext *context, + const GOptionEntry *entries, + const gchar *translation_domain) +{ + g_return_if_fail (entries != NULL); + + if (!context->main_group) + context->main_group = g_option_group_new (NULL, NULL, NULL, NULL, NULL); + + g_option_group_add_entries (context->main_group, entries); + g_option_group_set_translation_domain (context->main_group, translation_domain); +} + +static gint +calculate_max_length (GOptionGroup *group) +{ + GOptionEntry *entry; + gint i, len, max_length; + + max_length = 0; + + for (i = 0; i < group->n_entries; i++) + { + entry = &group->entries[i]; + + if (entry->flags & G_OPTION_FLAG_HIDDEN) + continue; + + len = _g_utf8_strwidth (entry->long_name, -1); + + if (entry->short_name) + len += 4; + + if (!NO_ARG (entry) && entry->arg_description) + len += 1 + _g_utf8_strwidth (TRANSLATE (group, entry->arg_description), -1); + + max_length = MAX (max_length, len); + } + + return max_length; +} + +static void +print_entry (GOptionGroup *group, + gint max_length, + const GOptionEntry *entry, + GString *string) +{ + GString *str; + + if (entry->flags & G_OPTION_FLAG_HIDDEN) + return; + + if (entry->long_name[0] == 0) + return; + + str = g_string_new (NULL); + + if (entry->short_name) + g_string_append_printf (str, " -%c, --%s", entry->short_name, entry->long_name); + else + g_string_append_printf (str, " --%s", entry->long_name); + + if (entry->arg_description) + g_string_append_printf (str, "=%s", TRANSLATE (group, entry->arg_description)); + + g_string_append_printf (string, "%s%*s %s\n", str->str, + (int) (max_length + 4 - _g_utf8_strwidth (str->str, -1)), "", + entry->description ? TRANSLATE (group, entry->description) : ""); + g_string_free (str, TRUE); +} + +static gboolean +group_has_visible_entries (GOptionContext *context, + GOptionGroup *group, + gboolean main_entries) +{ + GOptionFlags reject_filter = G_OPTION_FLAG_HIDDEN; + GOptionEntry *entry; + gint i, l; + gboolean main_group = group == context->main_group; + + if (!main_entries) + reject_filter |= G_OPTION_FLAG_IN_MAIN; + + for (i = 0, l = (group ? group->n_entries : 0); i < l; i++) + { + entry = &group->entries[i]; + + if (main_entries && !main_group && !(entry->flags & G_OPTION_FLAG_IN_MAIN)) + continue; + if (!(entry->flags & reject_filter)) + return TRUE; + } + + return FALSE; +} + +static gboolean +group_list_has_visible_entires (GOptionContext *context, + GList *group_list, + gboolean main_entries) +{ + while (group_list) + { + if (group_has_visible_entries (context, group_list->data, main_entries)) + return TRUE; + + group_list = group_list->next; + } + + return FALSE; +} + +static gboolean +context_has_h_entry (GOptionContext *context) +{ + gsize i; + GList *list; + + if (context->main_group) + { + for (i = 0; i < context->main_group->n_entries; i++) + { + if (context->main_group->entries[i].short_name == 'h') + return TRUE; + } + } + + for (list = context->groups; list != NULL; list = g_list_next (list)) + { + GOptionGroup *group; + + group = (GOptionGroup*)list->data; + for (i = 0; i < group->n_entries; i++) + { + if (group->entries[i].short_name == 'h') + return TRUE; + } + } + return FALSE; +} + +/** + * g_option_context_get_help: + * @context: a #GOptionContext + * @main_help: if %TRUE, only include the main group + * @group: the #GOptionGroup to create help for, or %NULL + * + * Returns a formatted, translated help text for the given context. + * To obtain the text produced by , call + * g_option_context_get_help (context, TRUE, NULL). + * To obtain the text produced by , call + * g_option_context_get_help (context, FALSE, NULL). + * To obtain the help text for an option group, call + * g_option_context_get_help (context, FALSE, group). + * + * Returns: A newly allocated string containing the help text + * + * Since: 2.14 + */ +gchar * +g_option_context_get_help (GOptionContext *context, + gboolean main_help, + GOptionGroup *group) +{ + GList *list; + gint max_length, len; + gint i; + GOptionEntry *entry; + GHashTable *shadow_map; + gboolean seen[256]; + const gchar *rest_description; + GString *string; + guchar token; + + string = g_string_sized_new (1024); + + rest_description = NULL; + if (context->main_group) + { + + for (i = 0; i < context->main_group->n_entries; i++) + { + entry = &context->main_group->entries[i]; + if (entry->long_name[0] == 0) + { + rest_description = TRANSLATE (context->main_group, entry->arg_description); + break; + } + } + } + + g_string_append_printf (string, "%s\n %s %s", + _("Usage:"), g_get_prgname(), _("[OPTION...]")); + + if (rest_description) + { + g_string_append (string, " "); + g_string_append (string, rest_description); + } + + if (context->parameter_string) + { + g_string_append (string, " "); + g_string_append (string, TRANSLATE (context, context->parameter_string)); + } + + g_string_append (string, "\n\n"); + + if (context->summary) + { + g_string_append (string, TRANSLATE (context, context->summary)); + g_string_append (string, "\n\n"); + } + + memset (seen, 0, sizeof (gboolean) * 256); + shadow_map = g_hash_table_new (g_str_hash, g_str_equal); + + if (context->main_group) + { + for (i = 0; i < context->main_group->n_entries; i++) + { + entry = &context->main_group->entries[i]; + g_hash_table_insert (shadow_map, + (gpointer)entry->long_name, + entry); + + if (seen[(guchar)entry->short_name]) + entry->short_name = 0; + else + seen[(guchar)entry->short_name] = TRUE; + } + } + + list = context->groups; + while (list != NULL) + { + GOptionGroup *g = list->data; + for (i = 0; i < g->n_entries; i++) + { + entry = &g->entries[i]; + if (g_hash_table_lookup (shadow_map, entry->long_name) && + !(entry->flags & G_OPTION_FLAG_NOALIAS)) + entry->long_name = g_strdup_printf ("%s-%s", g->name, entry->long_name); + else + g_hash_table_insert (shadow_map, (gpointer)entry->long_name, entry); + + if (seen[(guchar)entry->short_name] && + !(entry->flags & G_OPTION_FLAG_NOALIAS)) + entry->short_name = 0; + else + seen[(guchar)entry->short_name] = TRUE; + } + list = list->next; + } + + g_hash_table_destroy (shadow_map); + + list = context->groups; + + max_length = _g_utf8_strwidth ("-?, --help", -1); + + if (list) + { + len = _g_utf8_strwidth ("--help-all", -1); + max_length = MAX (max_length, len); + } + + if (context->main_group) + { + len = calculate_max_length (context->main_group); + max_length = MAX (max_length, len); + } + + while (list != NULL) + { + GOptionGroup *g = list->data; + + /* First, we check the --help- options */ + len = _g_utf8_strwidth ("--help-", -1) + _g_utf8_strwidth (g->name, -1); + max_length = MAX (max_length, len); + + /* Then we go through the entries */ + len = calculate_max_length (g); + max_length = MAX (max_length, len); + + list = list->next; + } + + /* Add a bit of padding */ + max_length += 4; + + if (!group) + { + list = context->groups; + + token = context_has_h_entry (context) ? '?' : 'h'; + + g_string_append_printf (string, "%s\n -%c, --%-*s %s\n", + _("Help Options:"), token, max_length - 4, "help", + _("Show help options")); + + /* We only want --help-all when there are groups */ + if (list) + g_string_append_printf (string, " --%-*s %s\n", + max_length, "help-all", + _("Show all help options")); + + while (list) + { + GOptionGroup *g = list->data; + + if (group_has_visible_entries (context, g, FALSE)) + g_string_append_printf (string, " --help-%-*s %s\n", + max_length - 5, g->name, + TRANSLATE (g, g->help_description)); + + list = list->next; + } + + g_string_append (string, "\n"); + } + + if (group) + { + /* Print a certain group */ + + if (group_has_visible_entries (context, group, FALSE)) + { + g_string_append (string, TRANSLATE (group, group->description)); + g_string_append (string, "\n"); + for (i = 0; i < group->n_entries; i++) + print_entry (group, max_length, &group->entries[i], string); + g_string_append (string, "\n"); + } + } + else if (!main_help) + { + /* Print all groups */ + + list = context->groups; + + while (list) + { + GOptionGroup *g = list->data; + + if (group_has_visible_entries (context, g, FALSE)) + { + g_string_append (string, g->description); + g_string_append (string, "\n"); + for (i = 0; i < g->n_entries; i++) + if (!(g->entries[i].flags & G_OPTION_FLAG_IN_MAIN)) + print_entry (g, max_length, &g->entries[i], string); + + g_string_append (string, "\n"); + } + + list = list->next; + } + } + + /* Print application options if --help or --help-all has been specified */ + if ((main_help || !group) && + (group_has_visible_entries (context, context->main_group, TRUE) || + group_list_has_visible_entires (context, context->groups, TRUE))) + { + list = context->groups; + + g_string_append (string, _("Application Options:")); + g_string_append (string, "\n"); + if (context->main_group) + for (i = 0; i < context->main_group->n_entries; i++) + print_entry (context->main_group, max_length, + &context->main_group->entries[i], string); + + while (list != NULL) + { + GOptionGroup *g = list->data; + + /* Print main entries from other groups */ + for (i = 0; i < g->n_entries; i++) + if (g->entries[i].flags & G_OPTION_FLAG_IN_MAIN) + print_entry (g, max_length, &g->entries[i], string); + + list = list->next; + } + + g_string_append (string, "\n"); + } + + if (context->description) + { + g_string_append (string, TRANSLATE (context, context->description)); + g_string_append (string, "\n"); + } + + return g_string_free (string, FALSE); +} + +G_GNUC_NORETURN +static void +print_help (GOptionContext *context, + gboolean main_help, + GOptionGroup *group) +{ + gchar *help; + + help = g_option_context_get_help (context, main_help, group); + g_print ("%s", help); + g_free (help); + + exit (0); +} + +static gboolean +parse_int (const gchar *arg_name, + const gchar *arg, + gint *result, + GError **error) +{ + gchar *end; + glong tmp; + + errno = 0; + tmp = strtol (arg, &end, 0); + + if (*arg == '\0' || *end != '\0') + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + _("Cannot parse integer value '%s' for %s"), + arg, arg_name); + return FALSE; + } + + *result = tmp; + if (*result != tmp || errno == ERANGE) + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + _("Integer value '%s' for %s out of range"), + arg, arg_name); + return FALSE; + } + + return TRUE; +} + + +static gboolean +parse_double (const gchar *arg_name, + const gchar *arg, + gdouble *result, + GError **error) +{ + gchar *end; + gdouble tmp; + + errno = 0; + tmp = g_strtod (arg, &end); + + if (*arg == '\0' || *end != '\0') + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + _("Cannot parse double value '%s' for %s"), + arg, arg_name); + return FALSE; + } + if (errno == ERANGE) + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + _("Double value '%s' for %s out of range"), + arg, arg_name); + return FALSE; + } + + *result = tmp; + + return TRUE; +} + + +static gboolean +parse_int64 (const gchar *arg_name, + const gchar *arg, + gint64 *result, + GError **error) +{ + gchar *end; + gint64 tmp; + + errno = 0; + tmp = g_ascii_strtoll (arg, &end, 0); + + if (*arg == '\0' || *end != '\0') + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + _("Cannot parse integer value '%s' for %s"), + arg, arg_name); + return FALSE; + } + if (errno == ERANGE) + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + _("Integer value '%s' for %s out of range"), + arg, arg_name); + return FALSE; + } + + *result = tmp; + + return TRUE; +} + + +static Change * +get_change (GOptionContext *context, + GOptionArg arg_type, + gpointer arg_data) +{ + GList *list; + Change *change = NULL; + + for (list = context->changes; list != NULL; list = list->next) + { + change = list->data; + + if (change->arg_data == arg_data) + goto found; + } + + change = g_new0 (Change, 1); + change->arg_type = arg_type; + change->arg_data = arg_data; + + context->changes = g_list_prepend (context->changes, change); + + found: + + return change; +} + +static void +add_pending_null (GOptionContext *context, + gchar **ptr, + gchar *value) +{ + PendingNull *n; + + n = g_new0 (PendingNull, 1); + n->ptr = ptr; + n->value = value; + + context->pending_nulls = g_list_prepend (context->pending_nulls, n); +} + +static gboolean +parse_arg (GOptionContext *context, + GOptionGroup *group, + GOptionEntry *entry, + const gchar *value, + const gchar *option_name, + GError **error) + +{ + Change *change; + + g_assert (value || OPTIONAL_ARG (entry) || NO_ARG (entry)); + + switch (entry->arg) + { + case G_OPTION_ARG_NONE: + { + change = get_change (context, G_OPTION_ARG_NONE, + entry->arg_data); + + *(gboolean *)entry->arg_data = !(entry->flags & G_OPTION_FLAG_REVERSE); + break; + } + case G_OPTION_ARG_STRING: + { + gchar *data; + + data = g_locale_to_utf8 (value, -1, NULL, NULL, error); + + if (!data) + return FALSE; + + change = get_change (context, G_OPTION_ARG_STRING, + entry->arg_data); + g_free (change->allocated.str); + + change->prev.str = *(gchar **)entry->arg_data; + change->allocated.str = data; + + *(gchar **)entry->arg_data = data; + break; + } + case G_OPTION_ARG_STRING_ARRAY: + { + gchar *data; + + data = g_locale_to_utf8 (value, -1, NULL, NULL, error); + + if (!data) + return FALSE; + + change = get_change (context, G_OPTION_ARG_STRING_ARRAY, + entry->arg_data); + + if (change->allocated.array.len == 0) + { + change->prev.array = *(gchar ***)entry->arg_data; + change->allocated.array.data = g_new (gchar *, 2); + } + else + change->allocated.array.data = + g_renew (gchar *, change->allocated.array.data, + change->allocated.array.len + 2); + + change->allocated.array.data[change->allocated.array.len] = data; + change->allocated.array.data[change->allocated.array.len + 1] = NULL; + + change->allocated.array.len ++; + + *(gchar ***)entry->arg_data = change->allocated.array.data; + + break; + } + + case G_OPTION_ARG_FILENAME: + { + gchar *data; + +#ifdef G_OS_WIN32 + data = g_locale_to_utf8 (value, -1, NULL, NULL, error); + + if (!data) + return FALSE; +#else + data = g_strdup (value); +#endif + change = get_change (context, G_OPTION_ARG_FILENAME, + entry->arg_data); + g_free (change->allocated.str); + + change->prev.str = *(gchar **)entry->arg_data; + change->allocated.str = data; + + *(gchar **)entry->arg_data = data; + break; + } + + case G_OPTION_ARG_FILENAME_ARRAY: + { + gchar *data; + +#ifdef G_OS_WIN32 + data = g_locale_to_utf8 (value, -1, NULL, NULL, error); + + if (!data) + return FALSE; +#else + data = g_strdup (value); +#endif + change = get_change (context, G_OPTION_ARG_STRING_ARRAY, + entry->arg_data); + + if (change->allocated.array.len == 0) + { + change->prev.array = *(gchar ***)entry->arg_data; + change->allocated.array.data = g_new (gchar *, 2); + } + else + change->allocated.array.data = + g_renew (gchar *, change->allocated.array.data, + change->allocated.array.len + 2); + + change->allocated.array.data[change->allocated.array.len] = data; + change->allocated.array.data[change->allocated.array.len + 1] = NULL; + + change->allocated.array.len ++; + + *(gchar ***)entry->arg_data = change->allocated.array.data; + + break; + } + + case G_OPTION_ARG_INT: + { + gint data; + + if (!parse_int (option_name, value, + &data, + error)) + return FALSE; + + change = get_change (context, G_OPTION_ARG_INT, + entry->arg_data); + change->prev.integer = *(gint *)entry->arg_data; + *(gint *)entry->arg_data = data; + break; + } + case G_OPTION_ARG_CALLBACK: + { + gchar *data; + gboolean retval; + + if (!value && entry->flags & G_OPTION_FLAG_OPTIONAL_ARG) + data = NULL; + else if (entry->flags & G_OPTION_FLAG_NO_ARG) + data = NULL; + else if (entry->flags & G_OPTION_FLAG_FILENAME) + { +#ifdef G_OS_WIN32 + data = g_locale_to_utf8 (value, -1, NULL, NULL, error); +#else + data = g_strdup (value); +#endif + } + else + data = g_locale_to_utf8 (value, -1, NULL, NULL, error); + + if (!(entry->flags & (G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_OPTIONAL_ARG)) && + !data) + return FALSE; + + retval = (* (GOptionArgFunc) entry->arg_data) (option_name, data, group->user_data, error); + + if (!retval && error != NULL && *error == NULL) + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_FAILED, + _("Error parsing option %s"), option_name); + + g_free (data); + + return retval; + + break; + } + case G_OPTION_ARG_DOUBLE: + { + gdouble data; + + if (!parse_double (option_name, value, + &data, + error)) + { + return FALSE; + } + + change = get_change (context, G_OPTION_ARG_DOUBLE, + entry->arg_data); + change->prev.dbl = *(gdouble *)entry->arg_data; + *(gdouble *)entry->arg_data = data; + break; + } + case G_OPTION_ARG_INT64: + { + gint64 data; + + if (!parse_int64 (option_name, value, + &data, + error)) + { + return FALSE; + } + + change = get_change (context, G_OPTION_ARG_INT64, + entry->arg_data); + change->prev.int64 = *(gint64 *)entry->arg_data; + *(gint64 *)entry->arg_data = data; + break; + } + default: + g_assert_not_reached (); + } + + return TRUE; +} + +static gboolean +parse_short_option (GOptionContext *context, + GOptionGroup *group, + gint idx, + gint *new_idx, + gchar arg, + gint *argc, + gchar ***argv, + GError **error, + gboolean *parsed) +{ + gint j; + + for (j = 0; j < group->n_entries; j++) + { + if (arg == group->entries[j].short_name) + { + gchar *option_name; + gchar *value = NULL; + + option_name = g_strdup_printf ("-%c", group->entries[j].short_name); + + if (NO_ARG (&group->entries[j])) + value = NULL; + else + { + if (*new_idx > idx) + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_FAILED, + _("Error parsing option %s"), option_name); + g_free (option_name); + return FALSE; + } + + if (idx < *argc - 1) + { + if (!OPTIONAL_ARG (&group->entries[j])) + { + value = (*argv)[idx + 1]; + add_pending_null (context, &((*argv)[idx + 1]), NULL); + *new_idx = idx + 1; + } + else + { + if ((*argv)[idx + 1][0] == '-') + value = NULL; + else + { + value = (*argv)[idx + 1]; + add_pending_null (context, &((*argv)[idx + 1]), NULL); + *new_idx = idx + 1; + } + } + } + else if (idx >= *argc - 1 && OPTIONAL_ARG (&group->entries[j])) + value = NULL; + else + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + _("Missing argument for %s"), option_name); + g_free (option_name); + return FALSE; + } + } + + if (!parse_arg (context, group, &group->entries[j], + value, option_name, error)) + { + g_free (option_name); + return FALSE; + } + + g_free (option_name); + *parsed = TRUE; + } + } + + return TRUE; +} + +static gboolean +parse_long_option (GOptionContext *context, + GOptionGroup *group, + gint *idx, + gchar *arg, + gboolean aliased, + gint *argc, + gchar ***argv, + GError **error, + gboolean *parsed) +{ + gint j; + + for (j = 0; j < group->n_entries; j++) + { + if (*idx >= *argc) + return TRUE; + + if (aliased && (group->entries[j].flags & G_OPTION_FLAG_NOALIAS)) + continue; + + if (NO_ARG (&group->entries[j]) && + strcmp (arg, group->entries[j].long_name) == 0) + { + gchar *option_name; + gboolean retval; + + option_name = g_strconcat ("--", group->entries[j].long_name, NULL); + retval = parse_arg (context, group, &group->entries[j], + NULL, option_name, error); + g_free (option_name); + + add_pending_null (context, &((*argv)[*idx]), NULL); + *parsed = TRUE; + + return retval; + } + else + { + gint len = strlen (group->entries[j].long_name); + + if (strncmp (arg, group->entries[j].long_name, len) == 0 && + (arg[len] == '=' || arg[len] == 0)) + { + gchar *value = NULL; + gchar *option_name; + + add_pending_null (context, &((*argv)[*idx]), NULL); + option_name = g_strconcat ("--", group->entries[j].long_name, NULL); + + if (arg[len] == '=') + value = arg + len + 1; + else if (*idx < *argc - 1) + { + if (!OPTIONAL_ARG (&group->entries[j])) + { + value = (*argv)[*idx + 1]; + add_pending_null (context, &((*argv)[*idx + 1]), NULL); + (*idx)++; + } + else + { + if ((*argv)[*idx + 1][0] == '-') + { + gboolean retval; + retval = parse_arg (context, group, &group->entries[j], + NULL, option_name, error); + *parsed = TRUE; + g_free (option_name); + return retval; + } + else + { + value = (*argv)[*idx + 1]; + add_pending_null (context, &((*argv)[*idx + 1]), NULL); + (*idx)++; + } + } + } + else if (*idx >= *argc - 1 && OPTIONAL_ARG (&group->entries[j])) + { + gboolean retval; + retval = parse_arg (context, group, &group->entries[j], + NULL, option_name, error); + *parsed = TRUE; + g_free (option_name); + return retval; + } + else + { + g_set_error (error, + G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + _("Missing argument for %s"), option_name); + g_free (option_name); + return FALSE; + } + + if (!parse_arg (context, group, &group->entries[j], + value, option_name, error)) + { + g_free (option_name); + return FALSE; + } + + g_free (option_name); + *parsed = TRUE; + } + } + } + + return TRUE; +} + +static gboolean +parse_remaining_arg (GOptionContext *context, + GOptionGroup *group, + gint *idx, + gint *argc, + gchar ***argv, + GError **error, + gboolean *parsed) +{ + gint j; + + for (j = 0; j < group->n_entries; j++) + { + if (*idx >= *argc) + return TRUE; + + if (group->entries[j].long_name[0]) + continue; + + g_return_val_if_fail (group->entries[j].arg == G_OPTION_ARG_CALLBACK || + group->entries[j].arg == G_OPTION_ARG_STRING_ARRAY || + group->entries[j].arg == G_OPTION_ARG_FILENAME_ARRAY, FALSE); + + add_pending_null (context, &((*argv)[*idx]), NULL); + + if (!parse_arg (context, group, &group->entries[j], (*argv)[*idx], "", error)) + return FALSE; + + *parsed = TRUE; + return TRUE; + } + + return TRUE; +} + +static void +free_changes_list (GOptionContext *context, + gboolean revert) +{ + GList *list; + + for (list = context->changes; list != NULL; list = list->next) + { + Change *change = list->data; + + if (revert) + { + switch (change->arg_type) + { + case G_OPTION_ARG_NONE: + *(gboolean *)change->arg_data = change->prev.bool; + break; + case G_OPTION_ARG_INT: + *(gint *)change->arg_data = change->prev.integer; + break; + case G_OPTION_ARG_STRING: + case G_OPTION_ARG_FILENAME: + g_free (change->allocated.str); + *(gchar **)change->arg_data = change->prev.str; + break; + case G_OPTION_ARG_STRING_ARRAY: + case G_OPTION_ARG_FILENAME_ARRAY: + g_strfreev (change->allocated.array.data); + *(gchar ***)change->arg_data = change->prev.array; + break; + case G_OPTION_ARG_DOUBLE: + *(gdouble *)change->arg_data = change->prev.dbl; + break; + case G_OPTION_ARG_INT64: + *(gint64 *)change->arg_data = change->prev.int64; + break; + default: + g_assert_not_reached (); + } + } + + g_free (change); + } + + g_list_free (context->changes); + context->changes = NULL; +} + +static void +free_pending_nulls (GOptionContext *context, + gboolean perform_nulls) +{ + GList *list; + + for (list = context->pending_nulls; list != NULL; list = list->next) + { + PendingNull *n = list->data; + + if (perform_nulls) + { + if (n->value) + { + /* Copy back the short options */ + *(n->ptr)[0] = '-'; + strcpy (*n->ptr + 1, n->value); + } + else + *n->ptr = NULL; + } + + g_free (n->value); + g_free (n); + } + + g_list_free (context->pending_nulls); + context->pending_nulls = NULL; +} + +/* Use a platform-specific mechanism to look up the first argument to + * the current process. + * Note if you implement this for other platforms, also add it to + * tests/option-argv0.c + */ +static char * +platform_get_argv0 (void) +{ +#if defined __linux + char *cmdline; + char *base_arg0; + gsize len; + + if (!g_file_get_contents ("/proc/self/cmdline", + &cmdline, + &len, + NULL)) + return NULL; + /* Sanity check for a NUL terminator. */ + if (!memchr (cmdline, 0, len)) + return NULL; + /* We could just return cmdline, but I think it's better + * to hold on to a smaller malloc block; the arguments + * could be large. + */ + base_arg0 = g_path_get_basename (cmdline); + g_free (cmdline); + return base_arg0; +#elif defined __OpenBSD__ + char **cmdline = NULL; + char *base_arg0; + gsize len = PATH_MAX; + + int mib[] = { CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV }; + + cmdline = (char **) realloc (cmdline, len); + + if (sysctl (mib, nitems (mib), cmdline, &len, NULL, 0) == -1) + { + g_free (cmdline); + return NULL; + } + + /* We could just return cmdline, but I think it's better + * to hold on to a smaller malloc block; the arguments + * could be large. + */ + base_arg0 = g_path_get_basename (*cmdline); + g_free (cmdline); + return base_arg0; +#endif + + return NULL; +} + +/** + * g_option_context_parse: + * @context: a #GOptionContext + * @argc: (inout) (allow-none): a pointer to the number of command line arguments + * @argv: (inout) (array length=argc) (allow-none): a pointer to the array of command line arguments + * @error: a return location for errors + * + * Parses the command line arguments, recognizing options + * which have been added to @context. A side-effect of + * calling this function is that g_set_prgname() will be + * called. + * + * If the parsing is successful, any parsed arguments are + * removed from the array and @argc and @argv are updated + * accordingly. A '--' option is stripped from @argv + * unless there are unparsed options before and after it, + * or some of the options after it start with '-'. In case + * of an error, @argc and @argv are left unmodified. + * + * If automatic support is enabled + * (see g_option_context_set_help_enabled()), and the + * @argv array contains one of the recognized help options, + * this function will produce help output to stdout and + * call exit (0). + * + * Note that function depends on the + * current locale for + * automatic character set conversion of string and filename + * arguments. + * + * Return value: %TRUE if the parsing was successful, + * %FALSE if an error occurred + * + * Since: 2.6 + **/ +gboolean +g_option_context_parse (GOptionContext *context, + gint *argc, + gchar ***argv, + GError **error) +{ + gint i, j, k; + GList *list; + + /* Set program name */ + if (!g_get_prgname()) + { + gchar *prgname; + + if (argc && argv && *argc) + prgname = g_path_get_basename ((*argv)[0]); + else + prgname = platform_get_argv0 (); + + if (prgname) + g_set_prgname (prgname); + else + g_set_prgname (""); + + g_free (prgname); + } + + /* Call pre-parse hooks */ + list = context->groups; + while (list) + { + GOptionGroup *group = list->data; + + if (group->pre_parse_func) + { + if (!(* group->pre_parse_func) (context, group, + group->user_data, error)) + goto fail; + } + + list = list->next; + } + + if (context->main_group && context->main_group->pre_parse_func) + { + if (!(* context->main_group->pre_parse_func) (context, context->main_group, + context->main_group->user_data, error)) + goto fail; + } + + if (argc && argv) + { + gboolean stop_parsing = FALSE; + gboolean has_unknown = FALSE; + gint separator_pos = 0; + + for (i = 1; i < *argc; i++) + { + gchar *arg, *dash; + gboolean parsed = FALSE; + + if ((*argv)[i][0] == '-' && (*argv)[i][1] != '\0' && !stop_parsing) + { + if ((*argv)[i][1] == '-') + { + /* -- option */ + + arg = (*argv)[i] + 2; + + /* '--' terminates list of arguments */ + if (*arg == 0) + { + separator_pos = i; + stop_parsing = TRUE; + continue; + } + + /* Handle help options */ + if (context->help_enabled) + { + if (strcmp (arg, "help") == 0) + print_help (context, TRUE, NULL); + else if (strcmp (arg, "help-all") == 0) + print_help (context, FALSE, NULL); + else if (strncmp (arg, "help-", 5) == 0) + { + list = context->groups; + + while (list) + { + GOptionGroup *group = list->data; + + if (strcmp (arg + 5, group->name) == 0) + print_help (context, FALSE, group); + + list = list->next; + } + } + } + + if (context->main_group && + !parse_long_option (context, context->main_group, &i, arg, + FALSE, argc, argv, error, &parsed)) + goto fail; + + if (parsed) + continue; + + /* Try the groups */ + list = context->groups; + while (list) + { + GOptionGroup *group = list->data; + + if (!parse_long_option (context, group, &i, arg, + FALSE, argc, argv, error, &parsed)) + goto fail; + + if (parsed) + break; + + list = list->next; + } + + if (parsed) + continue; + + /* Now look for ---@name + * @description: a description for this group to be shown in + * . This string is translated using the translation + * domain or translation function of the group + * @help_description: a description for the @name option. + * This string is translated using the translation domain or translation function + * of the group + * @user_data: user data that will be passed to the pre- and post-parse hooks, + * the error hook and to callbacks of %G_OPTION_ARG_CALLBACK options, or %NULL + * @destroy: a function that will be called to free @user_data, or %NULL + * + * Creates a new #GOptionGroup. + * + * Return value: a newly created option group. It should be added + * to a #GOptionContext or freed with g_option_group_free(). + * + * Since: 2.6 + **/ +GOptionGroup * +g_option_group_new (const gchar *name, + const gchar *description, + const gchar *help_description, + gpointer user_data, + GDestroyNotify destroy) + +{ + GOptionGroup *group; + + group = g_new0 (GOptionGroup, 1); + group->name = g_strdup (name); + group->description = g_strdup (description); + group->help_description = g_strdup (help_description); + group->user_data = user_data; + group->destroy_notify = destroy; + + return group; +} + + +/** + * g_option_group_free: + * @group: a #GOptionGroup + * + * Frees a #GOptionGroup. Note that you must not + * free groups which have been added to a #GOptionContext. + * + * Since: 2.6 + **/ +void +g_option_group_free (GOptionGroup *group) +{ + g_return_if_fail (group != NULL); + + g_free (group->name); + g_free (group->description); + g_free (group->help_description); + + g_free (group->entries); + + if (group->destroy_notify) + (* group->destroy_notify) (group->user_data); + + if (group->translate_notify) + (* group->translate_notify) (group->translate_data); + + g_free (group); +} + + +/** + * g_option_group_add_entries: + * @group: a #GOptionGroup + * @entries: a %NULL-terminated array of #GOptionEntrys + * + * Adds the options specified in @entries to @group. + * + * Since: 2.6 + **/ +void +g_option_group_add_entries (GOptionGroup *group, + const GOptionEntry *entries) +{ + gint i, n_entries; + + g_return_if_fail (entries != NULL); + + for (n_entries = 0; entries[n_entries].long_name != NULL; n_entries++) ; + + group->entries = g_renew (GOptionEntry, group->entries, group->n_entries + n_entries); + + memcpy (group->entries + group->n_entries, entries, sizeof (GOptionEntry) * n_entries); + + for (i = group->n_entries; i < group->n_entries + n_entries; i++) + { + gchar c = group->entries[i].short_name; + + if (c == '-' || (c != 0 && !g_ascii_isprint (c))) + { + g_warning (G_STRLOC ": ignoring invalid short option '%c' (%d) in entry %s:%s", + c, c, group->name, group->entries[i].long_name); + group->entries[i].short_name = '\0'; + } + + if (group->entries[i].arg != G_OPTION_ARG_NONE && + (group->entries[i].flags & G_OPTION_FLAG_REVERSE) != 0) + { + g_warning (G_STRLOC ": ignoring reverse flag on option of arg-type %d in entry %s:%s", + group->entries[i].arg, group->name, group->entries[i].long_name); + + group->entries[i].flags &= ~G_OPTION_FLAG_REVERSE; + } + + if (group->entries[i].arg != G_OPTION_ARG_CALLBACK && + (group->entries[i].flags & (G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_OPTIONAL_ARG|G_OPTION_FLAG_FILENAME)) != 0) + { + g_warning (G_STRLOC ": ignoring no-arg, optional-arg or filename flags (%d) on option of arg-type %d in entry %s:%s", + group->entries[i].flags, group->entries[i].arg, group->name, group->entries[i].long_name); + + group->entries[i].flags &= ~(G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_OPTIONAL_ARG|G_OPTION_FLAG_FILENAME); + } + } + + group->n_entries += n_entries; +} + +/** + * g_option_group_set_parse_hooks: + * @group: a #GOptionGroup + * @pre_parse_func: a function to call before parsing, or %NULL + * @post_parse_func: a function to call after parsing, or %NULL + * + * Associates two functions with @group which will be called + * from g_option_context_parse() before the first option is parsed + * and after the last option has been parsed, respectively. + * + * Note that the user data to be passed to @pre_parse_func and + * @post_parse_func can be specified when constructing the group + * with g_option_group_new(). + * + * Since: 2.6 + **/ +void +g_option_group_set_parse_hooks (GOptionGroup *group, + GOptionParseFunc pre_parse_func, + GOptionParseFunc post_parse_func) +{ + g_return_if_fail (group != NULL); + + group->pre_parse_func = pre_parse_func; + group->post_parse_func = post_parse_func; +} + +/** + * g_option_group_set_error_hook: + * @group: a #GOptionGroup + * @error_func: a function to call when an error occurs + * + * Associates a function with @group which will be called + * from g_option_context_parse() when an error occurs. + * + * Note that the user data to be passed to @error_func can be + * specified when constructing the group with g_option_group_new(). + * + * Since: 2.6 + **/ +void +g_option_group_set_error_hook (GOptionGroup *group, + GOptionErrorFunc error_func) +{ + g_return_if_fail (group != NULL); + + group->error_func = error_func; +} + + +/** + * g_option_group_set_translate_func: + * @group: a #GOptionGroup + * @func: the #GTranslateFunc, or %NULL + * @data: user data to pass to @func, or %NULL + * @destroy_notify: a function which gets called to free @data, or %NULL + * + * Sets the function which is used to translate user-visible + * strings, for output. Different + * groups can use different #GTranslateFuncs. If @func + * is %NULL, strings are not translated. + * + * If you are using gettext(), you only need to set the translation + * domain, see g_option_group_set_translation_domain(). + * + * Since: 2.6 + **/ +void +g_option_group_set_translate_func (GOptionGroup *group, + GTranslateFunc func, + gpointer data, + GDestroyNotify destroy_notify) +{ + g_return_if_fail (group != NULL); + + if (group->translate_notify) + group->translate_notify (group->translate_data); + + group->translate_func = func; + group->translate_data = data; + group->translate_notify = destroy_notify; +} + +static const gchar * +dgettext_swapped (const gchar *msgid, + const gchar *domainname) +{ + return g_dgettext (domainname, msgid); +} + +/** + * g_option_group_set_translation_domain: + * @group: a #GOptionGroup + * @domain: the domain to use + * + * A convenience function to use gettext() for translating + * user-visible strings. + * + * Since: 2.6 + **/ +void +g_option_group_set_translation_domain (GOptionGroup *group, + const gchar *domain) +{ + g_return_if_fail (group != NULL); + + g_option_group_set_translate_func (group, + (GTranslateFunc)dgettext_swapped, + g_strdup (domain), + g_free); +} + +/** + * g_option_context_set_translate_func: + * @context: a #GOptionContext + * @func: the #GTranslateFunc, or %NULL + * @data: user data to pass to @func, or %NULL + * @destroy_notify: a function which gets called to free @data, or %NULL + * + * Sets the function which is used to translate the contexts + * user-visible strings, for output. + * If @func is %NULL, strings are not translated. + * + * Note that option groups have their own translation functions, + * this function only affects the @parameter_string (see g_option_context_new()), + * the summary (see g_option_context_set_summary()) and the description + * (see g_option_context_set_description()). + * + * If you are using gettext(), you only need to set the translation + * domain, see g_option_context_set_translation_domain(). + * + * Since: 2.12 + **/ +void +g_option_context_set_translate_func (GOptionContext *context, + GTranslateFunc func, + gpointer data, + GDestroyNotify destroy_notify) +{ + g_return_if_fail (context != NULL); + + if (context->translate_notify) + context->translate_notify (context->translate_data); + + context->translate_func = func; + context->translate_data = data; + context->translate_notify = destroy_notify; +} + +/** + * g_option_context_set_translation_domain: + * @context: a #GOptionContext + * @domain: the domain to use + * + * A convenience function to use gettext() for translating + * user-visible strings. + * + * Since: 2.12 + **/ +void +g_option_context_set_translation_domain (GOptionContext *context, + const gchar *domain) +{ + g_return_if_fail (context != NULL); + + g_option_context_set_translate_func (context, + (GTranslateFunc)dgettext_swapped, + g_strdup (domain), + g_free); +} + +/** + * g_option_context_set_summary: + * @context: a #GOptionContext + * @summary: a string to be shown in output + * before the list of options, or %NULL + * + * Adds a string to be displayed in output + * before the list of options. This is typically a summary of the + * program functionality. + * + * Note that the summary is translated (see + * g_option_context_set_translate_func() and + * g_option_context_set_translation_domain()). + * + * Since: 2.12 + */ +void +g_option_context_set_summary (GOptionContext *context, + const gchar *summary) +{ + g_return_if_fail (context != NULL); + + g_free (context->summary); + context->summary = g_strdup (summary); +} + + +/** + * g_option_context_get_summary: + * @context: a #GOptionContext + * + * Returns the summary. See g_option_context_set_summary(). + * + * Returns: the summary + * + * Since: 2.12 + */ +const gchar * +g_option_context_get_summary (GOptionContext *context) +{ + g_return_val_if_fail (context != NULL, NULL); + + return context->summary; +} + +/** + * g_option_context_set_description: + * @context: a #GOptionContext + * @description: a string to be shown in output + * after the list of options, or %NULL + * + * Adds a string to be displayed in output + * after the list of options. This text often includes a bug reporting + * address. + * + * Note that the summary is translated (see + * g_option_context_set_translate_func()). + * + * Since: 2.12 + */ +void +g_option_context_set_description (GOptionContext *context, + const gchar *description) +{ + g_return_if_fail (context != NULL); + + g_free (context->description); + context->description = g_strdup (description); +} + + +/** + * g_option_context_get_description: + * @context: a #GOptionContext + * + * Returns the description. See g_option_context_set_description(). + * + * Returns: the description + * + * Since: 2.12 + */ +const gchar * +g_option_context_get_description (GOptionContext *context) +{ + g_return_val_if_fail (context != NULL, NULL); + + return context->description; +} diff --git a/glib/glib/goption.h b/glib/glib/goption.h new file mode 100644 index 0000000..7d1f2a1 --- /dev/null +++ b/glib/glib/goption.h @@ -0,0 +1,370 @@ +/* goption.h - Option parser + * + * Copyright (C) 2004 Anders Carlsson + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_OPTION_H__ +#define __G_OPTION_H__ + +#include +#include + +G_BEGIN_DECLS + +/** + * GOptionContext: + * + * A GOptionContext struct defines which options + * are accepted by the commandline option parser. The struct has only private + * fields and should not be directly accessed. + */ +typedef struct _GOptionContext GOptionContext; + +/** + * GOptionGroup: + * + * A GOptionGroup struct defines the options in a single + * group. The struct has only private fields and should not be directly accessed. + * + * All options in a group share the same translation function. Libraries which + * need to parse commandline options are expected to provide a function for + * getting a GOptionGroup holding their options, which + * the application can then add to its #GOptionContext. + */ +typedef struct _GOptionGroup GOptionGroup; +typedef struct _GOptionEntry GOptionEntry; + +/** + * GOptionFlags: + * @G_OPTION_FLAG_HIDDEN: The option doesn't appear in + * output. + * @G_OPTION_FLAG_IN_MAIN: The option appears in the main section of the + * output, even if it is defined in a group. + * @G_OPTION_FLAG_REVERSE: For options of the %G_OPTION_ARG_NONE kind, this flag + * indicates that the sense of the option is reversed. + * @G_OPTION_FLAG_NO_ARG: For options of the %G_OPTION_ARG_CALLBACK kind, + * this flag indicates that the callback does not take any argument + * (like a %G_OPTION_ARG_NONE option). Since 2.8 + * @G_OPTION_FLAG_FILENAME: For options of the %G_OPTION_ARG_CALLBACK + * kind, this flag indicates that the argument should be passed to the + * callback in the GLib filename encoding rather than UTF-8. Since 2.8 + * @G_OPTION_FLAG_OPTIONAL_ARG: For options of the %G_OPTION_ARG_CALLBACK + * kind, this flag indicates that the argument supply is optional. If no argument + * is given then data of %GOptionParseFunc will be set to NULL. Since 2.8 + * @G_OPTION_FLAG_NOALIAS: This flag turns off the automatic conflict resolution + * which prefixes long option names with groupname- if + * there is a conflict. This option should only be used in situations where + * aliasing is necessary to model some legacy commandline interface. It is + * not safe to use this option, unless all option groups are under your + * direct control. Since 2.8. + * + * Flags which modify individual options. + */ +typedef enum +{ + G_OPTION_FLAG_HIDDEN = 1 << 0, + G_OPTION_FLAG_IN_MAIN = 1 << 1, + G_OPTION_FLAG_REVERSE = 1 << 2, + G_OPTION_FLAG_NO_ARG = 1 << 3, + G_OPTION_FLAG_FILENAME = 1 << 4, + G_OPTION_FLAG_OPTIONAL_ARG = 1 << 5, + G_OPTION_FLAG_NOALIAS = 1 << 6 +} GOptionFlags; + +/** + * GOptionArg: + * @G_OPTION_ARG_NONE: No extra argument. This is useful for simple flags. + * @G_OPTION_ARG_STRING: The option takes a string argument. + * @G_OPTION_ARG_INT: The option takes an integer argument. + * @G_OPTION_ARG_CALLBACK: The option provides a callback to parse the + * extra argument. + * @G_OPTION_ARG_FILENAME: The option takes a filename as argument. + * @G_OPTION_ARG_STRING_ARRAY: The option takes a string argument, multiple + * uses of the option are collected into an array of strings. + * @G_OPTION_ARG_FILENAME_ARRAY: The option takes a filename as argument, + * multiple uses of the option are collected into an array of strings. + * @G_OPTION_ARG_DOUBLE: The option takes a double argument. The argument + * can be formatted either for the user's locale or for the "C" locale. Since 2.12 + * @G_OPTION_ARG_INT64: The option takes a 64-bit integer. Like %G_OPTION_ARG_INT + * but for larger numbers. The number can be in decimal base, or in hexadecimal + * (when prefixed with 0x, for example, 0xffffffff). + * Since 2.12 + * + * The #GOptionArg enum values determine which type of extra argument the + * options expect to find. If an option expects an extra argument, it + * can be specified in several ways; with a short option: + * , with a long option: + * or combined in a single argument: . + */ +typedef enum +{ + G_OPTION_ARG_NONE, + G_OPTION_ARG_STRING, + G_OPTION_ARG_INT, + G_OPTION_ARG_CALLBACK, + G_OPTION_ARG_FILENAME, + G_OPTION_ARG_STRING_ARRAY, + G_OPTION_ARG_FILENAME_ARRAY, + G_OPTION_ARG_DOUBLE, + G_OPTION_ARG_INT64 +} GOptionArg; + +/** + * GOptionArgFunc: + * @option_name: The name of the option being parsed. This will be either a + * single dash followed by a single letter (for a short name) or two dashes + * followed by a long option name. + * @value: The value to be parsed. + * @data: User data added to the #GOptionGroup containing the option when it + * was created with g_option_group_new() + * @error: A return location for errors. The error code %G_OPTION_ERROR_FAILED + * is intended to be used for errors in #GOptionArgFunc callbacks. + * + * The type of function to be passed as callback for %G_OPTION_ARG_CALLBACK + * options. + * + * Returns: %TRUE if the option was successfully parsed, %FALSE if an error + * occurred, in which case @error should be set with g_set_error() + */ +typedef gboolean (*GOptionArgFunc) (const gchar *option_name, + const gchar *value, + gpointer data, + GError **error); + +/** + * GOptionParseFunc: + * @context: The active #GOptionContext + * @group: The group to which the function belongs + * @data: User data added to the #GOptionGroup containing the option when it + * was created with g_option_group_new() + * @error: A return location for error details + * + * The type of function that can be called before and after parsing. + * + * Returns: %TRUE if the function completed successfully, %FALSE if an error + * occurred, in which case @error should be set with g_set_error() + */ +typedef gboolean (*GOptionParseFunc) (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error); + +/** + * GOptionErrorFunc: + * @context: The active #GOptionContext + * @group: The group to which the function belongs + * @data: User data added to the #GOptionGroup containing the option when it + * was created with g_option_group_new() + * @error: The #GError containing details about the parse error + * + * The type of function to be used as callback when a parse error occurs. + */ +typedef void (*GOptionErrorFunc) (GOptionContext *context, + GOptionGroup *group, + gpointer data, + GError **error); + +/** + * G_OPTION_ERROR: + * + * Error domain for option parsing. Errors in this domain will + * be from the #GOptionError enumeration. See #GError for information on + * error domains. + */ +#define G_OPTION_ERROR (g_option_error_quark ()) + +/** + * GOptionError: + * @G_OPTION_ERROR_UNKNOWN_OPTION: An option was not known to the parser. + * This error will only be reported, if the parser hasn't been instructed + * to ignore unknown options, see g_option_context_set_ignore_unknown_options(). + * @G_OPTION_ERROR_BAD_VALUE: A value couldn't be parsed. + * @G_OPTION_ERROR_FAILED: A #GOptionArgFunc callback failed. + * + * Error codes returned by option parsing. + */ +typedef enum +{ + G_OPTION_ERROR_UNKNOWN_OPTION, + G_OPTION_ERROR_BAD_VALUE, + G_OPTION_ERROR_FAILED +} GOptionError; + +GQuark g_option_error_quark (void); + +/** + * GOptionEntry: + * @long_name: The long name of an option can be used to specify it + * in a commandline as --long_name. Every + * option must have a long name. To resolve conflicts if multiple + * option groups contain the same long name, it is also possible to + * specify the option as + * --groupname-long_name. + * @short_name: If an option has a short name, it can be specified + * -short_name in a commandline. @short_name must be + * a printable ASCII character different from '-', or zero if the option has no + * short name. + * @flags: Flags from #GOptionFlags. + * @arg: The type of the option, as a #GOptionArg. + * @arg_data: If the @arg type is %G_OPTION_ARG_CALLBACK, then @arg_data must + * point to a #GOptionArgFunc callback function, which will be called to handle + * the extra argument. Otherwise, @arg_data is a pointer to a location to store + * the value, the required type of the location depends on the @arg type: + * + * + * %G_OPTION_ARG_NONE + * %gboolean + * + * + * %G_OPTION_ARG_STRING + * %gchar* + * + * + * %G_OPTION_ARG_INT + * %gint + * + * + * %G_OPTION_ARG_FILENAME + * %gchar* + * + * + * %G_OPTION_ARG_STRING_ARRAY + * %gchar** + * + * + * %G_OPTION_ARG_FILENAME_ARRAY + * %gchar** + * + * + * %G_OPTION_ARG_DOUBLE + * %gdouble + * + * + * If @arg type is %G_OPTION_ARG_STRING or %G_OPTION_ARG_FILENAME the location + * will contain a newly allocated string if the option was given. That string + * needs to be freed by the callee using g_free(). Likewise if @arg type is + * %G_OPTION_ARG_STRING_ARRAY or %G_OPTION_ARG_FILENAME_ARRAY, the data should + * be freed using g_strfreev(). + * @description: the description for the option in + * output. The @description is translated using the @translate_func of the + * group, see g_option_group_set_translation_domain(). + * @arg_description: The placeholder to use for the extra argument parsed + * by the option in + * output. The @arg_description is translated using the @translate_func of the + * group, see g_option_group_set_translation_domain(). + * + * A GOptionEntry defines a single option. + * To have an effect, they must be added to a #GOptionGroup with + * g_option_context_add_main_entries() or g_option_group_add_entries(). + */ +struct _GOptionEntry +{ + const gchar *long_name; + gchar short_name; + gint flags; + + GOptionArg arg; + gpointer arg_data; + + const gchar *description; + const gchar *arg_description; +}; + +/** + * G_OPTION_REMAINING: + * + * If a long option in the main group has this name, it is not treated as a + * regular option. Instead it collects all non-option arguments which would + * otherwise be left in argv. The option must be of type + * %G_OPTION_ARG_CALLBACK, %G_OPTION_ARG_STRING_ARRAY + * or %G_OPTION_ARG_FILENAME_ARRAY. + * + * + * Using #G_OPTION_REMAINING instead of simply scanning argv + * for leftover arguments has the advantage that GOption takes care of + * necessary encoding conversions for strings or filenames. + * + * Since: 2.6 + */ +#define G_OPTION_REMAINING "" + +GOptionContext *g_option_context_new (const gchar *parameter_string); +void g_option_context_set_summary (GOptionContext *context, + const gchar *summary); +const gchar * g_option_context_get_summary (GOptionContext *context); +void g_option_context_set_description (GOptionContext *context, + const gchar *description); +const gchar * g_option_context_get_description (GOptionContext *context); +void g_option_context_free (GOptionContext *context); +void g_option_context_set_help_enabled (GOptionContext *context, + gboolean help_enabled); +gboolean g_option_context_get_help_enabled (GOptionContext *context); +void g_option_context_set_ignore_unknown_options (GOptionContext *context, + gboolean ignore_unknown); +gboolean g_option_context_get_ignore_unknown_options (GOptionContext *context); + +void g_option_context_add_main_entries (GOptionContext *context, + const GOptionEntry *entries, + const gchar *translation_domain); +gboolean g_option_context_parse (GOptionContext *context, + gint *argc, + gchar ***argv, + GError **error); +void g_option_context_set_translate_func (GOptionContext *context, + GTranslateFunc func, + gpointer data, + GDestroyNotify destroy_notify); +void g_option_context_set_translation_domain (GOptionContext *context, + const gchar *domain); + +void g_option_context_add_group (GOptionContext *context, + GOptionGroup *group); +void g_option_context_set_main_group (GOptionContext *context, + GOptionGroup *group); +GOptionGroup *g_option_context_get_main_group (GOptionContext *context); +gchar *g_option_context_get_help (GOptionContext *context, + gboolean main_help, + GOptionGroup *group); + +GOptionGroup *g_option_group_new (const gchar *name, + const gchar *description, + const gchar *help_description, + gpointer user_data, + GDestroyNotify destroy); +void g_option_group_set_parse_hooks (GOptionGroup *group, + GOptionParseFunc pre_parse_func, + GOptionParseFunc post_parse_func); +void g_option_group_set_error_hook (GOptionGroup *group, + GOptionErrorFunc error_func); +void g_option_group_free (GOptionGroup *group); +void g_option_group_add_entries (GOptionGroup *group, + const GOptionEntry *entries); +void g_option_group_set_translate_func (GOptionGroup *group, + GTranslateFunc func, + gpointer data, + GDestroyNotify destroy_notify); +void g_option_group_set_translation_domain (GOptionGroup *group, + const gchar *domain); + +G_END_DECLS + +#endif /* __G_OPTION_H__ */ diff --git a/glib/glib/gpattern.c b/glib/glib/gpattern.c new file mode 100644 index 0000000..7770d9c --- /dev/null +++ b/glib/glib/gpattern.c @@ -0,0 +1,442 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997, 1999 Peter Mattis, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "gpattern.h" + +#include "gmacros.h" +#include "gmessages.h" +#include "gmem.h" +#include "gunicode.h" +#include "gutils.h" + +/** + * SECTION:patterns + * @title: Glob-style pattern matching + * @short_description: matches strings against patterns containing '*' + * (wildcard) and '?' (joker) + * + * The g_pattern_match* functions match a string + * against a pattern containing '*' and '?' wildcards with similar + * semantics as the standard glob() function: '*' matches an arbitrary, + * possibly empty, string, '?' matches an arbitrary character. + * + * Note that in contrast to glob(), the '/' character + * can be matched by the wildcards, there are no + * '[...]' character ranges and '*' and '?' can + * not be escaped to include them literally in a + * pattern. + * + * When multiple strings must be matched against the same pattern, it + * is better to compile the pattern to a #GPatternSpec using + * g_pattern_spec_new() and use g_pattern_match_string() instead of + * g_pattern_match_simple(). This avoids the overhead of repeated + * pattern compilation. + **/ + +/** + * GPatternSpec: + * + * A GPatternSpec is the 'compiled' form of a + * pattern. This structure is opaque and its fields cannot be accessed + * directly. + **/ + +/* keep enum and structure of gpattern.c and patterntest.c in sync */ +typedef enum +{ + G_MATCH_ALL, /* "*A?A*" */ + G_MATCH_ALL_TAIL, /* "*A?AA" */ + G_MATCH_HEAD, /* "AAAA*" */ + G_MATCH_TAIL, /* "*AAAA" */ + G_MATCH_EXACT, /* "AAAAA" */ + G_MATCH_LAST +} GMatchType; + +struct _GPatternSpec +{ + GMatchType match_type; + guint pattern_length; + guint min_length; + guint max_length; + gchar *pattern; +}; + + +/* --- functions --- */ +static inline gboolean +g_pattern_ph_match (const gchar *match_pattern, + const gchar *match_string, + gboolean *wildcard_reached_p) +{ + register const gchar *pattern, *string; + register gchar ch; + + pattern = match_pattern; + string = match_string; + + ch = *pattern; + pattern++; + while (ch) + { + switch (ch) + { + case '?': + if (!*string) + return FALSE; + string = g_utf8_next_char (string); + break; + + case '*': + *wildcard_reached_p = TRUE; + do + { + ch = *pattern; + pattern++; + if (ch == '?') + { + if (!*string) + return FALSE; + string = g_utf8_next_char (string); + } + } + while (ch == '*' || ch == '?'); + if (!ch) + return TRUE; + do + { + gboolean next_wildcard_reached = FALSE; + while (ch != *string) + { + if (!*string) + return FALSE; + string = g_utf8_next_char (string); + } + string++; + if (g_pattern_ph_match (pattern, string, &next_wildcard_reached)) + return TRUE; + if (next_wildcard_reached) + /* the forthcoming pattern substring up to the next wildcard has + * been matched, but a mismatch occoured for the rest of the + * pattern, following the next wildcard. + * there's no need to advance the current match position any + * further if the rest pattern will not match. + */ + return FALSE; + } + while (*string); + break; + + default: + if (ch == *string) + string++; + else + return FALSE; + break; + } + + ch = *pattern; + pattern++; + } + + return *string == 0; +} + +/** + * g_pattern_match: + * @pspec: a #GPatternSpec + * @string_length: the length of @string (in bytes, i.e. strlen(), + * not g_utf8_strlen()) + * @string: the UTF-8 encoded string to match + * @string_reversed: the reverse of @string or %NULL + * @Returns: %TRUE if @string matches @pspec + * + * Matches a string against a compiled pattern. Passing the correct + * length of the string given is mandatory. The reversed string can be + * omitted by passing %NULL, this is more efficient if the reversed + * version of the string to be matched is not at hand, as + * g_pattern_match() will only construct it if the compiled pattern + * requires reverse matches. + * + * Note that, if the user code will (possibly) match a string against a + * multitude of patterns containing wildcards, chances are high that + * some patterns will require a reversed string. In this case, it's + * more efficient to provide the reversed string to avoid multiple + * constructions thereof in the various calls to g_pattern_match(). + * + * Note also that the reverse of a UTF-8 encoded string can in general + * not be obtained by g_strreverse(). This works + * only if the string doesn't contain any multibyte characters. GLib + * offers the g_utf8_strreverse() function to reverse UTF-8 encoded + * strings. + **/ +gboolean +g_pattern_match (GPatternSpec *pspec, + guint string_length, + const gchar *string, + const gchar *string_reversed) +{ + g_return_val_if_fail (pspec != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + + if (string_length < pspec->min_length || + string_length > pspec->max_length) + return FALSE; + + switch (pspec->match_type) + { + gboolean dummy; + case G_MATCH_ALL: + return g_pattern_ph_match (pspec->pattern, string, &dummy); + case G_MATCH_ALL_TAIL: + if (string_reversed) + return g_pattern_ph_match (pspec->pattern, string_reversed, &dummy); + else + { + gboolean result; + gchar *tmp; + tmp = g_utf8_strreverse (string, string_length); + result = g_pattern_ph_match (pspec->pattern, tmp, &dummy); + g_free (tmp); + return result; + } + case G_MATCH_HEAD: + if (pspec->pattern_length == string_length) + return strcmp (pspec->pattern, string) == 0; + else if (pspec->pattern_length) + return strncmp (pspec->pattern, string, pspec->pattern_length) == 0; + else + return TRUE; + case G_MATCH_TAIL: + if (pspec->pattern_length) + return strcmp (pspec->pattern, string + (string_length - pspec->pattern_length)) == 0; + else + return TRUE; + case G_MATCH_EXACT: + if (pspec->pattern_length != string_length) + return FALSE; + else + return strcmp (pspec->pattern, string) == 0; + default: + g_return_val_if_fail (pspec->match_type < G_MATCH_LAST, FALSE); + return FALSE; + } +} + +/** + * g_pattern_spec_new: + * @pattern: a zero-terminated UTF-8 encoded string + * @Returns: a newly-allocated #GPatternSpec + * + * Compiles a pattern to a #GPatternSpec. + **/ +GPatternSpec* +g_pattern_spec_new (const gchar *pattern) +{ + GPatternSpec *pspec; + gboolean seen_joker = FALSE, seen_wildcard = FALSE, more_wildcards = FALSE; + gint hw_pos = -1, tw_pos = -1, hj_pos = -1, tj_pos = -1; + gboolean follows_wildcard = FALSE; + guint pending_jokers = 0; + const gchar *s; + gchar *d; + guint i; + + g_return_val_if_fail (pattern != NULL, NULL); + + /* canonicalize pattern and collect necessary stats */ + pspec = g_new (GPatternSpec, 1); + pspec->pattern_length = strlen (pattern); + pspec->min_length = 0; + pspec->max_length = 0; + pspec->pattern = g_new (gchar, pspec->pattern_length + 1); + d = pspec->pattern; + for (i = 0, s = pattern; *s != 0; s++) + { + switch (*s) + { + case '*': + if (follows_wildcard) /* compress multiple wildcards */ + { + pspec->pattern_length--; + continue; + } + follows_wildcard = TRUE; + if (hw_pos < 0) + hw_pos = i; + tw_pos = i; + break; + case '?': + pending_jokers++; + pspec->min_length++; + pspec->max_length += 4; /* maximum UTF-8 character length */ + continue; + default: + for (; pending_jokers; pending_jokers--, i++) { + *d++ = '?'; + if (hj_pos < 0) + hj_pos = i; + tj_pos = i; + } + follows_wildcard = FALSE; + pspec->min_length++; + pspec->max_length++; + break; + } + *d++ = *s; + i++; + } + for (; pending_jokers; pending_jokers--) { + *d++ = '?'; + if (hj_pos < 0) + hj_pos = i; + tj_pos = i; + } + *d++ = 0; + seen_joker = hj_pos >= 0; + seen_wildcard = hw_pos >= 0; + more_wildcards = seen_wildcard && hw_pos != tw_pos; + if (seen_wildcard) + pspec->max_length = G_MAXUINT; + + /* special case sole head/tail wildcard or exact matches */ + if (!seen_joker && !more_wildcards) + { + if (pspec->pattern[0] == '*') + { + pspec->match_type = G_MATCH_TAIL; + memmove (pspec->pattern, pspec->pattern + 1, --pspec->pattern_length); + pspec->pattern[pspec->pattern_length] = 0; + return pspec; + } + if (pspec->pattern_length > 0 && + pspec->pattern[pspec->pattern_length - 1] == '*') + { + pspec->match_type = G_MATCH_HEAD; + pspec->pattern[--pspec->pattern_length] = 0; + return pspec; + } + if (!seen_wildcard) + { + pspec->match_type = G_MATCH_EXACT; + return pspec; + } + } + + /* now just need to distinguish between head or tail match start */ + tw_pos = pspec->pattern_length - 1 - tw_pos; /* last pos to tail distance */ + tj_pos = pspec->pattern_length - 1 - tj_pos; /* last pos to tail distance */ + if (seen_wildcard) + pspec->match_type = tw_pos > hw_pos ? G_MATCH_ALL_TAIL : G_MATCH_ALL; + else /* seen_joker */ + pspec->match_type = tj_pos > hj_pos ? G_MATCH_ALL_TAIL : G_MATCH_ALL; + if (pspec->match_type == G_MATCH_ALL_TAIL) { + gchar *tmp = pspec->pattern; + pspec->pattern = g_utf8_strreverse (pspec->pattern, pspec->pattern_length); + g_free (tmp); + } + return pspec; +} + +/** + * g_pattern_spec_free: + * @pspec: a #GPatternSpec + * + * Frees the memory allocated for the #GPatternSpec. + **/ +void +g_pattern_spec_free (GPatternSpec *pspec) +{ + g_return_if_fail (pspec != NULL); + + g_free (pspec->pattern); + g_free (pspec); +} + +/** + * g_pattern_spec_equal: + * @pspec1: a #GPatternSpec + * @pspec2: another #GPatternSpec + * @Returns: Whether the compiled patterns are equal + * + * Compares two compiled pattern specs and returns whether they will + * match the same set of strings. + **/ +gboolean +g_pattern_spec_equal (GPatternSpec *pspec1, + GPatternSpec *pspec2) +{ + g_return_val_if_fail (pspec1 != NULL, FALSE); + g_return_val_if_fail (pspec2 != NULL, FALSE); + + return (pspec1->pattern_length == pspec2->pattern_length && + pspec1->match_type == pspec2->match_type && + strcmp (pspec1->pattern, pspec2->pattern) == 0); +} + +/** + * g_pattern_match_string: + * @pspec: a #GPatternSpec + * @string: the UTF-8 encoded string to match + * @Returns: %TRUE if @string matches @pspec + * + * Matches a string against a compiled pattern. If the string is to be + * matched against more than one pattern, consider using + * g_pattern_match() instead while supplying the reversed string. + **/ +gboolean +g_pattern_match_string (GPatternSpec *pspec, + const gchar *string) +{ + g_return_val_if_fail (pspec != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + + return g_pattern_match (pspec, strlen (string), string, NULL); +} + +/** + * g_pattern_match_simple: + * @pattern: the UTF-8 encoded pattern + * @string: the UTF-8 encoded string to match + * @Returns: %TRUE if @string matches @pspec + * + * Matches a string against a pattern given as a string. If this + * function is to be called in a loop, it's more efficient to compile + * the pattern once with g_pattern_spec_new() and call + * g_pattern_match_string() repeatedly. + **/ +gboolean +g_pattern_match_simple (const gchar *pattern, + const gchar *string) +{ + GPatternSpec *pspec; + gboolean ergo; + + g_return_val_if_fail (pattern != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + + pspec = g_pattern_spec_new (pattern); + ergo = g_pattern_match (pspec, strlen (string), string, NULL); + g_pattern_spec_free (pspec); + + return ergo; +} diff --git a/glib/glib/gpattern.h b/glib/glib/gpattern.h new file mode 100644 index 0000000..e692d90 --- /dev/null +++ b/glib/glib/gpattern.h @@ -0,0 +1,49 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997, 1999 Peter Mattis, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_PATTERN_H__ +#define __G_PATTERN_H__ + +#include + +G_BEGIN_DECLS + + +typedef struct _GPatternSpec GPatternSpec; + +GPatternSpec* g_pattern_spec_new (const gchar *pattern); +void g_pattern_spec_free (GPatternSpec *pspec); +gboolean g_pattern_spec_equal (GPatternSpec *pspec1, + GPatternSpec *pspec2); +gboolean g_pattern_match (GPatternSpec *pspec, + guint string_length, + const gchar *string, + const gchar *string_reversed); +gboolean g_pattern_match_string (GPatternSpec *pspec, + const gchar *string); +gboolean g_pattern_match_simple (const gchar *pattern, + const gchar *string); + +G_END_DECLS + +#endif /* __G_PATTERN_H__ */ diff --git a/glib/glib/gpoll.c b/glib/glib/gpoll.c new file mode 100644 index 0000000..940abae --- /dev/null +++ b/glib/glib/gpoll.c @@ -0,0 +1,432 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gpoll.c: poll(2) abstraction + * Copyright 1998 Owen Taylor + * Copyright 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" +#include "glibconfig.h" +#include "giochannel.h" + +/* Uncomment the next line (and the corresponding line in gmain.c) to + * enable debugging printouts if the environment variable + * G_MAIN_POLL_DEBUG is set to some value. + */ +/* #define G_MAIN_POLL_DEBUG */ + +#ifdef _WIN32 +/* Always enable debugging printout on Windows, as it is more often + * needed there... + */ +#define G_MAIN_POLL_DEBUG +#endif + +#include +#include +#include +#ifdef HAVE_SYS_TIME_H +#include +#endif /* HAVE_SYS_TIME_H */ +#ifdef GLIB_HAVE_SYS_POLL_H +# include +# undef events /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */ +# undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */ + +/* The poll() emulation on OS/X doesn't handle fds=NULL, nfds=0, + * so we prefer our own poll emulation. + */ +#if defined(_POLL_EMUL_H_) || defined(BROKEN_POLL) +#undef HAVE_POLL +#endif + +#endif /* GLIB_HAVE_SYS_POLL_H */ +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#include + +#ifdef G_OS_WIN32 +#define STRICT +#include +#endif /* G_OS_WIN32 */ + +#include "gpoll.h" + +#ifdef G_OS_WIN32 +#include "gprintf.h" +#endif + +#ifdef G_MAIN_POLL_DEBUG +extern gboolean _g_main_poll_debug; +#endif + +#ifdef HAVE_POLL +/* SunOS has poll, but doesn't provide a prototype. */ +# if defined (sun) && !defined (__SVR4) +extern gint poll (struct pollfd *fds, guint nfsd, gint timeout); +# endif /* !sun */ + +/** + * g_poll: + * @fds: file descriptors to poll + * @nfds: the number of file descriptors in @fds + * @timeout: amount of time to wait, in milliseconds, or -1 to wait forever + * + * Polls @fds, as with the poll() system call, but portably. (On + * systems that don't have poll(), it is emulated using select().) + * This is used internally by #GMainContext, but it can be called + * directly if you need to block until a file descriptor is ready, but + * don't want to run the full main loop. + * + * Each element of @fds is a #GPollFD describing a single file + * descriptor to poll. The %fd field indicates the file descriptor, + * and the %events field indicates the events to poll for. On return, + * the %revents fields will be filled with the events that actually + * occurred. + * + * On POSIX systems, the file descriptors in @fds can be any sort of + * file descriptor, but the situation is much more complicated on + * Windows. If you need to use g_poll() in code that has to run on + * Windows, the easiest solution is to construct all of your + * #GPollFDs with g_io_channel_win32_make_pollfd(). + * + * Return value: the number of entries in @fds whose %revents fields + * were filled in, or 0 if the operation timed out, or -1 on error or + * if the call was interrupted. + * + * Since: 2.20 + **/ +gint +g_poll (GPollFD *fds, + guint nfds, + gint timeout) +{ + return poll ((struct pollfd *)fds, nfds, timeout); +} + +#else /* !HAVE_POLL */ + +#ifdef G_OS_WIN32 + +static int +poll_rest (gboolean poll_msgs, + HANDLE *handles, + gint nhandles, + GPollFD *fds, + guint nfds, + gint timeout) +{ + DWORD ready; + GPollFD *f; + int recursed_result; + + if (poll_msgs) + { + /* Wait for either messages or handles + * -> Use MsgWaitForMultipleObjectsEx + */ + if (_g_main_poll_debug) + g_print (" MsgWaitForMultipleObjectsEx(%d, %d)\n", nhandles, timeout); + + ready = MsgWaitForMultipleObjectsEx (nhandles, handles, timeout, + QS_ALLINPUT, MWMO_ALERTABLE); + + if (ready == WAIT_FAILED) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + g_warning ("MsgWaitForMultipleObjectsEx failed: %s", emsg); + g_free (emsg); + } + } + else if (nhandles == 0) + { + /* No handles to wait for, just the timeout */ + if (timeout == INFINITE) + ready = WAIT_FAILED; + else + { + SleepEx (timeout, TRUE); + ready = WAIT_TIMEOUT; + } + } + else + { + /* Wait for just handles + * -> Use WaitForMultipleObjectsEx + */ + if (_g_main_poll_debug) + g_print (" WaitForMultipleObjectsEx(%d, %d)\n", nhandles, timeout); + + ready = WaitForMultipleObjectsEx (nhandles, handles, FALSE, timeout, TRUE); + if (ready == WAIT_FAILED) + { + gchar *emsg = g_win32_error_message (GetLastError ()); + g_warning ("WaitForMultipleObjectsEx failed: %s", emsg); + g_free (emsg); + } + } + + if (_g_main_poll_debug) + g_print (" wait returns %ld%s\n", + ready, + (ready == WAIT_FAILED ? " (WAIT_FAILED)" : + (ready == WAIT_TIMEOUT ? " (WAIT_TIMEOUT)" : + (poll_msgs && ready == WAIT_OBJECT_0 + nhandles ? " (msg)" : "")))); + + if (ready == WAIT_FAILED) + return -1; + else if (ready == WAIT_TIMEOUT || + ready == WAIT_IO_COMPLETION) + return 0; + else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles) + { + for (f = fds; f < &fds[nfds]; ++f) + if (f->fd == G_WIN32_MSG_HANDLE && f->events & G_IO_IN) + f->revents |= G_IO_IN; + + /* If we have a timeout, or no handles to poll, be satisfied + * with just noticing we have messages waiting. + */ + if (timeout != 0 || nhandles == 0) + return 1; + + /* If no timeout and handles to poll, recurse to poll them, + * too. + */ + recursed_result = poll_rest (FALSE, handles, nhandles, fds, nfds, 0); + return (recursed_result == -1) ? -1 : 1 + recursed_result; + } + else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles) + { + for (f = fds; f < &fds[nfds]; ++f) + { + if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0]) + { + f->revents = f->events; + if (_g_main_poll_debug) + g_print (" got event %p\n", (HANDLE) f->fd); + } + } + + /* If no timeout and polling several handles, recurse to poll + * the rest of them. + */ + if (timeout == 0 && nhandles > 1) + { + /* Remove the handle that fired */ + int i; + if (ready < nhandles - 1) + for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++) + handles[i-1] = handles[i]; + nhandles--; + recursed_result = poll_rest (FALSE, handles, nhandles, fds, nfds, 0); + return (recursed_result == -1) ? -1 : 1 + recursed_result; + } + return 1; + } + + return 0; +} + +gint +g_poll (GPollFD *fds, + guint nfds, + gint timeout) +{ + HANDLE handles[MAXIMUM_WAIT_OBJECTS]; + gboolean poll_msgs = FALSE; + GPollFD *f; + gint nhandles = 0; + int retval; + + if (_g_main_poll_debug) + g_print ("g_poll: waiting for"); + + for (f = fds; f < &fds[nfds]; ++f) + if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN)) + { + if (_g_main_poll_debug && !poll_msgs) + g_print (" MSG"); + poll_msgs = TRUE; + } + else if (f->fd > 0) + { + /* Don't add the same handle several times into the array, as + * docs say that is not allowed, even if it actually does seem + * to work. + */ + gint i; + + for (i = 0; i < nhandles; i++) + if (handles[i] == (HANDLE) f->fd) + break; + + if (i == nhandles) + { + if (nhandles == MAXIMUM_WAIT_OBJECTS) + { + g_warning ("Too many handles to wait for!\n"); + break; + } + else + { + if (_g_main_poll_debug) + g_print (" %p", (HANDLE) f->fd); + handles[nhandles++] = (HANDLE) f->fd; + } + } + } + + if (_g_main_poll_debug) + g_print ("\n"); + + for (f = fds; f < &fds[nfds]; ++f) + f->revents = 0; + + if (timeout == -1) + timeout = INFINITE; + + /* Polling for several things? */ + if (nhandles > 1 || (nhandles > 0 && poll_msgs)) + { + /* First check if one or several of them are immediately + * available + */ + retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, 0); + + /* If not, and we have a significant timeout, poll again with + * timeout then. Note that this will return indication for only + * one event, or only for messages. We ignore timeouts less than + * ten milliseconds as they are mostly pointless on Windows, the + * MsgWaitForMultipleObjectsEx() call will timeout right away + * anyway. + */ + if (retval == 0 && (timeout == INFINITE || timeout >= 10)) + retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); + } + else + { + /* Just polling for one thing, so no need to check first if + * available immediately + */ + retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout); + } + + if (retval == -1) + for (f = fds; f < &fds[nfds]; ++f) + f->revents = 0; + + return retval; +} + +#else /* !G_OS_WIN32 */ + +/* The following implementation of poll() comes from the GNU C Library. + * Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc. + */ + +#include /* for bzero on BSD systems */ + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ + +#ifdef G_OS_BEOS +#undef NO_FD_SET +#endif /* G_OS_BEOS */ + +#ifndef NO_FD_SET +# define SELECT_MASK fd_set +#else /* !NO_FD_SET */ +# ifndef _AIX +typedef long fd_mask; +# endif /* _AIX */ +# ifdef _IBMR2 +# define SELECT_MASK void +# else /* !_IBMR2 */ +# define SELECT_MASK int +# endif /* !_IBMR2 */ +#endif /* !NO_FD_SET */ + +gint +g_poll (GPollFD *fds, + guint nfds, + gint timeout) +{ + struct timeval tv; + SELECT_MASK rset, wset, xset; + GPollFD *f; + int ready; + int maxfd = 0; + + FD_ZERO (&rset); + FD_ZERO (&wset); + FD_ZERO (&xset); + + for (f = fds; f < &fds[nfds]; ++f) + if (f->fd >= 0) + { + if (f->events & G_IO_IN) + FD_SET (f->fd, &rset); + if (f->events & G_IO_OUT) + FD_SET (f->fd, &wset); + if (f->events & G_IO_PRI) + FD_SET (f->fd, &xset); + if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI))) + maxfd = f->fd; + } + + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + ready = select (maxfd + 1, &rset, &wset, &xset, + timeout == -1 ? NULL : &tv); + if (ready > 0) + for (f = fds; f < &fds[nfds]; ++f) + { + f->revents = 0; + if (f->fd >= 0) + { + if (FD_ISSET (f->fd, &rset)) + f->revents |= G_IO_IN; + if (FD_ISSET (f->fd, &wset)) + f->revents |= G_IO_OUT; + if (FD_ISSET (f->fd, &xset)) + f->revents |= G_IO_PRI; + } + } + + return ready; +} + +#endif /* !G_OS_WIN32 */ + +#endif /* !HAVE_POLL */ diff --git a/glib/glib/gpoll.h b/glib/glib/gpoll.h new file mode 100644 index 0000000..f28b758 --- /dev/null +++ b/glib/glib/gpoll.h @@ -0,0 +1,120 @@ +/* gpoll.h - poll(2) support + * Copyright (C) 2008 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (__G_MAIN_H__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_POLL_H__ +#define __G_POLL_H__ + +#include + +G_BEGIN_DECLS + +/* Any definitions using GPollFD or GPollFunc are primarily + * for Unix and not guaranteed to be the compatible on all + * operating systems on which GLib runs. Right now, the + * GLib does use these functions on Win32 as well, but interprets + * them in a fairly different way than on Unix. If you use + * these definitions, you are should be prepared to recode + * for different operating systems. + * + * Note that on systems with a working poll(2), that function is used + * in place of g_poll(). Thus g_poll() must have the same signature as + * poll(), meaning GPollFD must have the same layout as struct pollfd. + * + * + * On Win32, the fd in a GPollFD should be Win32 HANDLE (*not* a file + * descriptor as provided by the C runtime) that can be used by + * MsgWaitForMultipleObjects. This does *not* include file handles + * from CreateFile, SOCKETs, nor pipe handles. (But you can use + * WSAEventSelect to signal events when a SOCKET is readable). + * + * On Win32, fd can also be the special value G_WIN32_MSG_HANDLE to + * indicate polling for messages. + * + * But note that G_WIN32_MSG_HANDLE GPollFDs should not be used by GDK + * (GTK) programs, as GDK itself wants to read messages and convert them + * to GDK events. + * + * So, unless you really know what you are doing, it's best not to try + * to use the main loop polling stuff for your own needs on + * Windows. + */ +typedef struct _GPollFD GPollFD; + +/** + * GPollFunc: + * @ufds: an array of #GPollFD elements + * @nfsd: the number of elements in @ufds + * @timeout_: the maximum time to wait for an event of the file descriptors. + * A negative value indicates an infinite timeout. + * + * Specifies the type of function passed to g_main_context_set_poll_func(). + * The semantics of the function should match those of the poll() system call. + * + * Returns: the number of #GPollFD elements which have events or errors + * reported, or -1 if an error occurred. + */ +typedef gint (*GPollFunc) (GPollFD *ufds, + guint nfsd, + gint timeout_); + +/** + * GPollFD: + * @fd: the file descriptor to poll (or a HANDLE on Win32) + * @events: a bitwise combination from #GIOCondition, specifying which + * events should be polled for. Typically for reading from a file + * descriptor you would use %G_IO_IN | %G_IO_HUP | %G_IO_ERR, and + * for writing you would use %G_IO_OUT | %G_IO_ERR. + * @revents: a bitwise combination of flags from #GIOCondition, returned + * from the poll() function to indicate which events occurred. + * + * Represents a file descriptor, which events to poll for, and which events + * occurred. + */ +struct _GPollFD +{ +#if defined (G_OS_WIN32) && GLIB_SIZEOF_VOID_P == 8 + gint64 fd; +#else + gint fd; +#endif + gushort events; + gushort revents; +}; + +#ifdef G_OS_WIN32 +#if GLIB_SIZEOF_VOID_P == 8 +#define G_POLLFD_FORMAT "%#I64x" +#else +#define G_POLLFD_FORMAT "%#x" +#endif +#else +#define G_POLLFD_FORMAT "%d" +#endif + +gint g_poll (GPollFD *fds, + guint nfds, + gint timeout); + +G_END_DECLS + +#endif /* __G_POLL_H__ */ diff --git a/glib/glib/gprimes.c b/glib/glib/gprimes.c new file mode 100644 index 0000000..6e27343 --- /dev/null +++ b/glib/glib/gprimes.c @@ -0,0 +1,98 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "gprimes.h" + + +static const guint g_primes[] = +{ + 11, + 19, + 37, + 73, + 109, + 163, + 251, + 367, + 557, + 823, + 1237, + 1861, + 2777, + 4177, + 6247, + 9371, + 14057, + 21089, + 31627, + 47431, + 71143, + 106721, + 160073, + 240101, + 360163, + 540217, + 810343, + 1215497, + 1823231, + 2734867, + 4102283, + 6153409, + 9230113, + 13845163, +}; + +/** + * g_spaced_primes_closest: + * @num: a #guint + * + * Gets the smallest prime number from a built-in array of primes which + * is larger than @num. This is used within GLib to calculate the optimum + * size of a #GHashTable. + * + * The built-in array of primes ranges from 11 to 13845163 such that + * each prime is approximately 1.5-2 times the previous prime. + * + * Returns: the smallest prime number from a built-in array of primes + * which is larger than @num + */ +guint +g_spaced_primes_closest (guint num) +{ + gint i; + + for (i = 0; i < G_N_ELEMENTS (g_primes); i++) + if (g_primes[i] > num) + return g_primes[i]; + + return g_primes[G_N_ELEMENTS (g_primes) - 1]; +} diff --git a/glib/glib/gprimes.h b/glib/glib/gprimes.h new file mode 100644 index 0000000..19f5702 --- /dev/null +++ b/glib/glib/gprimes.h @@ -0,0 +1,51 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_PRIMES_H__ +#define __G_PRIMES_H__ + +#include + +G_BEGIN_DECLS + +/* Prime numbers. + */ + +/* This function returns prime numbers spaced by approximately 1.5-2.0 + * and is for use in resizing data structures which prefer + * prime-valued sizes. The closest spaced prime function returns the + * next largest prime, or the highest it knows about which is about + * MAXINT/4. + */ +guint g_spaced_primes_closest (guint num) G_GNUC_CONST; + +G_END_DECLS + +#endif /* __G_PRIMES_H__ */ diff --git a/glib/glib/gprintf.c b/glib/glib/gprintf.c new file mode 100644 index 0000000..346fd95 --- /dev/null +++ b/glib/glib/gprintf.c @@ -0,0 +1,340 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997, 2002 Peter Mattis, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include + +#include "gprintf.h" +#include "gprintfint.h" + + +/** + * g_printf: + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @...: the arguments to insert in the output. + * + * An implementation of the standard printf() function which supports + * positional parameters, as specified in the Single Unix Specification. + * + * Returns: the number of bytes printed. + * + * Since: 2.2 + **/ +gint +g_printf (gchar const *format, + ...) +{ + va_list args; + gint retval; + + va_start (args, format); + retval = g_vprintf (format, args); + va_end (args); + + return retval; +} + +/** + * g_fprintf: + * @file: the stream to write to. + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @...: the arguments to insert in the output. + * + * An implementation of the standard fprintf() function which supports + * positional parameters, as specified in the Single Unix Specification. + * + * Returns: the number of bytes printed. + * + * Since: 2.2 + **/ +gint +g_fprintf (FILE *file, + gchar const *format, + ...) +{ + va_list args; + gint retval; + + va_start (args, format); + retval = g_vfprintf (file, format, args); + va_end (args); + + return retval; +} + +/** + * g_sprintf: + * @string: A pointer to a memory buffer to contain the resulting string. It + * is up to the caller to ensure that the allocated buffer is large + * enough to hold the formatted result + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @...: the arguments to insert in the output. + * + * An implementation of the standard sprintf() function which supports + * positional parameters, as specified in the Single Unix Specification. + * + * Note that it is usually better to use g_snprintf(), to avoid the + * risk of buffer overflow. + * + * See also g_strdup_printf(). + * + * Returns: the number of bytes printed. + * + * Since: 2.2 + **/ +gint +g_sprintf (gchar *string, + gchar const *format, + ...) +{ + va_list args; + gint retval; + + va_start (args, format); + retval = g_vsprintf (string, format, args); + va_end (args); + + return retval; +} + +/** + * g_snprintf: + * @string: the buffer to hold the output. + * @n: the maximum number of bytes to produce (including the + * terminating nul character). + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @...: the arguments to insert in the output. + * + * A safer form of the standard sprintf() function. The output is guaranteed + * to not exceed @n characters (including the terminating nul character), so + * it is easy to ensure that a buffer overflow cannot occur. + * + * See also g_strdup_printf(). + * + * In versions of GLib prior to 1.2.3, this function may return -1 if the + * output was truncated, and the truncated string may not be nul-terminated. + * In versions prior to 1.3.12, this function returns the length of the output + * string. + * + * The return value of g_snprintf() conforms to the snprintf() + * function as standardized in ISO C99. Note that this is different from + * traditional snprintf(), which returns the length of the output string. + * + * The format string may contain positional parameters, as specified in + * the Single Unix Specification. + * + * Returns: the number of bytes which would be produced if the buffer + * was large enough. + **/ +gint +g_snprintf (gchar *string, + gulong n, + gchar const *format, + ...) +{ + va_list args; + gint retval; + + va_start (args, format); + retval = g_vsnprintf (string, n, format, args); + va_end (args); + + return retval; +} + +/** + * g_vprintf: + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @args: the list of arguments to insert in the output. + * + * An implementation of the standard vprintf() function which supports + * positional parameters, as specified in the Single Unix Specification. + * + * Returns: the number of bytes printed. + * + * Since: 2.2 + **/ +gint +g_vprintf (gchar const *format, + va_list args) +{ + g_return_val_if_fail (format != NULL, -1); + + return _g_vprintf (format, args); +} + +/** + * g_vfprintf: + * @file: the stream to write to. + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @args: the list of arguments to insert in the output. + * + * An implementation of the standard fprintf() function which supports + * positional parameters, as specified in the Single Unix Specification. + * + * Returns: the number of bytes printed. + * + * Since: 2.2 + **/ +gint +g_vfprintf (FILE *file, + gchar const *format, + va_list args) +{ + g_return_val_if_fail (format != NULL, -1); + + return _g_vfprintf (file, format, args); +} + +/** + * g_vsprintf: + * @string: the buffer to hold the output. + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @args: the list of arguments to insert in the output. + * + * An implementation of the standard vsprintf() function which supports + * positional parameters, as specified in the Single Unix Specification. + * + * Returns: the number of bytes printed. + * + * Since: 2.2 + **/ +gint +g_vsprintf (gchar *string, + gchar const *format, + va_list args) +{ + g_return_val_if_fail (string != NULL, -1); + g_return_val_if_fail (format != NULL, -1); + + return _g_vsprintf (string, format, args); +} + +/** + * g_vsnprintf: + * @string: the buffer to hold the output. + * @n: the maximum number of bytes to produce (including the + * terminating nul character). + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @args: the list of arguments to insert in the output. + * + * A safer form of the standard vsprintf() function. The output is guaranteed + * to not exceed @n characters (including the terminating nul character), so + * it is easy to ensure that a buffer overflow cannot occur. + * + * See also g_strdup_vprintf(). + * + * In versions of GLib prior to 1.2.3, this function may return -1 if the + * output was truncated, and the truncated string may not be nul-terminated. + * In versions prior to 1.3.12, this function returns the length of the output + * string. + * + * The return value of g_vsnprintf() conforms to the vsnprintf() function + * as standardized in ISO C99. Note that this is different from traditional + * vsnprintf(), which returns the length of the output string. + * + * The format string may contain positional parameters, as specified in + * the Single Unix Specification. + * + * Returns: the number of bytes which would be produced if the buffer + * was large enough. + */ +gint +g_vsnprintf (gchar *string, + gulong n, + gchar const *format, + va_list args) +{ + g_return_val_if_fail (n == 0 || string != NULL, -1); + g_return_val_if_fail (format != NULL, -1); + + return _g_vsnprintf (string, n, format, args); +} + +/** + * g_vasprintf: + * @string: the return location for the newly-allocated string. + * @format: a standard printf() format string, but notice + * string precision pitfalls. + * @args: the list of arguments to insert in the output. + * + * An implementation of the GNU vasprintf() function which supports + * positional parameters, as specified in the Single Unix Specification. + * This function is similar to g_vsprintf(), except that it allocates a + * string to hold the output, instead of putting the output in a buffer + * you allocate in advance. + * + * Returns: the number of bytes printed. + * + * Since: 2.4 + **/ +gint +g_vasprintf (gchar **string, + gchar const *format, + va_list args) +{ + gint len; + g_return_val_if_fail (string != NULL, -1); + +#if !defined(HAVE_GOOD_PRINTF) + + len = _g_gnulib_vasprintf (string, format, args); + if (len < 0) + *string = NULL; + +#elif defined (HAVE_VASPRINTF) + + len = vasprintf (string, format, args); + if (len < 0) + *string = NULL; + else if (!g_mem_is_system_malloc ()) + { + /* vasprintf returns malloc-allocated memory */ + gchar *string1 = g_strndup (*string, len); + free (*string); + *string = string1; + } + +#else + + { + va_list args2; + + G_VA_COPY (args2, args); + + *string = g_new (gchar, g_printf_string_upper_bound (format, args)); + + len = _g_vsprintf (*string, format, args2); + va_end (args2); + } +#endif + + return len; +} diff --git a/glib/glib/gprintf.h b/glib/glib/gprintf.h new file mode 100644 index 0000000..d96870f --- /dev/null +++ b/glib/glib/gprintf.h @@ -0,0 +1,52 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997, 2002 Peter Mattis, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_PRINTF_H__ +#define __G_PRINTF_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +gint g_printf (gchar const *format, + ...) G_GNUC_PRINTF (1, 2); +gint g_fprintf (FILE *file, + gchar const *format, + ...) G_GNUC_PRINTF (2, 3); +gint g_sprintf (gchar *string, + gchar const *format, + ...) G_GNUC_PRINTF (2, 3); + +gint g_vprintf (gchar const *format, + va_list args); +gint g_vfprintf (FILE *file, + gchar const *format, + va_list args); +gint g_vsprintf (gchar *string, + gchar const *format, + va_list args); +gint g_vasprintf (gchar **string, + gchar const *format, + va_list args); + +G_END_DECLS + +#endif /* __G_PRINTF_H__ */ diff --git a/glib/glib/gprintfint.h b/glib/glib/gprintfint.h new file mode 100644 index 0000000..0c975a1 --- /dev/null +++ b/glib/glib/gprintfint.h @@ -0,0 +1,59 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 2002. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#ifndef __G_PRINTFINT_H__ +#define __G_PRINTFINT_H__ + +#ifdef HAVE_GOOD_PRINTF + +#define _g_printf printf +#define _g_fprintf fprintf +#define _g_sprintf sprintf +#define _g_snprintf snprintf + +#define _g_vprintf vprintf +#define _g_vfprintf vfprintf +#define _g_vsprintf vsprintf +#define _g_vsnprintf vsnprintf + +#else + +#include "gnulib/printf.h" + +#define _g_printf _g_gnulib_printf +#define _g_fprintf _g_gnulib_fprintf +#define _g_sprintf _g_gnulib_sprintf +#define _g_snprintf _g_gnulib_snprintf + +#define _g_vprintf _g_gnulib_vprintf +#define _g_vfprintf _g_gnulib_vfprintf +#define _g_vsprintf _g_gnulib_vsprintf +#define _g_vsnprintf _g_gnulib_vsnprintf + +#endif + +#endif /* __G_PRINTF_H__ */ + diff --git a/glib/glib/gqsort.c b/glib/glib/gqsort.c new file mode 100644 index 0000000..fc699ea --- /dev/null +++ b/glib/glib/gqsort.c @@ -0,0 +1,306 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1991, 1992, 1996, 1997,1999,2004 Free Software Foundation, Inc. + * Copyright (C) 2000 Eazel, Inc. + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include "galloca.h" +#include "gmem.h" + +#include "gqsort.h" + +#include "gtestutils.h" + +/* This file was originally from stdlib/msort.c in gnu libc, just changed + to build inside glib and to not fall back to an unstable quicksort + for large arrays. */ + +/* An alternative to qsort, with an identical interface. + This file is part of the GNU C Library. + Copyright (C) 1992,95-97,99,2000,01,02,04,07 Free Software Foundation, Inc. + Written by Mike Haertel, September 1988. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + + +struct msort_param +{ + size_t s; + size_t var; + GCompareDataFunc cmp; + void *arg; + char *t; +}; + +static void msort_with_tmp (const struct msort_param *p, void *b, size_t n); + +static void +msort_with_tmp (const struct msort_param *p, void *b, size_t n) +{ + char *b1, *b2; + size_t n1, n2; + char *tmp = p->t; + const size_t s = p->s; + GCompareDataFunc cmp = p->cmp; + void *arg = p->arg; + + if (n <= 1) + return; + + n1 = n / 2; + n2 = n - n1; + b1 = b; + b2 = (char *) b + (n1 * p->s); + + msort_with_tmp (p, b1, n1); + msort_with_tmp (p, b2, n2); + + switch (p->var) + { + case 0: + while (n1 > 0 && n2 > 0) + { + if ((*cmp) (b1, b2, arg) <= 0) + { + *(guint32 *) tmp = *(guint32 *) b1; + b1 += sizeof (guint32); + --n1; + } + else + { + *(guint32 *) tmp = *(guint32 *) b2; + b2 += sizeof (guint32); + --n2; + } + tmp += sizeof (guint32); + } + break; + case 1: + while (n1 > 0 && n2 > 0) + { + if ((*cmp) (b1, b2, arg) <= 0) + { + *(guint64 *) tmp = *(guint64 *) b1; + b1 += sizeof (guint64); + --n1; + } + else + { + *(guint64 *) tmp = *(guint64 *) b2; + b2 += sizeof (guint64); + --n2; + } + tmp += sizeof (guint64); + } + break; + case 2: + while (n1 > 0 && n2 > 0) + { + unsigned long *tmpl = (unsigned long *) tmp; + unsigned long *bl; + + tmp += s; + if ((*cmp) (b1, b2, arg) <= 0) + { + bl = (unsigned long *) b1; + b1 += s; + --n1; + } + else + { + bl = (unsigned long *) b2; + b2 += s; + --n2; + } + while (tmpl < (unsigned long *) tmp) + *tmpl++ = *bl++; + } + break; + case 3: + while (n1 > 0 && n2 > 0) + { + if ((*cmp) (*(const void **) b1, *(const void **) b2, arg) <= 0) + { + *(void **) tmp = *(void **) b1; + b1 += sizeof (void *); + --n1; + } + else + { + *(void **) tmp = *(void **) b2; + b2 += sizeof (void *); + --n2; + } + tmp += sizeof (void *); + } + break; + default: + while (n1 > 0 && n2 > 0) + { + if ((*cmp) (b1, b2, arg) <= 0) + { + memcpy (tmp, b1, s); + tmp += s; + b1 += s; + --n1; + } + else + { + memcpy (tmp, b2, s); + tmp += s; + b2 += s; + --n2; + } + } + break; + } + + if (n1 > 0) + memcpy (tmp, b1, n1 * s); + memcpy (b, p->t, (n - n2) * s); +} + + +static void +msort_r (void *b, size_t n, size_t s, GCompareDataFunc cmp, void *arg) +{ + size_t size = n * s; + char *tmp = NULL; + struct msort_param p; + + /* For large object sizes use indirect sorting. */ + if (s > 32) + size = 2 * n * sizeof (void *) + s; + + if (size < 1024) + /* The temporary array is small, so put it on the stack. */ + p.t = g_alloca (size); + else + { + /* It's large, so malloc it. */ + tmp = g_malloc (size); + p.t = tmp; + } + + p.s = s; + p.var = 4; + p.cmp = cmp; + p.arg = arg; + + if (s > 32) + { + /* Indirect sorting. */ + char *ip = (char *) b; + void **tp = (void **) (p.t + n * sizeof (void *)); + void **t = tp; + void *tmp_storage = (void *) (tp + n); + char *kp; + size_t i; + + while ((void *) t < tmp_storage) + { + *t++ = ip; + ip += s; + } + p.s = sizeof (void *); + p.var = 3; + msort_with_tmp (&p, p.t + n * sizeof (void *), n); + + /* tp[0] .. tp[n - 1] is now sorted, copy around entries of + the original array. Knuth vol. 3 (2nd ed.) exercise 5.2-10. */ + for (i = 0, ip = (char *) b; i < n; i++, ip += s) + if ((kp = tp[i]) != ip) + { + size_t j = i; + char *jp = ip; + memcpy (tmp_storage, ip, s); + + do + { + size_t k = (kp - (char *) b) / s; + tp[j] = jp; + memcpy (jp, kp, s); + j = k; + jp = kp; + kp = tp[k]; + } + while (kp != ip); + + tp[j] = jp; + memcpy (jp, tmp_storage, s); + } + } + else + { + if ((s & (sizeof (guint32) - 1)) == 0 + && ((char *) b - (char *) 0) % ALIGNOF_GUINT32 == 0) + { + if (s == sizeof (guint32)) + p.var = 0; + else if (s == sizeof (guint64) + && ((char *) b - (char *) 0) % ALIGNOF_GUINT64 == 0) + p.var = 1; + else if ((s & (sizeof (unsigned long) - 1)) == 0 + && ((char *) b - (char *) 0) + % ALIGNOF_UNSIGNED_LONG == 0) + p.var = 2; + } + msort_with_tmp (&p, b, n); + } + g_free (tmp); +} + +/** + * g_qsort_with_data: + * @pbase: start of array to sort + * @total_elems: elements in the array + * @size: size of each element + * @compare_func: function to compare elements + * @user_data: data to pass to @compare_func + * + * This is just like the standard C qsort() function, but + * the comparison routine accepts a user data argument. + * + * This is guaranteed to be a stable sort since version 2.32. + */ +void +g_qsort_with_data (gconstpointer pbase, + gint total_elems, + gsize size, + GCompareDataFunc compare_func, + gpointer user_data) +{ + msort_r ((gpointer)pbase, total_elems, size, compare_func, user_data); +} diff --git a/glib/glib/gqsort.h b/glib/glib/gqsort.h new file mode 100644 index 0000000..05b4b66 --- /dev/null +++ b/glib/glib/gqsort.h @@ -0,0 +1,46 @@ + /* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_QSORT_H__ +#define __G_QSORT_H__ + +#include + +G_BEGIN_DECLS + +void g_qsort_with_data (gconstpointer pbase, + gint total_elems, + gsize size, + GCompareDataFunc compare_func, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_QSORT_H__ */ diff --git a/glib/glib/gquark.h b/glib/glib/gquark.h new file mode 100644 index 0000000..78b9546 --- /dev/null +++ b/glib/glib/gquark.h @@ -0,0 +1,52 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_QUARK_H__ +#define __G_QUARK_H__ + +#include + +G_BEGIN_DECLS + +typedef guint32 GQuark; + +/* Quarks (string<->id association) + */ +GQuark g_quark_try_string (const gchar *string); +GQuark g_quark_from_static_string (const gchar *string); +GQuark g_quark_from_string (const gchar *string); +const gchar * g_quark_to_string (GQuark quark) G_GNUC_CONST; + +const gchar * g_intern_string (const gchar *string); +const gchar * g_intern_static_string (const gchar *string); + +G_END_DECLS + +#endif /* __G_QUARK_H__ */ diff --git a/glib/glib/gqueue.c b/glib/glib/gqueue.c new file mode 100644 index 0000000..d9ee3a8 --- /dev/null +++ b/glib/glib/gqueue.c @@ -0,0 +1,1072 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GQueue: Double ended queue implementation, piggy backed on GList. + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * MT safe + */ + +/** + * SECTION:queue + * @Title: Double-ended Queues + * @Short_description: double-ended queue data structure + * + * The #GQueue structure and its associated functions provide a standard + * queue data structure. Internally, GQueue uses the same data structure + * as #GList to store elements. + * + * The data contained in each element can be either integer values, by + * using one of the Type + * Conversion Macros, or simply pointers to any type of data. + * + * To create a new GQueue, use g_queue_new(). + * + * To initialize a statically-allocated GQueue, use #G_QUEUE_INIT or + * g_queue_init(). + * + * To add elements, use g_queue_push_head(), g_queue_push_head_link(), + * g_queue_push_tail() and g_queue_push_tail_link(). + * + * To remove elements, use g_queue_pop_head() and g_queue_pop_tail(). + * + * To free the entire queue, use g_queue_free(). + */ +#include "config.h" + +#include "gqueue.h" + +#include "gtestutils.h" +#include "gslice.h" + +/** + * g_queue_new: + * + * Creates a new #GQueue. + * + * Returns: a new #GQueue. + **/ +GQueue* +g_queue_new (void) +{ + return g_slice_new0 (GQueue); +} + +/** + * g_queue_free: + * @queue: a #GQueue. + * + * Frees the memory allocated for the #GQueue. Only call this function if + * @queue was created with g_queue_new(). If queue elements contain + * dynamically-allocated memory, they should be freed first. + * + * + * If queue elements contain dynamically-allocated memory, + * you should either use g_queue_free_full() or free them manually + * first. + * + **/ +void +g_queue_free (GQueue *queue) +{ + g_return_if_fail (queue != NULL); + + g_list_free (queue->head); + g_slice_free (GQueue, queue); +} + +/** + * g_queue_free_full: + * @queue: a pointer to a #GQueue + * @free_func: the function to be called to free each element's data + * + * Convenience method, which frees all the memory used by a #GQueue, and + * calls the specified destroy function on every element's data. + * + * Since: 2.32 + */ +void +g_queue_free_full (GQueue *queue, + GDestroyNotify free_func) +{ + g_queue_foreach (queue, (GFunc) free_func, NULL); + g_queue_free (queue); +} + +/** + * g_queue_init: + * @queue: an uninitialized #GQueue + * + * A statically-allocated #GQueue must be initialized with this function + * before it can be used. Alternatively you can initialize it with + * #G_QUEUE_INIT. It is not necessary to initialize queues created with + * g_queue_new(). + * + * Since: 2.14 + **/ +void +g_queue_init (GQueue *queue) +{ + g_return_if_fail (queue != NULL); + + queue->head = queue->tail = NULL; + queue->length = 0; +} + +/** + * g_queue_clear: + * @queue: a #GQueue + * + * Removes all the elements in @queue. If queue elements contain + * dynamically-allocated memory, they should be freed first. + * + * Since: 2.14 + */ +void +g_queue_clear (GQueue *queue) +{ + g_return_if_fail (queue != NULL); + + g_list_free (queue->head); + g_queue_init (queue); +} + +/** + * g_queue_is_empty: + * @queue: a #GQueue. + * + * Returns %TRUE if the queue is empty. + * + * Returns: %TRUE if the queue is empty. + **/ +gboolean +g_queue_is_empty (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, TRUE); + + return queue->head == NULL; +} + +/** + * g_queue_get_length: + * @queue: a #GQueue + * + * Returns the number of items in @queue. + * + * Return value: The number of items in @queue. + * + * Since: 2.4 + **/ +guint +g_queue_get_length (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, 0); + + return queue->length; +} + +/** + * g_queue_reverse: + * @queue: a #GQueue + * + * Reverses the order of the items in @queue. + * + * Since: 2.4 + **/ +void +g_queue_reverse (GQueue *queue) +{ + g_return_if_fail (queue != NULL); + + queue->tail = queue->head; + queue->head = g_list_reverse (queue->head); +} + +/** + * g_queue_copy: + * @queue: a #GQueue + * + * Copies a @queue. Note that is a shallow copy. If the elements in the + * queue consist of pointers to data, the pointers are copied, but the + * actual data is not. + * + * Return value: A copy of @queue + * + * Since: 2.4 + **/ +GQueue * +g_queue_copy (GQueue *queue) +{ + GQueue *result; + GList *list; + + g_return_val_if_fail (queue != NULL, NULL); + + result = g_queue_new (); + + for (list = queue->head; list != NULL; list = list->next) + g_queue_push_tail (result, list->data); + + return result; +} + +/** + * g_queue_foreach: + * @queue: a #GQueue + * @func: the function to call for each element's data + * @user_data: user data to pass to @func + * + * Calls @func for each element in the queue passing @user_data to the + * function. + * + * Since: 2.4 + **/ +void +g_queue_foreach (GQueue *queue, + GFunc func, + gpointer user_data) +{ + GList *list; + + g_return_if_fail (queue != NULL); + g_return_if_fail (func != NULL); + + list = queue->head; + while (list) + { + GList *next = list->next; + func (list->data, user_data); + list = next; + } +} + +/** + * g_queue_find: + * @queue: a #GQueue + * @data: data to find + * + * Finds the first link in @queue which contains @data. + * + * Return value: The first link in @queue which contains @data. + * + * Since: 2.4 + **/ +GList * +g_queue_find (GQueue *queue, + gconstpointer data) +{ + g_return_val_if_fail (queue != NULL, NULL); + + return g_list_find (queue->head, data); +} + +/** + * g_queue_find_custom: + * @queue: a #GQueue + * @data: user data passed to @func + * @func: a #GCompareFunc to call for each element. It should return 0 + * when the desired element is found + * + * Finds an element in a #GQueue, using a supplied function to find the + * desired element. It iterates over the queue, calling the given function + * which should return 0 when the desired element is found. The function + * takes two gconstpointer arguments, the #GQueue element's data as the + * first argument and the given user data as the second argument. + * + * Return value: The found link, or %NULL if it wasn't found + * + * Since: 2.4 + **/ +GList * +g_queue_find_custom (GQueue *queue, + gconstpointer data, + GCompareFunc func) +{ + g_return_val_if_fail (queue != NULL, NULL); + g_return_val_if_fail (func != NULL, NULL); + + return g_list_find_custom (queue->head, data, func); +} + +/** + * g_queue_sort: + * @queue: a #GQueue + * @compare_func: the #GCompareDataFunc used to sort @queue. This function + * is passed two elements of the queue and should return 0 if they are + * equal, a negative value if the first comes before the second, and + * a positive value if the second comes before the first. + * @user_data: user data passed to @compare_func + * + * Sorts @queue using @compare_func. + * + * Since: 2.4 + **/ +void +g_queue_sort (GQueue *queue, + GCompareDataFunc compare_func, + gpointer user_data) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (compare_func != NULL); + + queue->head = g_list_sort_with_data (queue->head, compare_func, user_data); + queue->tail = g_list_last (queue->head); +} + +/** + * g_queue_push_head: + * @queue: a #GQueue. + * @data: the data for the new element. + * + * Adds a new element at the head of the queue. + **/ +void +g_queue_push_head (GQueue *queue, + gpointer data) +{ + g_return_if_fail (queue != NULL); + + queue->head = g_list_prepend (queue->head, data); + if (!queue->tail) + queue->tail = queue->head; + queue->length++; +} + +/** + * g_queue_push_nth: + * @queue: a #GQueue + * @data: the data for the new element + * @n: the position to insert the new element. If @n is negative or + * larger than the number of elements in the @queue, the element is + * added to the end of the queue. + * + * Inserts a new element into @queue at the given position + * + * Since: 2.4 + **/ +void +g_queue_push_nth (GQueue *queue, + gpointer data, + gint n) +{ + g_return_if_fail (queue != NULL); + + if (n < 0 || n >= queue->length) + { + g_queue_push_tail (queue, data); + return; + } + + g_queue_insert_before (queue, g_queue_peek_nth_link (queue, n), data); +} + +/** + * g_queue_push_head_link: + * @queue: a #GQueue. + * @link_: a single #GList element, not a list with + * more than one element. + * + * Adds a new element at the head of the queue. + **/ +void +g_queue_push_head_link (GQueue *queue, + GList *link) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (link != NULL); + g_return_if_fail (link->prev == NULL); + g_return_if_fail (link->next == NULL); + + link->next = queue->head; + if (queue->head) + queue->head->prev = link; + else + queue->tail = link; + queue->head = link; + queue->length++; +} + +/** + * g_queue_push_tail: + * @queue: a #GQueue. + * @data: the data for the new element. + * + * Adds a new element at the tail of the queue. + **/ +void +g_queue_push_tail (GQueue *queue, + gpointer data) +{ + g_return_if_fail (queue != NULL); + + queue->tail = g_list_append (queue->tail, data); + if (queue->tail->next) + queue->tail = queue->tail->next; + else + queue->head = queue->tail; + queue->length++; +} + +/** + * g_queue_push_tail_link: + * @queue: a #GQueue. + * @link_: a single #GList element, not a list with + * more than one element. + * + * Adds a new element at the tail of the queue. + **/ +void +g_queue_push_tail_link (GQueue *queue, + GList *link) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (link != NULL); + g_return_if_fail (link->prev == NULL); + g_return_if_fail (link->next == NULL); + + link->prev = queue->tail; + if (queue->tail) + queue->tail->next = link; + else + queue->head = link; + queue->tail = link; + queue->length++; +} + +/** + * g_queue_push_nth_link: + * @queue: a #GQueue + * @n: the position to insert the link. If this is negative or larger than + * the number of elements in @queue, the link is added to the end of + * @queue. + * @link_: the link to add to @queue + * + * Inserts @link into @queue at the given position. + * + * Since: 2.4 + **/ +void +g_queue_push_nth_link (GQueue *queue, + gint n, + GList *link_) +{ + GList *next; + GList *prev; + + g_return_if_fail (queue != NULL); + g_return_if_fail (link_ != NULL); + + if (n < 0 || n >= queue->length) + { + g_queue_push_tail_link (queue, link_); + return; + } + + g_assert (queue->head); + g_assert (queue->tail); + + next = g_queue_peek_nth_link (queue, n); + prev = next->prev; + + if (prev) + prev->next = link_; + next->prev = link_; + + link_->next = next; + link_->prev = prev; + + if (queue->head->prev) + queue->head = queue->head->prev; + + if (queue->tail->next) + queue->tail = queue->tail->next; + + queue->length++; +} + +/** + * g_queue_pop_head: + * @queue: a #GQueue. + * + * Removes the first element of the queue. + * + * Returns: the data of the first element in the queue, or %NULL if the queue + * is empty. + **/ +gpointer +g_queue_pop_head (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + if (queue->head) + { + GList *node = queue->head; + gpointer data = node->data; + + queue->head = node->next; + if (queue->head) + queue->head->prev = NULL; + else + queue->tail = NULL; + g_list_free_1 (node); + queue->length--; + + return data; + } + + return NULL; +} + +/** + * g_queue_pop_head_link: + * @queue: a #GQueue. + * + * Removes the first element of the queue. + * + * Returns: the #GList element at the head of the queue, or %NULL if the queue + * is empty. + **/ +GList* +g_queue_pop_head_link (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + if (queue->head) + { + GList *node = queue->head; + + queue->head = node->next; + if (queue->head) + { + queue->head->prev = NULL; + node->next = NULL; + } + else + queue->tail = NULL; + queue->length--; + + return node; + } + + return NULL; +} + +/** + * g_queue_peek_head_link: + * @queue: a #GQueue + * + * Returns the first link in @queue + * + * Return value: the first link in @queue, or %NULL if @queue is empty + * + * Since: 2.4 + **/ +GList* +g_queue_peek_head_link (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + return queue->head; +} + +/** + * g_queue_peek_tail_link: + * @queue: a #GQueue + * + * Returns the last link @queue. + * + * Return value: the last link in @queue, or %NULL if @queue is empty + * + * Since: 2.4 + **/ +GList* +g_queue_peek_tail_link (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + return queue->tail; +} + +/** + * g_queue_pop_tail: + * @queue: a #GQueue. + * + * Removes the last element of the queue. + * + * Returns: the data of the last element in the queue, or %NULL if the queue + * is empty. + **/ +gpointer +g_queue_pop_tail (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + if (queue->tail) + { + GList *node = queue->tail; + gpointer data = node->data; + + queue->tail = node->prev; + if (queue->tail) + queue->tail->next = NULL; + else + queue->head = NULL; + queue->length--; + g_list_free_1 (node); + + return data; + } + + return NULL; +} + +/** + * g_queue_pop_nth: + * @queue: a #GQueue + * @n: the position of the element. + * + * Removes the @n'th element of @queue. + * + * Return value: the element's data, or %NULL if @n is off the end of @queue. + * + * Since: 2.4 + **/ +gpointer +g_queue_pop_nth (GQueue *queue, + guint n) +{ + GList *nth_link; + gpointer result; + + g_return_val_if_fail (queue != NULL, NULL); + + if (n >= queue->length) + return NULL; + + nth_link = g_queue_peek_nth_link (queue, n); + result = nth_link->data; + + g_queue_delete_link (queue, nth_link); + + return result; +} + +/** + * g_queue_pop_tail_link: + * @queue: a #GQueue. + * + * Removes the last element of the queue. + * + * Returns: the #GList element at the tail of the queue, or %NULL if the queue + * is empty. + **/ +GList* +g_queue_pop_tail_link (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + if (queue->tail) + { + GList *node = queue->tail; + + queue->tail = node->prev; + if (queue->tail) + { + queue->tail->next = NULL; + node->prev = NULL; + } + else + queue->head = NULL; + queue->length--; + + return node; + } + + return NULL; +} + +/** + * g_queue_pop_nth_link: + * @queue: a #GQueue + * @n: the link's position + * + * Removes and returns the link at the given position. + * + * Return value: The @n'th link, or %NULL if @n is off the end of @queue. + * + * Since: 2.4 + **/ +GList* +g_queue_pop_nth_link (GQueue *queue, + guint n) +{ + GList *link; + + g_return_val_if_fail (queue != NULL, NULL); + + if (n >= queue->length) + return NULL; + + link = g_queue_peek_nth_link (queue, n); + g_queue_unlink (queue, link); + + return link; +} + +/** + * g_queue_peek_nth_link: + * @queue: a #GQueue + * @n: the position of the link + * + * Returns the link at the given position + * + * Return value: The link at the @n'th position, or %NULL if @n is off the + * end of the list + * + * Since: 2.4 + **/ +GList * +g_queue_peek_nth_link (GQueue *queue, + guint n) +{ + GList *link; + gint i; + + g_return_val_if_fail (queue != NULL, NULL); + + if (n >= queue->length) + return NULL; + + if (n > queue->length / 2) + { + n = queue->length - n - 1; + + link = queue->tail; + for (i = 0; i < n; ++i) + link = link->prev; + } + else + { + link = queue->head; + for (i = 0; i < n; ++i) + link = link->next; + } + + return link; +} + +/** + * g_queue_link_index: + * @queue: a #GQueue + * @link_: A #GList link + * + * Returns the position of @link_ in @queue. + * + * Return value: The position of @link_, or -1 if the link is + * not part of @queue + * + * Since: 2.4 + **/ +gint +g_queue_link_index (GQueue *queue, + GList *link_) +{ + g_return_val_if_fail (queue != NULL, -1); + + return g_list_position (queue->head, link_); +} + +/** + * g_queue_unlink + * @queue: a #GQueue + * @link_: a #GList link that must be part of @queue + * + * Unlinks @link_ so that it will no longer be part of @queue. The link is + * not freed. + * + * @link_ must be part of @queue, + * + * Since: 2.4 + **/ +void +g_queue_unlink (GQueue *queue, + GList *link_) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (link_ != NULL); + + if (link_ == queue->tail) + queue->tail = queue->tail->prev; + + queue->head = g_list_remove_link (queue->head, link_); + queue->length--; +} + +/** + * g_queue_delete_link: + * @queue: a #GQueue + * @link_: a #GList link that must be part of @queue + * + * Removes @link_ from @queue and frees it. + * + * @link_ must be part of @queue. + * + * Since: 2.4 + **/ +void +g_queue_delete_link (GQueue *queue, + GList *link_) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (link_ != NULL); + + g_queue_unlink (queue, link_); + g_list_free (link_); +} + +/** + * g_queue_peek_head: + * @queue: a #GQueue. + * + * Returns the first element of the queue. + * + * Returns: the data of the first element in the queue, or %NULL if the queue + * is empty. + **/ +gpointer +g_queue_peek_head (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + return queue->head ? queue->head->data : NULL; +} + +/** + * g_queue_peek_tail: + * @queue: a #GQueue. + * + * Returns the last element of the queue. + * + * Returns: the data of the last element in the queue, or %NULL if the queue + * is empty. + **/ +gpointer +g_queue_peek_tail (GQueue *queue) +{ + g_return_val_if_fail (queue != NULL, NULL); + + return queue->tail ? queue->tail->data : NULL; +} + +/** + * g_queue_peek_nth: + * @queue: a #GQueue + * @n: the position of the element. + * + * Returns the @n'th element of @queue. + * + * Return value: The data for the @n'th element of @queue, or %NULL if @n is + * off the end of @queue. + * + * Since: 2.4 + **/ +gpointer +g_queue_peek_nth (GQueue *queue, + guint n) +{ + GList *link; + + g_return_val_if_fail (queue != NULL, NULL); + + link = g_queue_peek_nth_link (queue, n); + + if (link) + return link->data; + + return NULL; +} + +/** + * g_queue_index: + * @queue: a #GQueue + * @data: the data to find. + * + * Returns the position of the first element in @queue which contains @data. + * + * Return value: The position of the first element in @queue which contains @data, or -1 if no element in @queue contains @data. + * + * Since: 2.4 + **/ +gint +g_queue_index (GQueue *queue, + gconstpointer data) +{ + g_return_val_if_fail (queue != NULL, -1); + + return g_list_index (queue->head, data); +} + +/** + * g_queue_remove: + * @queue: a #GQueue + * @data: data to remove. + * + * Removes the first element in @queue that contains @data. + * + * Return value: %TRUE if @data was found and removed from @queue + * + * Since: 2.4 + **/ +gboolean +g_queue_remove (GQueue *queue, + gconstpointer data) +{ + GList *link; + + g_return_val_if_fail (queue != NULL, FALSE); + + link = g_list_find (queue->head, data); + + if (link) + g_queue_delete_link (queue, link); + + return (link != NULL); +} + +/** + * g_queue_remove_all: + * @queue: a #GQueue + * @data: data to remove + * + * Remove all elements whose data equals @data from @queue. + * + * Return value: the number of elements removed from @queue + * + * Since: 2.4 + **/ +guint +g_queue_remove_all (GQueue *queue, + gconstpointer data) +{ + GList *list; + guint old_length; + + g_return_val_if_fail (queue != NULL, 0); + + old_length = queue->length; + + list = queue->head; + while (list) + { + GList *next = list->next; + + if (list->data == data) + g_queue_delete_link (queue, list); + + list = next; + } + + return (old_length - queue->length); +} + +/** + * g_queue_insert_before: + * @queue: a #GQueue + * @sibling: a #GList link that must be part of @queue + * @data: the data to insert + * + * Inserts @data into @queue before @sibling. + * + * @sibling must be part of @queue. + * + * Since: 2.4 + **/ +void +g_queue_insert_before (GQueue *queue, + GList *sibling, + gpointer data) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (sibling != NULL); + + queue->head = g_list_insert_before (queue->head, sibling, data); + queue->length++; +} + +/** + * g_queue_insert_after: + * @queue: a #GQueue + * @sibling: a #GList link that must be part of @queue + * @data: the data to insert + * + * Inserts @data into @queue after @sibling + * + * @sibling must be part of @queue + * + * Since: 2.4 + **/ +void +g_queue_insert_after (GQueue *queue, + GList *sibling, + gpointer data) +{ + g_return_if_fail (queue != NULL); + g_return_if_fail (sibling != NULL); + + if (sibling == queue->tail) + g_queue_push_tail (queue, data); + else + g_queue_insert_before (queue, sibling->next, data); +} + +/** + * g_queue_insert_sorted: + * @queue: a #GQueue + * @data: the data to insert + * @func: the #GCompareDataFunc used to compare elements in the queue. It is + * called with two elements of the @queue and @user_data. It should + * return 0 if the elements are equal, a negative value if the first + * element comes before the second, and a positive value if the second + * element comes before the first. + * @user_data: user data passed to @func. + * + * Inserts @data into @queue using @func to determine the new position. + * + * Since: 2.4 + **/ +void +g_queue_insert_sorted (GQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data) +{ + GList *list; + + g_return_if_fail (queue != NULL); + + list = queue->head; + while (list && func (list->data, data, user_data) < 0) + list = list->next; + + if (list) + g_queue_insert_before (queue, list, data); + else + g_queue_push_tail (queue, data); +} diff --git a/glib/glib/gqueue.h b/glib/glib/gqueue.h new file mode 100644 index 0000000..1d13eef --- /dev/null +++ b/glib/glib/gqueue.h @@ -0,0 +1,152 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_QUEUE_H__ +#define __G_QUEUE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GQueue GQueue; + +/** + * GQueue: + * @head: a pointer to the first element of the queue + * @tail: a pointer to the last element of the queue + * @length: the number of elements in the queue + * + * Contains the public fields of a + * Queue. + */ +struct _GQueue +{ + GList *head; + GList *tail; + guint length; +}; + +/** + * G_QUEUE_INIT: + * + * A statically-allocated #GQueue must be initialized with this + * macro before it can be used. This macro can be used to initialize + * a variable, but it cannot be assigned to a variable. In that case + * you have to use g_queue_init(). + * + * |[ + * GQueue my_queue = G_QUEUE_INIT; + * ]| + * + * Since: 2.14 + */ +#define G_QUEUE_INIT { NULL, NULL, 0 } + +/* Queues + */ +GQueue* g_queue_new (void); +void g_queue_free (GQueue *queue); +void g_queue_free_full (GQueue *queue, + GDestroyNotify free_func); +void g_queue_init (GQueue *queue); +void g_queue_clear (GQueue *queue); +gboolean g_queue_is_empty (GQueue *queue); +guint g_queue_get_length (GQueue *queue); +void g_queue_reverse (GQueue *queue); +GQueue * g_queue_copy (GQueue *queue); +void g_queue_foreach (GQueue *queue, + GFunc func, + gpointer user_data); +GList * g_queue_find (GQueue *queue, + gconstpointer data); +GList * g_queue_find_custom (GQueue *queue, + gconstpointer data, + GCompareFunc func); +void g_queue_sort (GQueue *queue, + GCompareDataFunc compare_func, + gpointer user_data); + +void g_queue_push_head (GQueue *queue, + gpointer data); +void g_queue_push_tail (GQueue *queue, + gpointer data); +void g_queue_push_nth (GQueue *queue, + gpointer data, + gint n); +gpointer g_queue_pop_head (GQueue *queue); +gpointer g_queue_pop_tail (GQueue *queue); +gpointer g_queue_pop_nth (GQueue *queue, + guint n); +gpointer g_queue_peek_head (GQueue *queue); +gpointer g_queue_peek_tail (GQueue *queue); +gpointer g_queue_peek_nth (GQueue *queue, + guint n); +gint g_queue_index (GQueue *queue, + gconstpointer data); +gboolean g_queue_remove (GQueue *queue, + gconstpointer data); +guint g_queue_remove_all (GQueue *queue, + gconstpointer data); +void g_queue_insert_before (GQueue *queue, + GList *sibling, + gpointer data); +void g_queue_insert_after (GQueue *queue, + GList *sibling, + gpointer data); +void g_queue_insert_sorted (GQueue *queue, + gpointer data, + GCompareDataFunc func, + gpointer user_data); + +void g_queue_push_head_link (GQueue *queue, + GList *link_); +void g_queue_push_tail_link (GQueue *queue, + GList *link_); +void g_queue_push_nth_link (GQueue *queue, + gint n, + GList *link_); +GList* g_queue_pop_head_link (GQueue *queue); +GList* g_queue_pop_tail_link (GQueue *queue); +GList* g_queue_pop_nth_link (GQueue *queue, + guint n); +GList* g_queue_peek_head_link (GQueue *queue); +GList* g_queue_peek_tail_link (GQueue *queue); +GList* g_queue_peek_nth_link (GQueue *queue, + guint n); +gint g_queue_link_index (GQueue *queue, + GList *link_); +void g_queue_unlink (GQueue *queue, + GList *link_); +void g_queue_delete_link (GQueue *queue, + GList *link_); + +G_END_DECLS + +#endif /* __G_QUEUE_H__ */ diff --git a/glib/glib/grand.c b/glib/glib/grand.c new file mode 100644 index 0000000..0405628 --- /dev/null +++ b/glib/glib/grand.c @@ -0,0 +1,695 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* Originally developed and coded by Makoto Matsumoto and Takuji + * Nishimura. Please mail , if you're using + * code from this file in your own programs or libraries. + * Further information on the Mersenne Twister can be found at + * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html + * This code was adapted to glib by Sebastian Wilhelmi. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "grand.h" + +#include "genviron.h" +#include "gmain.h" +#include "gmem.h" +#include "gtestutils.h" +#include "gthread.h" + +#ifdef G_OS_WIN32 +#include /* For getpid() */ +#endif + +/** + * SECTION:random_numbers + * @title: Random Numbers + * @short_description: pseudo-random number generator + * + * The following functions allow you to use a portable, fast and good + * pseudo-random number generator (PRNG). It uses the Mersenne Twister + * PRNG, which was originally developed by Makoto Matsumoto and Takuji + * Nishimura. Further information can be found at + * + * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html. + * + * If you just need a random number, you simply call the + * g_random_* functions, which will create a + * globally used #GRand and use the according + * g_rand_* functions internally. Whenever you + * need a stream of reproducible random numbers, you better create a + * #GRand yourself and use the g_rand_* functions + * directly, which will also be slightly faster. Initializing a #GRand + * with a certain seed will produce exactly the same series of random + * numbers on all platforms. This can thus be used as a seed for e.g. + * games. + * + * The g_rand*_range functions will return high + * quality equally distributed random numbers, whereas for example the + * (g_random_int()%max) approach often + * doesn't yield equally distributed numbers. + * + * GLib changed the seeding algorithm for the pseudo-random number + * generator Mersenne Twister, as used by + * GRand and GRandom. + * This was necessary, because some seeds would yield very bad + * pseudo-random streams. Also the pseudo-random integers generated by + * g_rand*_int_range() will have a slightly better + * equal distribution with the new version of GLib. + * + * The original seeding and generation algorithms, as found in GLib + * 2.0.x, can be used instead of the new ones by setting the + * environment variable G_RANDOM_VERSION to the value of + * '2.0'. Use the GLib-2.0 algorithms only if you have sequences of + * numbers generated with Glib-2.0 that you need to reproduce exactly. + **/ + +/** + * GRand: + * + * The #GRand struct is an opaque data structure. It should only be + * accessed through the g_rand_* functions. + **/ + +G_LOCK_DEFINE_STATIC (global_random); +static GRand* global_random = NULL; + +/* Period parameters */ +#define N 624 +#define M 397 +#define MATRIX_A 0x9908b0df /* constant vector a */ +#define UPPER_MASK 0x80000000 /* most significant w-r bits */ +#define LOWER_MASK 0x7fffffff /* least significant r bits */ + +/* Tempering parameters */ +#define TEMPERING_MASK_B 0x9d2c5680 +#define TEMPERING_MASK_C 0xefc60000 +#define TEMPERING_SHIFT_U(y) (y >> 11) +#define TEMPERING_SHIFT_S(y) (y << 7) +#define TEMPERING_SHIFT_T(y) (y << 15) +#define TEMPERING_SHIFT_L(y) (y >> 18) + +static guint +get_random_version (void) +{ + static gsize initialized = FALSE; + static guint random_version; + + if (g_once_init_enter (&initialized)) + { + const gchar *version_string = g_getenv ("G_RANDOM_VERSION"); + if (!version_string || version_string[0] == '\000' || + strcmp (version_string, "2.2") == 0) + random_version = 22; + else if (strcmp (version_string, "2.0") == 0) + random_version = 20; + else + { + g_warning ("Unknown G_RANDOM_VERSION \"%s\". Using version 2.2.", + version_string); + random_version = 22; + } + g_once_init_leave (&initialized, TRUE); + } + + return random_version; +} + +struct _GRand +{ + guint32 mt[N]; /* the array for the state vector */ + guint mti; +}; + +/** + * g_rand_new_with_seed: + * @seed: a value to initialize the random number generator. + * + * Creates a new random number generator initialized with @seed. + * + * Return value: the new #GRand. + **/ +GRand* +g_rand_new_with_seed (guint32 seed) +{ + GRand *rand = g_new0 (GRand, 1); + g_rand_set_seed (rand, seed); + return rand; +} + +/** + * g_rand_new_with_seed_array: + * @seed: an array of seeds to initialize the random number generator. + * @seed_length: an array of seeds to initialize the random number generator. + * + * Creates a new random number generator initialized with @seed. + * + * Return value: the new #GRand. + * + * Since: 2.4 + **/ +GRand* +g_rand_new_with_seed_array (const guint32 *seed, guint seed_length) +{ + GRand *rand = g_new0 (GRand, 1); + g_rand_set_seed_array (rand, seed, seed_length); + return rand; +} + +/** + * g_rand_new: + * + * Creates a new random number generator initialized with a seed taken + * either from /dev/urandom (if existing) or from + * the current time (as a fallback). + * + * Return value: the new #GRand. + **/ +GRand* +g_rand_new (void) +{ + guint32 seed[4]; + GTimeVal now; +#ifdef G_OS_UNIX + static gboolean dev_urandom_exists = TRUE; + + if (dev_urandom_exists) + { + FILE* dev_urandom; + + do + { + errno = 0; + dev_urandom = fopen("/dev/urandom", "rb"); + } + while G_UNLIKELY (errno == EINTR); + + if (dev_urandom) + { + int r; + + setvbuf (dev_urandom, NULL, _IONBF, 0); + do + { + errno = 0; + r = fread (seed, sizeof (seed), 1, dev_urandom); + } + while G_UNLIKELY (errno == EINTR); + + if (r != 1) + dev_urandom_exists = FALSE; + + fclose (dev_urandom); + } + else + dev_urandom_exists = FALSE; + } +#else + static gboolean dev_urandom_exists = FALSE; +#endif + + if (!dev_urandom_exists) + { + g_get_current_time (&now); + seed[0] = now.tv_sec; + seed[1] = now.tv_usec; + seed[2] = getpid (); +#ifdef G_OS_UNIX + seed[3] = getppid (); +#else + seed[3] = 0; +#endif + } + + return g_rand_new_with_seed_array (seed, 4); +} + +/** + * g_rand_free: + * @rand_: a #GRand. + * + * Frees the memory allocated for the #GRand. + **/ +void +g_rand_free (GRand* rand) +{ + g_return_if_fail (rand != NULL); + + g_free (rand); +} + +/** + * g_rand_copy: + * @rand_: a #GRand. + * + * Copies a #GRand into a new one with the same exact state as before. + * This way you can take a snapshot of the random number generator for + * replaying later. + * + * Return value: the new #GRand. + * + * Since: 2.4 + **/ +GRand * +g_rand_copy (GRand* rand) +{ + GRand* new_rand; + + g_return_val_if_fail (rand != NULL, NULL); + + new_rand = g_new0 (GRand, 1); + memcpy (new_rand, rand, sizeof (GRand)); + + return new_rand; +} + +/** + * g_rand_set_seed: + * @rand_: a #GRand. + * @seed: a value to reinitialize the random number generator. + * + * Sets the seed for the random number generator #GRand to @seed. + **/ +void +g_rand_set_seed (GRand* rand, guint32 seed) +{ + g_return_if_fail (rand != NULL); + + switch (get_random_version ()) + { + case 20: + /* setting initial seeds to mt[N] using */ + /* the generator Line 25 of Table 1 in */ + /* [KNUTH 1981, The Art of Computer Programming */ + /* Vol. 2 (2nd Ed.), pp102] */ + + if (seed == 0) /* This would make the PRNG produce only zeros */ + seed = 0x6b842128; /* Just set it to another number */ + + rand->mt[0]= seed; + for (rand->mti=1; rand->mtimti++) + rand->mt[rand->mti] = (69069 * rand->mt[rand->mti-1]); + + break; + case 22: + /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ + /* In the previous version (see above), MSBs of the */ + /* seed affect only MSBs of the array mt[]. */ + + rand->mt[0]= seed; + for (rand->mti=1; rand->mtimti++) + rand->mt[rand->mti] = 1812433253UL * + (rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti; + break; + default: + g_assert_not_reached (); + } +} + +/** + * g_rand_set_seed_array: + * @rand_: a #GRand. + * @seed: array to initialize with + * @seed_length: length of array + * + * Initializes the random number generator by an array of + * longs. Array can be of arbitrary size, though only the + * first 624 values are taken. This function is useful + * if you have many low entropy seeds, or if you require more then + * 32bits of actual entropy for your application. + * + * Since: 2.4 + **/ +void +g_rand_set_seed_array (GRand* rand, const guint32 *seed, guint seed_length) +{ + int i, j, k; + + g_return_if_fail (rand != NULL); + g_return_if_fail (seed_length >= 1); + + g_rand_set_seed (rand, 19650218UL); + + i=1; j=0; + k = (N>seed_length ? N : seed_length); + for (; k; k--) + { + rand->mt[i] = (rand->mt[i] ^ + ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1664525UL)) + + seed[j] + j; /* non linear */ + rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; j++; + if (i>=N) + { + rand->mt[0] = rand->mt[N-1]; + i=1; + } + if (j>=seed_length) + j=0; + } + for (k=N-1; k; k--) + { + rand->mt[i] = (rand->mt[i] ^ + ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1566083941UL)) + - i; /* non linear */ + rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ + i++; + if (i>=N) + { + rand->mt[0] = rand->mt[N-1]; + i=1; + } + } + + rand->mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ +} + +/** + * g_rand_boolean: + * @rand_: a #GRand. + * @Returns: a random #gboolean. + * + * Returns a random #gboolean from @rand_. This corresponds to a + * unbiased coin toss. + **/ +/** + * g_rand_int: + * @rand_: a #GRand. + * + * Returns the next random #guint32 from @rand_ equally distributed over + * the range [0..2^32-1]. + * + * Return value: A random number. + **/ +guint32 +g_rand_int (GRand* rand) +{ + guint32 y; + static const guint32 mag01[2]={0x0, MATRIX_A}; + /* mag01[x] = x * MATRIX_A for x=0,1 */ + + g_return_val_if_fail (rand != NULL, 0); + + if (rand->mti >= N) { /* generate N words at one time */ + int kk; + + for (kk=0;kkmt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK); + rand->mt[kk] = rand->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1]; + } + for (;kkmt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK); + rand->mt[kk] = rand->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1]; + } + y = (rand->mt[N-1]&UPPER_MASK)|(rand->mt[0]&LOWER_MASK); + rand->mt[N-1] = rand->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1]; + + rand->mti = 0; + } + + y = rand->mt[rand->mti++]; + y ^= TEMPERING_SHIFT_U(y); + y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B; + y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C; + y ^= TEMPERING_SHIFT_L(y); + + return y; +} + +/* transform [0..2^32] -> [0..1] */ +#define G_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10 + +/** + * g_rand_int_range: + * @rand_: a #GRand. + * @begin: lower closed bound of the interval. + * @end: upper open bound of the interval. + * + * Returns the next random #gint32 from @rand_ equally distributed over + * the range [@begin..@end-1]. + * + * Return value: A random number. + **/ +gint32 +g_rand_int_range (GRand* rand, gint32 begin, gint32 end) +{ + guint32 dist = end - begin; + guint32 random; + + g_return_val_if_fail (rand != NULL, begin); + g_return_val_if_fail (end > begin, begin); + + switch (get_random_version ()) + { + case 20: + if (dist <= 0x10000L) /* 2^16 */ + { + /* This method, which only calls g_rand_int once is only good + * for (end - begin) <= 2^16, because we only have 32 bits set + * from the one call to g_rand_int (). */ + + /* we are using (trans + trans * trans), because g_rand_int only + * covers [0..2^32-1] and thus g_rand_int * trans only covers + * [0..1-2^-32], but the biggest double < 1 is 1-2^-52. + */ + + gdouble double_rand = g_rand_int (rand) * + (G_RAND_DOUBLE_TRANSFORM + + G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM); + + random = (gint32) (double_rand * dist); + } + else + { + /* Now we use g_rand_double_range (), which will set 52 bits for + us, so that it is safe to round and still get a decent + distribution */ + random = (gint32) g_rand_double_range (rand, 0, dist); + } + break; + case 22: + if (dist == 0) + random = 0; + else + { + /* maxvalue is set to the predecessor of the greatest + * multiple of dist less or equal 2^32. */ + guint32 maxvalue; + if (dist <= 0x80000000u) /* 2^31 */ + { + /* maxvalue = 2^32 - 1 - (2^32 % dist) */ + guint32 leftover = (0x80000000u % dist) * 2; + if (leftover >= dist) leftover -= dist; + maxvalue = 0xffffffffu - leftover; + } + else + maxvalue = dist - 1; + + do + random = g_rand_int (rand); + while (random > maxvalue); + + random %= dist; + } + break; + default: + random = 0; /* Quiet GCC */ + g_assert_not_reached (); + } + + return begin + random; +} + +/** + * g_rand_double: + * @rand_: a #GRand. + * + * Returns the next random #gdouble from @rand_ equally distributed over + * the range [0..1). + * + * Return value: A random number. + **/ +gdouble +g_rand_double (GRand* rand) +{ + /* We set all 52 bits after the point for this, not only the first + 32. Thats why we need two calls to g_rand_int */ + gdouble retval = g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM; + retval = (retval + g_rand_int (rand)) * G_RAND_DOUBLE_TRANSFORM; + + /* The following might happen due to very bad rounding luck, but + * actually this should be more than rare, we just try again then */ + if (retval >= 1.0) + return g_rand_double (rand); + + return retval; +} + +/** + * g_rand_double_range: + * @rand_: a #GRand. + * @begin: lower closed bound of the interval. + * @end: upper open bound of the interval. + * + * Returns the next random #gdouble from @rand_ equally distributed over + * the range [@begin..@end). + * + * Return value: A random number. + **/ +gdouble +g_rand_double_range (GRand* rand, gdouble begin, gdouble end) +{ + gdouble r; + + r = g_rand_double (rand); + + return r * end - (r - 1) * begin; +} + +/** + * g_random_boolean: + * @Returns: a random #gboolean. + * + * Returns a random #gboolean. This corresponds to a unbiased coin toss. + **/ +/** + * g_random_int: + * + * Return a random #guint32 equally distributed over the range + * [0..2^32-1]. + * + * Return value: A random number. + **/ +guint32 +g_random_int (void) +{ + guint32 result; + G_LOCK (global_random); + if (!global_random) + global_random = g_rand_new (); + + result = g_rand_int (global_random); + G_UNLOCK (global_random); + return result; +} + +/** + * g_random_int_range: + * @begin: lower closed bound of the interval. + * @end: upper open bound of the interval. + * + * Returns a random #gint32 equally distributed over the range + * [@begin..@end-1]. + * + * Return value: A random number. + **/ +gint32 +g_random_int_range (gint32 begin, gint32 end) +{ + gint32 result; + G_LOCK (global_random); + if (!global_random) + global_random = g_rand_new (); + + result = g_rand_int_range (global_random, begin, end); + G_UNLOCK (global_random); + return result; +} + +/** + * g_random_double: + * + * Returns a random #gdouble equally distributed over the range [0..1). + * + * Return value: A random number. + **/ +gdouble +g_random_double (void) +{ + double result; + G_LOCK (global_random); + if (!global_random) + global_random = g_rand_new (); + + result = g_rand_double (global_random); + G_UNLOCK (global_random); + return result; +} + +/** + * g_random_double_range: + * @begin: lower closed bound of the interval. + * @end: upper open bound of the interval. + * + * Returns a random #gdouble equally distributed over the range [@begin..@end). + * + * Return value: A random number. + **/ +gdouble +g_random_double_range (gdouble begin, gdouble end) +{ + double result; + G_LOCK (global_random); + if (!global_random) + global_random = g_rand_new (); + + result = g_rand_double_range (global_random, begin, end); + G_UNLOCK (global_random); + return result; +} + +/** + * g_random_set_seed: + * @seed: a value to reinitialize the global random number generator. + * + * Sets the seed for the global random number generator, which is used + * by the g_random_* functions, to @seed. + **/ +void +g_random_set_seed (guint32 seed) +{ + G_LOCK (global_random); + if (!global_random) + global_random = g_rand_new_with_seed (seed); + else + g_rand_set_seed (global_random, seed); + G_UNLOCK (global_random); +} diff --git a/glib/glib/grand.h b/glib/glib/grand.h new file mode 100644 index 0000000..182616b --- /dev/null +++ b/glib/glib/grand.h @@ -0,0 +1,85 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_RAND_H__ +#define __G_RAND_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GRand GRand; + +/* GRand - a good and fast random number generator: Mersenne Twister + * see http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html for more info. + * The range functions return a value in the intervall [begin, end). + * int -> [0..2^32-1] + * int_range -> [begin..end-1] + * double -> [0..1) + * double_range -> [begin..end) + */ + +GRand* g_rand_new_with_seed (guint32 seed); +GRand* g_rand_new_with_seed_array (const guint32 *seed, + guint seed_length); +GRand* g_rand_new (void); +void g_rand_free (GRand *rand_); +GRand* g_rand_copy (GRand *rand_); +void g_rand_set_seed (GRand *rand_, + guint32 seed); +void g_rand_set_seed_array (GRand *rand_, + const guint32 *seed, + guint seed_length); + +#define g_rand_boolean(rand_) ((g_rand_int (rand_) & (1 << 15)) != 0) + +guint32 g_rand_int (GRand *rand_); +gint32 g_rand_int_range (GRand *rand_, + gint32 begin, + gint32 end); +gdouble g_rand_double (GRand *rand_); +gdouble g_rand_double_range (GRand *rand_, + gdouble begin, + gdouble end); +void g_random_set_seed (guint32 seed); + +#define g_random_boolean() ((g_random_int () & (1 << 15)) != 0) + +guint32 g_random_int (void); +gint32 g_random_int_range (gint32 begin, + gint32 end); +gdouble g_random_double (void); +gdouble g_random_double_range (gdouble begin, + gdouble end); + + +G_END_DECLS + +#endif /* __G_RAND_H__ */ diff --git a/glib/glib/gregex.c b/glib/glib/gregex.c new file mode 100644 index 0000000..ffffda7 --- /dev/null +++ b/glib/glib/gregex.c @@ -0,0 +1,2971 @@ +/* GRegex -- regular expression API wrapper around PCRE. + * + * Copyright (C) 1999, 2000 Scott Wimer + * Copyright (C) 2004, Matthias Clasen + * Copyright (C) 2005 - 2007, Marco Barisione + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include + +#ifdef USE_SYSTEM_PCRE +#include +#else +#include "pcre/pcre.h" +#endif + +#include "gtypes.h" +#include "gregex.h" +#include "glibintl.h" +#include "glist.h" +#include "gmessages.h" +#include "gstrfuncs.h" +#include "gatomic.h" +#include "gthread.h" + +/** + * SECTION:gregex + * @title: Perl-compatible regular expressions + * @short_description: matches strings against regular expressions + * @see_also: + * + * The g_regex_*() functions implement regular + * expression pattern matching using syntax and semantics similar to + * Perl regular expression. + * + * Some functions accept a @start_position argument, setting it differs + * from just passing over a shortened string and setting #G_REGEX_MATCH_NOTBOL + * in the case of a pattern that begins with any kind of lookbehind assertion. + * For example, consider the pattern "\Biss\B" which finds occurrences of "iss" + * in the middle of words. ("\B" matches only if the current position in the + * subject is not a word boundary.) When applied to the string "Mississipi" + * from the fourth byte, namely "issipi", it does not match, because "\B" is + * always false at the start of the subject, which is deemed to be a word + * boundary. However, if the entire string is passed , but with + * @start_position set to 4, it finds the second occurrence of "iss" because + * it is able to look behind the starting point to discover that it is + * preceded by a letter. + * + * Note that, unless you set the #G_REGEX_RAW flag, all the strings passed + * to these functions must be encoded in UTF-8. The lengths and the positions + * inside the strings are in bytes and not in characters, so, for instance, + * "\xc3\xa0" (i.e. "à") is two bytes long but it is treated as a + * single character. If you set #G_REGEX_RAW the strings can be non-valid + * UTF-8 strings and a byte is treated as a character, so "\xc3\xa0" is two + * bytes and two characters long. + * + * When matching a pattern, "\n" matches only against a "\n" character in + * the string, and "\r" matches only a "\r" character. To match any newline + * sequence use "\R". This particular group matches either the two-character + * sequence CR + LF ("\r\n"), or one of the single characters LF (linefeed, + * U+000A, "\n"), VT vertical tab, U+000B, "\v"), FF (formfeed, U+000C, "\f"), + * CR (carriage return, U+000D, "\r"), NEL (next line, U+0085), LS (line + * separator, U+2028), or PS (paragraph separator, U+2029). + * + * The behaviour of the dot, circumflex, and dollar metacharacters are + * affected by newline characters, the default is to recognize any newline + * character (the same characters recognized by "\R"). This can be changed + * with #G_REGEX_NEWLINE_CR, #G_REGEX_NEWLINE_LF and #G_REGEX_NEWLINE_CRLF + * compile options, and with #G_REGEX_MATCH_NEWLINE_ANY, + * #G_REGEX_MATCH_NEWLINE_CR, #G_REGEX_MATCH_NEWLINE_LF and + * #G_REGEX_MATCH_NEWLINE_CRLF match options. These settings are also + * relevant when compiling a pattern if #G_REGEX_EXTENDED is set, and an + * unescaped "#" outside a character class is encountered. This indicates + * a comment that lasts until after the next newline. + * + * Creating and manipulating the same #GRegex structure from different + * threads is not a problem as #GRegex does not modify its internal + * state between creation and destruction, on the other hand #GMatchInfo + * is not threadsafe. + * + * The regular expressions low-level functionalities are obtained through + * the excellent PCRE library + * written by Philip Hazel. + */ + +/* Mask of all the possible values for GRegexCompileFlags. */ +#define G_REGEX_COMPILE_MASK (G_REGEX_CASELESS | \ + G_REGEX_MULTILINE | \ + G_REGEX_DOTALL | \ + G_REGEX_EXTENDED | \ + G_REGEX_ANCHORED | \ + G_REGEX_DOLLAR_ENDONLY | \ + G_REGEX_UNGREEDY | \ + G_REGEX_RAW | \ + G_REGEX_NO_AUTO_CAPTURE | \ + G_REGEX_OPTIMIZE | \ + G_REGEX_DUPNAMES | \ + G_REGEX_NEWLINE_CR | \ + G_REGEX_NEWLINE_LF | \ + G_REGEX_NEWLINE_CRLF) + +/* Mask of all the possible values for GRegexMatchFlags. */ +#define G_REGEX_MATCH_MASK (G_REGEX_MATCH_ANCHORED | \ + G_REGEX_MATCH_NOTBOL | \ + G_REGEX_MATCH_NOTEOL | \ + G_REGEX_MATCH_NOTEMPTY | \ + G_REGEX_MATCH_PARTIAL | \ + G_REGEX_MATCH_NEWLINE_CR | \ + G_REGEX_MATCH_NEWLINE_LF | \ + G_REGEX_MATCH_NEWLINE_CRLF | \ + G_REGEX_MATCH_NEWLINE_ANY) + +/* if the string is in UTF-8 use g_utf8_ functions, else use + * use just +/- 1. */ +#define NEXT_CHAR(re, s) (((re)->compile_opts & PCRE_UTF8) ? \ + g_utf8_next_char (s) : \ + ((s) + 1)) +#define PREV_CHAR(re, s) (((re)->compile_opts & PCRE_UTF8) ? \ + g_utf8_prev_char (s) : \ + ((s) - 1)) + +struct _GMatchInfo +{ + volatile gint ref_count; /* the ref count */ + GRegex *regex; /* the regex */ + GRegexMatchFlags match_opts; /* options used at match time on the regex */ + gint matches; /* number of matching sub patterns */ + gint pos; /* position in the string where last match left off */ + gint n_offsets; /* number of offsets */ + gint *offsets; /* array of offsets paired 0,1 ; 2,3 ; 3,4 etc */ + gint *workspace; /* workspace for pcre_dfa_exec() */ + gint n_workspace; /* number of workspace elements */ + const gchar *string; /* string passed to the match function */ + gssize string_len; /* length of string */ +}; + +struct _GRegex +{ + volatile gint ref_count; /* the ref count for the immutable part */ + gchar *pattern; /* the pattern */ + pcre *pcre_re; /* compiled form of the pattern */ + GRegexCompileFlags compile_opts; /* options used at compile time on the pattern */ + GRegexMatchFlags match_opts; /* options used at match time on the regex */ + pcre_extra *extra; /* data stored when G_REGEX_OPTIMIZE is used */ +}; + +/* TRUE if ret is an error code, FALSE otherwise. */ +#define IS_PCRE_ERROR(ret) ((ret) < PCRE_ERROR_NOMATCH && (ret) != PCRE_ERROR_PARTIAL) + +typedef struct _InterpolationData InterpolationData; +static gboolean interpolation_list_needs_match (GList *list); +static gboolean interpolate_replacement (const GMatchInfo *match_info, + GString *result, + gpointer data); +static GList *split_replacement (const gchar *replacement, + GError **error); +static void free_interpolation_data (InterpolationData *data); + + +static const gchar * +match_error (gint errcode) +{ + switch (errcode) + { + case PCRE_ERROR_NOMATCH: + /* not an error */ + break; + case PCRE_ERROR_NULL: + /* NULL argument, this should not happen in GRegex */ + g_warning ("A NULL argument was passed to PCRE"); + break; + case PCRE_ERROR_BADOPTION: + return "bad options"; + case PCRE_ERROR_BADMAGIC: + return _("corrupted object"); + case PCRE_ERROR_UNKNOWN_OPCODE: + return N_("internal error or corrupted object"); + case PCRE_ERROR_NOMEMORY: + return _("out of memory"); + case PCRE_ERROR_NOSUBSTRING: + /* not used by pcre_exec() */ + break; + case PCRE_ERROR_MATCHLIMIT: + return _("backtracking limit reached"); + case PCRE_ERROR_CALLOUT: + /* callouts are not implemented */ + break; + case PCRE_ERROR_BADUTF8: + case PCRE_ERROR_BADUTF8_OFFSET: + /* we do not check if strings are valid */ + break; + case PCRE_ERROR_PARTIAL: + /* not an error */ + break; + case PCRE_ERROR_BADPARTIAL: + return _("the pattern contains items not supported for partial matching"); + case PCRE_ERROR_INTERNAL: + return _("internal error"); + case PCRE_ERROR_BADCOUNT: + /* negative ovecsize, this should not happen in GRegex */ + g_warning ("A negative ovecsize was passed to PCRE"); + break; + case PCRE_ERROR_DFA_UITEM: + return _("the pattern contains items not supported for partial matching"); + case PCRE_ERROR_DFA_UCOND: + return _("back references as conditions are not supported for partial matching"); + case PCRE_ERROR_DFA_UMLIMIT: + /* the match_field field is not used in GRegex */ + break; + case PCRE_ERROR_DFA_WSSIZE: + /* handled expanding the workspace */ + break; + case PCRE_ERROR_DFA_RECURSE: + case PCRE_ERROR_RECURSIONLIMIT: + return _("recursion limit reached"); + case PCRE_ERROR_NULLWSLIMIT: + return _("workspace limit for empty substrings reached"); + case PCRE_ERROR_BADNEWLINE: + return _("invalid combination of newline flags"); + case PCRE_ERROR_BADOFFSET: + return _("bad offset"); + case PCRE_ERROR_SHORTUTF8: + return _("short utf8"); + default: + break; + } + return _("unknown error"); +} + +static void +translate_compile_error (gint *errcode, const gchar **errmsg) +{ + /* Compile errors are created adding 100 to the error code returned + * by PCRE. + * If errcode is known we put the translatable error message in + * erromsg. If errcode is unknown we put the generic + * G_REGEX_ERROR_COMPILE error code in errcode and keep the + * untranslated error message returned by PCRE. + * Note that there can be more PCRE errors with the same GRegexError + * and that some PCRE errors are useless for us. + */ + *errcode += 100; + + switch (*errcode) + { + case G_REGEX_ERROR_STRAY_BACKSLASH: + *errmsg = _("\\ at end of pattern"); + break; + case G_REGEX_ERROR_MISSING_CONTROL_CHAR: + *errmsg = _("\\c at end of pattern"); + break; + case G_REGEX_ERROR_UNRECOGNIZED_ESCAPE: + *errmsg = _("unrecognized character follows \\"); + break; + case 137: + /* A number of Perl escapes are not handled by PCRE. + * Therefore it explicitly raises ERR37. + */ + *errcode = G_REGEX_ERROR_UNRECOGNIZED_ESCAPE; + *errmsg = _("case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here"); + break; + case G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER: + *errmsg = _("numbers out of order in {} quantifier"); + break; + case G_REGEX_ERROR_QUANTIFIER_TOO_BIG: + *errmsg = _("number too big in {} quantifier"); + break; + case G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS: + *errmsg = _("missing terminating ] for character class"); + break; + case G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS: + *errmsg = _("invalid escape sequence in character class"); + break; + case G_REGEX_ERROR_RANGE_OUT_OF_ORDER: + *errmsg = _("range out of order in character class"); + break; + case G_REGEX_ERROR_NOTHING_TO_REPEAT: + *errmsg = _("nothing to repeat"); + break; + case G_REGEX_ERROR_UNRECOGNIZED_CHARACTER: + *errmsg = _("unrecognized character after (?"); + break; + case 124: + *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER; + *errmsg = _("unrecognized character after (?<"); + break; + case 141: + *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER; + *errmsg = _("unrecognized character after (?P"); + break; + case G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS: + *errmsg = _("POSIX named classes are supported only within a class"); + break; + case G_REGEX_ERROR_UNMATCHED_PARENTHESIS: + *errmsg = _("missing terminating )"); + break; + case 122: + *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS; + *errmsg = _(") without opening ("); + break; + case 129: + *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS; + /* translators: '(?R' and '(?[+-]digits' are both meant as (groups of) + * sequences here, '(?-54' would be an example for the second group. + */ + *errmsg = _("(?R or (?[+-]digits must be followed by )"); + break; + case G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE: + *errmsg = _("reference to non-existent subpattern"); + break; + case G_REGEX_ERROR_UNTERMINATED_COMMENT: + *errmsg = _("missing ) after comment"); + break; + case G_REGEX_ERROR_EXPRESSION_TOO_LARGE: + *errmsg = _("regular expression too large"); + break; + case G_REGEX_ERROR_MEMORY_ERROR: + *errmsg = _("failed to get memory"); + break; + case G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND: + *errmsg = _("lookbehind assertion is not fixed length"); + break; + case G_REGEX_ERROR_MALFORMED_CONDITION: + *errmsg = _("malformed number or name after (?("); + break; + case G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES: + *errmsg = _("conditional group contains more than two branches"); + break; + case G_REGEX_ERROR_ASSERTION_EXPECTED: + *errmsg = _("assertion expected after (?("); + break; + case G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME: + *errmsg = _("unknown POSIX class name"); + break; + case G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED: + *errmsg = _("POSIX collating elements are not supported"); + break; + case G_REGEX_ERROR_HEX_CODE_TOO_LARGE: + *errmsg = _("character value in \\x{...} sequence is too large"); + break; + case G_REGEX_ERROR_INVALID_CONDITION: + *errmsg = _("invalid condition (?(0)"); + break; + case G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND: + *errmsg = _("\\C not allowed in lookbehind assertion"); + break; + case G_REGEX_ERROR_INFINITE_LOOP: + *errmsg = _("recursive call could loop indefinitely"); + break; + case G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR: + *errmsg = _("missing terminator in subpattern name"); + break; + case G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME: + *errmsg = _("two named subpatterns have the same name"); + break; + case G_REGEX_ERROR_MALFORMED_PROPERTY: + *errmsg = _("malformed \\P or \\p sequence"); + break; + case G_REGEX_ERROR_UNKNOWN_PROPERTY: + *errmsg = _("unknown property name after \\P or \\p"); + break; + case G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG: + *errmsg = _("subpattern name is too long (maximum 32 characters)"); + break; + case G_REGEX_ERROR_TOO_MANY_SUBPATTERNS: + *errmsg = _("too many named subpatterns (maximum 10,000)"); + break; + case G_REGEX_ERROR_INVALID_OCTAL_VALUE: + *errmsg = _("octal value is greater than \\377"); + break; + case G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE: + *errmsg = _("DEFINE group contains more than one branch"); + break; + case G_REGEX_ERROR_DEFINE_REPETION: + *errmsg = _("repeating a DEFINE group is not allowed"); + break; + case G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS: + *errmsg = _("inconsistent NEWLINE options"); + break; + case G_REGEX_ERROR_MISSING_BACK_REFERENCE: + *errmsg = _("\\g is not followed by a braced name or an optionally " + "braced non-zero number"); + break; + case 11: + *errcode = G_REGEX_ERROR_INTERNAL; + *errmsg = _("unexpected repeat"); + break; + case 23: + *errcode = G_REGEX_ERROR_INTERNAL; + *errmsg = _("code overflow"); + break; + case 52: + *errcode = G_REGEX_ERROR_INTERNAL; + *errmsg = _("overran compiling workspace"); + break; + case 53: + *errcode = G_REGEX_ERROR_INTERNAL; + *errmsg = _("previously-checked referenced subpattern not found"); + break; + case 16: + /* This should not happen as we never pass a NULL erroffset */ + g_warning ("erroffset passed as NULL"); + *errcode = G_REGEX_ERROR_COMPILE; + break; + case 17: + /* This should not happen as we check options before passing them + * to pcre_compile2() */ + g_warning ("unknown option bit(s) set"); + *errcode = G_REGEX_ERROR_COMPILE; + break; + case 32: + case 44: + case 45: + /* These errors should not happen as we are using an UTF8-enabled PCRE + * and we do not check if strings are valid */ + g_warning ("%s", *errmsg); + *errcode = G_REGEX_ERROR_COMPILE; + break; + default: + *errcode = G_REGEX_ERROR_COMPILE; + } +} + +/* GMatchInfo */ + +static GMatchInfo * +match_info_new (const GRegex *regex, + const gchar *string, + gint string_len, + gint start_position, + gint match_options, + gboolean is_dfa) +{ + GMatchInfo *match_info; + + if (string_len < 0) + string_len = strlen (string); + + match_info = g_new0 (GMatchInfo, 1); + match_info->ref_count = 1; + match_info->regex = g_regex_ref ((GRegex *)regex); + match_info->string = string; + match_info->string_len = string_len; + match_info->matches = PCRE_ERROR_NOMATCH; + match_info->pos = start_position; + match_info->match_opts = match_options; + + if (is_dfa) + { + /* These values should be enough for most cases, if they are not + * enough g_regex_match_all_full() will expand them. */ + match_info->n_offsets = 24; + match_info->n_workspace = 100; + match_info->workspace = g_new (gint, match_info->n_workspace); + } + else + { + gint capture_count; + pcre_fullinfo (regex->pcre_re, regex->extra, + PCRE_INFO_CAPTURECOUNT, &capture_count); + match_info->n_offsets = (capture_count + 1) * 3; + } + + match_info->offsets = g_new0 (gint, match_info->n_offsets); + /* Set an invalid position for the previous match. */ + match_info->offsets[0] = -1; + match_info->offsets[1] = -1; + + return match_info; +} + +/** + * g_match_info_get_regex: + * @match_info: a #GMatchInfo + * + * Returns #GRegex object used in @match_info. It belongs to Glib + * and must not be freed. Use g_regex_ref() if you need to keep it + * after you free @match_info object. + * + * Returns: #GRegex object used in @match_info + * + * Since: 2.14 + */ +GRegex * +g_match_info_get_regex (const GMatchInfo *match_info) +{ + g_return_val_if_fail (match_info != NULL, NULL); + return match_info->regex; +} + +/** + * g_match_info_get_string: + * @match_info: a #GMatchInfo + * + * Returns the string searched with @match_info. This is the + * string passed to g_regex_match() or g_regex_replace() so + * you may not free it before calling this function. + * + * Returns: the string searched with @match_info + * + * Since: 2.14 + */ +const gchar * +g_match_info_get_string (const GMatchInfo *match_info) +{ + g_return_val_if_fail (match_info != NULL, NULL); + return match_info->string; +} + +/** + * g_match_info_ref: + * @match_info: a #GMatchInfo + * + * Increases reference count of @match_info by 1. + * + * Returns: @match_info + * + * Since: 2.30 + */ +GMatchInfo * +g_match_info_ref (GMatchInfo *match_info) +{ + g_return_val_if_fail (match_info != NULL, NULL); + g_atomic_int_inc (&match_info->ref_count); + return match_info; +} + +/** + * g_match_info_unref: + * @match_info: a #GMatchInfo + * + * Decreases reference count of @match_info by 1. When reference count drops + * to zero, it frees all the memory associated with the match_info structure. + * + * Since: 2.30 + */ +void +g_match_info_unref (GMatchInfo *match_info) +{ + if (g_atomic_int_dec_and_test (&match_info->ref_count)) + { + g_regex_unref (match_info->regex); + g_free (match_info->offsets); + g_free (match_info->workspace); + g_free (match_info); + } +} + +/** + * g_match_info_free: + * @match_info: (allow-none): a #GMatchInfo, or %NULL + * + * If @match_info is not %NULL, calls g_match_info_unref(); otherwise does + * nothing. + * + * Since: 2.14 + */ +void +g_match_info_free (GMatchInfo *match_info) +{ + if (match_info == NULL) + return; + + g_match_info_unref (match_info); +} + +/** + * g_match_info_next: + * @match_info: a #GMatchInfo structure + * @error: location to store the error occurring, or %NULL to ignore errors + * + * Scans for the next match using the same parameters of the previous + * call to g_regex_match_full() or g_regex_match() that returned + * @match_info. + * + * The match is done on the string passed to the match function, so you + * cannot free it before calling this function. + * + * Returns: %TRUE is the string matched, %FALSE otherwise + * + * Since: 2.14 + */ +gboolean +g_match_info_next (GMatchInfo *match_info, + GError **error) +{ + gint prev_match_start; + gint prev_match_end; + + g_return_val_if_fail (match_info != NULL, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail (match_info->pos >= 0, FALSE); + + prev_match_start = match_info->offsets[0]; + prev_match_end = match_info->offsets[1]; + + if (match_info->pos > match_info->string_len) + { + /* we have reached the end of the string */ + match_info->pos = -1; + match_info->matches = PCRE_ERROR_NOMATCH; + return FALSE; + } + + match_info->matches = pcre_exec (match_info->regex->pcre_re, + match_info->regex->extra, + match_info->string, + match_info->string_len, + match_info->pos, + match_info->regex->match_opts | match_info->match_opts, + match_info->offsets, + match_info->n_offsets); + if (IS_PCRE_ERROR (match_info->matches)) + { + g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, + _("Error while matching regular expression %s: %s"), + match_info->regex->pattern, match_error (match_info->matches)); + return FALSE; + } + + /* avoid infinite loops if the pattern is an empty string or something + * equivalent */ + if (match_info->pos == match_info->offsets[1]) + { + if (match_info->pos > match_info->string_len) + { + /* we have reached the end of the string */ + match_info->pos = -1; + match_info->matches = PCRE_ERROR_NOMATCH; + return FALSE; + } + + match_info->pos = NEXT_CHAR (match_info->regex, + &match_info->string[match_info->pos]) - + match_info->string; + } + else + { + match_info->pos = match_info->offsets[1]; + } + + /* it's possible to get two identical matches when we are matching + * empty strings, for instance if the pattern is "(?=[A-Z0-9])" and + * the string is "RegExTest" we have: + * - search at position 0: match from 0 to 0 + * - search at position 1: match from 3 to 3 + * - search at position 3: match from 3 to 3 (duplicate) + * - search at position 4: match from 5 to 5 + * - search at position 5: match from 5 to 5 (duplicate) + * - search at position 6: no match -> stop + * so we have to ignore the duplicates. + * see bug #515944: http://bugzilla.gnome.org/show_bug.cgi?id=515944 */ + if (match_info->matches >= 0 && + prev_match_start == match_info->offsets[0] && + prev_match_end == match_info->offsets[1]) + { + /* ignore this match and search the next one */ + return g_match_info_next (match_info, error); + } + + return match_info->matches >= 0; +} + +/** + * g_match_info_matches: + * @match_info: a #GMatchInfo structure + * + * Returns whether the previous match operation succeeded. + * + * Returns: %TRUE if the previous match operation succeeded, + * %FALSE otherwise + * + * Since: 2.14 + */ +gboolean +g_match_info_matches (const GMatchInfo *match_info) +{ + g_return_val_if_fail (match_info != NULL, FALSE); + + return match_info->matches >= 0; +} + +/** + * g_match_info_get_match_count: + * @match_info: a #GMatchInfo structure + * + * Retrieves the number of matched substrings (including substring 0, + * that is the whole matched text), so 1 is returned if the pattern + * has no substrings in it and 0 is returned if the match failed. + * + * If the last match was obtained using the DFA algorithm, that is + * using g_regex_match_all() or g_regex_match_all_full(), the retrieved + * count is not that of the number of capturing parentheses but that of + * the number of matched substrings. + * + * Returns: Number of matched substrings, or -1 if an error occurred + * + * Since: 2.14 + */ +gint +g_match_info_get_match_count (const GMatchInfo *match_info) +{ + g_return_val_if_fail (match_info, -1); + + if (match_info->matches == PCRE_ERROR_NOMATCH) + /* no match */ + return 0; + else if (match_info->matches < PCRE_ERROR_NOMATCH) + /* error */ + return -1; + else + /* match */ + return match_info->matches; +} + +/** + * g_match_info_is_partial_match: + * @match_info: a #GMatchInfo structure + * + * Usually if the string passed to g_regex_match*() matches as far as + * it goes, but is too short to match the entire pattern, %FALSE is + * returned. There are circumstances where it might be helpful to + * distinguish this case from other cases in which there is no match. + * + * Consider, for example, an application where a human is required to + * type in data for a field with specific formatting requirements. An + * example might be a date in the form ddmmmyy, defined by the pattern + * "^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$". + * If the application sees the user’s keystrokes one by one, and can + * check that what has been typed so far is potentially valid, it is + * able to raise an error as soon as a mistake is made. + * + * GRegex supports the concept of partial matching by means of the + * #G_REGEX_MATCH_PARTIAL flag. When this is set the return code for + * g_regex_match() or g_regex_match_full() is, as usual, %TRUE + * for a complete match, %FALSE otherwise. But, when these functions + * return %FALSE, you can check if the match was partial calling + * g_match_info_is_partial_match(). + * + * When using partial matching you cannot use g_match_info_fetch*(). + * + * Because of the way certain internal optimizations are implemented + * the partial matching algorithm cannot be used with all patterns. + * So repeated single characters such as "a{2,4}" and repeated single + * meta-sequences such as "\d+" are not permitted if the maximum number + * of occurrences is greater than one. Optional items such as "\d?" + * (where the maximum is one) are permitted. Quantifiers with any values + * are permitted after parentheses, so the invalid examples above can be + * coded thus "(a){2,4}" and "(\d)+". If #G_REGEX_MATCH_PARTIAL is set + * for a pattern that does not conform to the restrictions, matching + * functions return an error. + * + * Returns: %TRUE if the match was partial, %FALSE otherwise + * + * Since: 2.14 + */ +gboolean +g_match_info_is_partial_match (const GMatchInfo *match_info) +{ + g_return_val_if_fail (match_info != NULL, FALSE); + + return match_info->matches == PCRE_ERROR_PARTIAL; +} + +/** + * g_match_info_expand_references: + * @match_info: a #GMatchInfo or %NULL + * @string_to_expand: the string to expand + * @error: location to store the error occurring, or %NULL to ignore errors + * + * Returns a new string containing the text in @string_to_expand with + * references and escape sequences expanded. References refer to the last + * match done with @string against @regex and have the same syntax used by + * g_regex_replace(). + * + * The @string_to_expand must be UTF-8 encoded even if #G_REGEX_RAW was + * passed to g_regex_new(). + * + * The backreferences are extracted from the string passed to the match + * function, so you cannot call this function after freeing the string. + * + * @match_info may be %NULL in which case @string_to_expand must not + * contain references. For instance "foo\n" does not refer to an actual + * pattern and '\n' merely will be replaced with \n character, + * while to expand "\0" (whole match) one needs the result of a match. + * Use g_regex_check_replacement() to find out whether @string_to_expand + * contains references. + * + * Returns: (allow-none): the expanded string, or %NULL if an error occurred + * + * Since: 2.14 + */ +gchar * +g_match_info_expand_references (const GMatchInfo *match_info, + const gchar *string_to_expand, + GError **error) +{ + GString *result; + GList *list; + GError *tmp_error = NULL; + + g_return_val_if_fail (string_to_expand != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + + list = split_replacement (string_to_expand, &tmp_error); + if (tmp_error != NULL) + { + g_propagate_error (error, tmp_error); + return NULL; + } + + if (!match_info && interpolation_list_needs_match (list)) + { + g_critical ("String '%s' contains references to the match, can't " + "expand references without GMatchInfo object", + string_to_expand); + return NULL; + } + + result = g_string_sized_new (strlen (string_to_expand)); + interpolate_replacement (match_info, result, list); + + g_list_free_full (list, (GDestroyNotify) free_interpolation_data); + + return g_string_free (result, FALSE); +} + +/** + * g_match_info_fetch: + * @match_info: #GMatchInfo structure + * @match_num: number of the sub expression + * + * Retrieves the text matching the @match_num'th capturing + * parentheses. 0 is the full text of the match, 1 is the first paren + * set, 2 the second, and so on. + * + * If @match_num is a valid sub pattern but it didn't match anything + * (e.g. sub pattern 1, matching "b" against "(a)?b") then an empty + * string is returned. + * + * If the match was obtained using the DFA algorithm, that is using + * g_regex_match_all() or g_regex_match_all_full(), the retrieved + * string is not that of a set of parentheses but that of a matched + * substring. Substrings are matched in reverse order of length, so + * 0 is the longest match. + * + * The string is fetched from the string passed to the match function, + * so you cannot call this function after freeing the string. + * + * Returns: (allow-none): The matched substring, or %NULL if an error + * occurred. You have to free the string yourself + * + * Since: 2.14 + */ +gchar * +g_match_info_fetch (const GMatchInfo *match_info, + gint match_num) +{ + /* we cannot use pcre_get_substring() because it allocates the + * string using pcre_malloc(). */ + gchar *match = NULL; + gint start, end; + + g_return_val_if_fail (match_info != NULL, NULL); + g_return_val_if_fail (match_num >= 0, NULL); + + /* match_num does not exist or it didn't matched, i.e. matching "b" + * against "(a)?b" then group 0 is empty. */ + if (!g_match_info_fetch_pos (match_info, match_num, &start, &end)) + match = NULL; + else if (start == -1) + match = g_strdup (""); + else + match = g_strndup (&match_info->string[start], end - start); + + return match; +} + +/** + * g_match_info_fetch_pos: + * @match_info: #GMatchInfo structure + * @match_num: number of the sub expression + * @start_pos: (out) (allow-none): pointer to location where to store + * the start position, or %NULL + * @end_pos: (out) (allow-none): pointer to location where to store + * the end position, or %NULL + * + * Retrieves the position in bytes of the @match_num'th capturing + * parentheses. 0 is the full text of the match, 1 is the first + * paren set, 2 the second, and so on. + * + * If @match_num is a valid sub pattern but it didn't match anything + * (e.g. sub pattern 1, matching "b" against "(a)?b") then @start_pos + * and @end_pos are set to -1 and %TRUE is returned. + * + * If the match was obtained using the DFA algorithm, that is using + * g_regex_match_all() or g_regex_match_all_full(), the retrieved + * position is not that of a set of parentheses but that of a matched + * substring. Substrings are matched in reverse order of length, so + * 0 is the longest match. + * + * Returns: %TRUE if the position was fetched, %FALSE otherwise. If + * the position cannot be fetched, @start_pos and @end_pos are left + * unchanged + * + * Since: 2.14 + */ +gboolean +g_match_info_fetch_pos (const GMatchInfo *match_info, + gint match_num, + gint *start_pos, + gint *end_pos) +{ + g_return_val_if_fail (match_info != NULL, FALSE); + g_return_val_if_fail (match_num >= 0, FALSE); + + /* make sure the sub expression number they're requesting is less than + * the total number of sub expressions that were matched. */ + if (match_num >= match_info->matches) + return FALSE; + + if (start_pos != NULL) + *start_pos = match_info->offsets[2 * match_num]; + + if (end_pos != NULL) + *end_pos = match_info->offsets[2 * match_num + 1]; + + return TRUE; +} + +/* + * Returns number of first matched subpattern with name @name. + * There may be more than one in case when DUPNAMES is used, + * and not all subpatterns with that name match; + * pcre_get_stringnumber() does not work in that case. + */ +static gint +get_matched_substring_number (const GMatchInfo *match_info, + const gchar *name) +{ + gint entrysize; + gchar *first, *last; + guchar *entry; + + if (!(match_info->regex->compile_opts & G_REGEX_DUPNAMES)) + return pcre_get_stringnumber (match_info->regex->pcre_re, name); + + /* This code is copied from pcre_get.c: get_first_set() */ + entrysize = pcre_get_stringtable_entries (match_info->regex->pcre_re, + name, + &first, + &last); + + if (entrysize <= 0) + return entrysize; + + for (entry = (guchar*) first; entry <= (guchar*) last; entry += entrysize) + { + gint n = (entry[0] << 8) + entry[1]; + if (match_info->offsets[n*2] >= 0) + return n; + } + + return (first[0] << 8) + first[1]; +} + +/** + * g_match_info_fetch_named: + * @match_info: #GMatchInfo structure + * @name: name of the subexpression + * + * Retrieves the text matching the capturing parentheses named @name. + * + * If @name is a valid sub pattern name but it didn't match anything + * (e.g. sub pattern "X", matching "b" against "(?P<X>a)?b") + * then an empty string is returned. + * + * The string is fetched from the string passed to the match function, + * so you cannot call this function after freeing the string. + * + * Returns: (allow-none): The matched substring, or %NULL if an error + * occurred. You have to free the string yourself + * + * Since: 2.14 + */ +gchar * +g_match_info_fetch_named (const GMatchInfo *match_info, + const gchar *name) +{ + /* we cannot use pcre_get_named_substring() because it allocates the + * string using pcre_malloc(). */ + gint num; + + g_return_val_if_fail (match_info != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + num = get_matched_substring_number (match_info, name); + if (num < 0) + return NULL; + else + return g_match_info_fetch (match_info, num); +} + +/** + * g_match_info_fetch_named_pos: + * @match_info: #GMatchInfo structure + * @name: name of the subexpression + * @start_pos: (out) (allow-none): pointer to location where to store + * the start position, or %NULL + * @end_pos: (out) (allow-none): pointer to location where to store + * the end position, or %NULL + * + * Retrieves the position in bytes of the capturing parentheses named @name. + * + * If @name is a valid sub pattern name but it didn't match anything + * (e.g. sub pattern "X", matching "b" against "(?P<X>a)?b") + * then @start_pos and @end_pos are set to -1 and %TRUE is returned. + * + * Returns: %TRUE if the position was fetched, %FALSE otherwise. + * If the position cannot be fetched, @start_pos and @end_pos + * are left unchanged. + * + * Since: 2.14 + */ +gboolean +g_match_info_fetch_named_pos (const GMatchInfo *match_info, + const gchar *name, + gint *start_pos, + gint *end_pos) +{ + gint num; + + g_return_val_if_fail (match_info != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + num = get_matched_substring_number (match_info, name); + if (num < 0) + return FALSE; + + return g_match_info_fetch_pos (match_info, num, start_pos, end_pos); +} + +/** + * g_match_info_fetch_all: + * @match_info: a #GMatchInfo structure + * + * Bundles up pointers to each of the matching substrings from a match + * and stores them in an array of gchar pointers. The first element in + * the returned array is the match number 0, i.e. the entire matched + * text. + * + * If a sub pattern didn't match anything (e.g. sub pattern 1, matching + * "b" against "(a)?b") then an empty string is inserted. + * + * If the last match was obtained using the DFA algorithm, that is using + * g_regex_match_all() or g_regex_match_all_full(), the retrieved + * strings are not that matched by sets of parentheses but that of the + * matched substring. Substrings are matched in reverse order of length, + * so the first one is the longest match. + * + * The strings are fetched from the string passed to the match function, + * so you cannot call this function after freeing the string. + * + * Returns: (allow-none): a %NULL-terminated array of gchar * pointers. + * It must be freed using g_strfreev(). If the previous match failed + * %NULL is returned + * + * Since: 2.14 + */ +gchar ** +g_match_info_fetch_all (const GMatchInfo *match_info) +{ + /* we cannot use pcre_get_substring_list() because the returned value + * isn't suitable for g_strfreev(). */ + gchar **result; + gint i; + + g_return_val_if_fail (match_info != NULL, NULL); + + if (match_info->matches < 0) + return NULL; + + result = g_new (gchar *, match_info->matches + 1); + for (i = 0; i < match_info->matches; i++) + result[i] = g_match_info_fetch (match_info, i); + result[i] = NULL; + + return result; +} + + +/* GRegex */ + +GQuark +g_regex_error_quark (void) +{ + static GQuark error_quark = 0; + + if (error_quark == 0) + error_quark = g_quark_from_static_string ("g-regex-error-quark"); + + return error_quark; +} + +/** + * g_regex_ref: + * @regex: a #GRegex + * + * Increases reference count of @regex by 1. + * + * Returns: @regex + * + * Since: 2.14 + */ +GRegex * +g_regex_ref (GRegex *regex) +{ + g_return_val_if_fail (regex != NULL, NULL); + g_atomic_int_inc (®ex->ref_count); + return regex; +} + +/** + * g_regex_unref: + * @regex: a #GRegex + * + * Decreases reference count of @regex by 1. When reference count drops + * to zero, it frees all the memory associated with the regex structure. + * + * Since: 2.14 + */ +void +g_regex_unref (GRegex *regex) +{ + g_return_if_fail (regex != NULL); + + if (g_atomic_int_dec_and_test (®ex->ref_count)) + { + g_free (regex->pattern); + if (regex->pcre_re != NULL) + pcre_free (regex->pcre_re); + if (regex->extra != NULL) + pcre_free (regex->extra); + g_free (regex); + } +} + +/** + * g_regex_new: + * @pattern: the regular expression + * @compile_options: compile options for the regular expression, or 0 + * @match_options: match options for the regular expression, or 0 + * @error: return location for a #GError + * + * Compiles the regular expression to an internal form, and does + * the initial setup of the #GRegex structure. + * + * Returns: a #GRegex structure. Call g_regex_unref() when you + * are done with it + * + * Since: 2.14 + */ +GRegex * +g_regex_new (const gchar *pattern, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options, + GError **error) +{ + GRegex *regex; + pcre *re; + const gchar *errmsg; + gint erroffset; + gint errcode; + gboolean optimize = FALSE; + static gsize initialised; + unsigned long int pcre_compile_options; + + g_return_val_if_fail (pattern != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail ((compile_options & ~G_REGEX_COMPILE_MASK) == 0, NULL); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL); + + if (g_once_init_enter (&initialised)) + { + gint support; + const gchar *msg; + + pcre_config (PCRE_CONFIG_UTF8, &support); + if (!support) + { + msg = N_("PCRE library is compiled without UTF8 support"); + g_critical ("%s", msg); + g_set_error_literal (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE, gettext (msg)); + return NULL; + } + + pcre_config (PCRE_CONFIG_UNICODE_PROPERTIES, &support); + if (!support) + { + msg = N_("PCRE library is compiled without UTF8 properties support"); + g_critical ("%s", msg); + g_set_error_literal (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE, gettext (msg)); + return NULL; + } + + g_once_init_leave (&initialised, TRUE); + } + + /* G_REGEX_OPTIMIZE has the same numeric value of PCRE_NO_UTF8_CHECK, + * as we do not need to wrap PCRE_NO_UTF8_CHECK. */ + if (compile_options & G_REGEX_OPTIMIZE) + optimize = TRUE; + + /* In GRegex the string are, by default, UTF-8 encoded. PCRE + * instead uses UTF-8 only if required with PCRE_UTF8. */ + if (compile_options & G_REGEX_RAW) + { + /* disable utf-8 */ + compile_options &= ~G_REGEX_RAW; + } + else + { + /* enable utf-8 */ + compile_options |= PCRE_UTF8 | PCRE_NO_UTF8_CHECK; + match_options |= PCRE_NO_UTF8_CHECK; + } + + /* PCRE_NEWLINE_ANY is the default for the internal PCRE but + * not for the system one. */ + if (!(compile_options & G_REGEX_NEWLINE_CR) && + !(compile_options & G_REGEX_NEWLINE_LF)) + { + compile_options |= PCRE_NEWLINE_ANY; + } + + compile_options |= PCRE_UCP; + + /* compile the pattern */ + re = pcre_compile2 (pattern, compile_options, &errcode, + &errmsg, &erroffset, NULL); + + /* if the compilation failed, set the error member and return + * immediately */ + if (re == NULL) + { + GError *tmp_error; + + /* Translate the PCRE error code to GRegexError and use a translated + * error message if possible */ + translate_compile_error (&errcode, &errmsg); + + /* PCRE uses byte offsets but we want to show character offsets */ + erroffset = g_utf8_pointer_to_offset (pattern, &pattern[erroffset]); + + tmp_error = g_error_new (G_REGEX_ERROR, errcode, + _("Error while compiling regular " + "expression %s at char %d: %s"), + pattern, erroffset, errmsg); + g_propagate_error (error, tmp_error); + + return NULL; + } + + /* For options set at the beginning of the pattern, pcre puts them into + * compile options, e.g. "(?i)foo" will make the pcre structure store + * PCRE_CASELESS even though it wasn't explicitly given for compilation. */ + pcre_fullinfo (re, NULL, PCRE_INFO_OPTIONS, &pcre_compile_options); + compile_options = pcre_compile_options; + + if (!(compile_options & G_REGEX_DUPNAMES)) + { + gboolean jchanged = FALSE; + pcre_fullinfo (re, NULL, PCRE_INFO_JCHANGED, &jchanged); + if (jchanged) + compile_options |= G_REGEX_DUPNAMES; + } + + regex = g_new0 (GRegex, 1); + regex->ref_count = 1; + regex->pattern = g_strdup (pattern); + regex->pcre_re = re; + regex->compile_opts = compile_options; + regex->match_opts = match_options; + + if (optimize) + { + regex->extra = pcre_study (regex->pcre_re, 0, &errmsg); + if (errmsg != NULL) + { + GError *tmp_error = g_error_new (G_REGEX_ERROR, + G_REGEX_ERROR_OPTIMIZE, + _("Error while optimizing " + "regular expression %s: %s"), + regex->pattern, + errmsg); + g_propagate_error (error, tmp_error); + + g_regex_unref (regex); + return NULL; + } + } + + return regex; +} + +/** + * g_regex_get_pattern: + * @regex: a #GRegex structure + * + * Gets the pattern string associated with @regex, i.e. a copy of + * the string passed to g_regex_new(). + * + * Returns: the pattern of @regex + * + * Since: 2.14 + */ +const gchar * +g_regex_get_pattern (const GRegex *regex) +{ + g_return_val_if_fail (regex != NULL, NULL); + + return regex->pattern; +} + +/** + * g_regex_get_max_backref: + * @regex: a #GRegex + * + * Returns the number of the highest back reference + * in the pattern, or 0 if the pattern does not contain + * back references. + * + * Returns: the number of the highest back reference + * + * Since: 2.14 + */ +gint +g_regex_get_max_backref (const GRegex *regex) +{ + gint value; + + pcre_fullinfo (regex->pcre_re, regex->extra, + PCRE_INFO_BACKREFMAX, &value); + + return value; +} + +/** + * g_regex_get_capture_count: + * @regex: a #GRegex + * + * Returns the number of capturing subpatterns in the pattern. + * + * Returns: the number of capturing subpatterns + * + * Since: 2.14 + */ +gint +g_regex_get_capture_count (const GRegex *regex) +{ + gint value; + + pcre_fullinfo (regex->pcre_re, regex->extra, + PCRE_INFO_CAPTURECOUNT, &value); + + return value; +} + +/** + * g_regex_get_compile_flags: + * @regex: a #GRegex + * + * Returns the compile options that @regex was created with. + * + * Returns: flags from #GRegexCompileFlags + * + * Since: 2.26 + */ +GRegexCompileFlags +g_regex_get_compile_flags (const GRegex *regex) +{ + g_return_val_if_fail (regex != NULL, 0); + + return regex->compile_opts; +} + +/** + * g_regex_get_match_flags: + * @regex: a #GRegex + * + * Returns the match options that @regex was created with. + * + * Returns: flags from #GRegexMatchFlags + * + * Since: 2.26 + */ +GRegexMatchFlags +g_regex_get_match_flags (const GRegex *regex) +{ + g_return_val_if_fail (regex != NULL, 0); + + return regex->match_opts; +} + +/** + * g_regex_match_simple: + * @pattern: the regular expression + * @string: the string to scan for matches + * @compile_options: compile options for the regular expression, or 0 + * @match_options: match options, or 0 + * + * Scans for a match in @string for @pattern. + * + * This function is equivalent to g_regex_match() but it does not + * require to compile the pattern with g_regex_new(), avoiding some + * lines of code when you need just to do a match without extracting + * substrings, capture counts, and so on. + * + * If this function is to be called on the same @pattern more than + * once, it's more efficient to compile the pattern once with + * g_regex_new() and then use g_regex_match(). + * + * Returns: %TRUE if the string matched, %FALSE otherwise + * + * Since: 2.14 + */ +gboolean +g_regex_match_simple (const gchar *pattern, + const gchar *string, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options) +{ + GRegex *regex; + gboolean result; + + regex = g_regex_new (pattern, compile_options, 0, NULL); + if (!regex) + return FALSE; + result = g_regex_match_full (regex, string, -1, 0, match_options, NULL, NULL); + g_regex_unref (regex); + return result; +} + +/** + * g_regex_match: + * @regex: a #GRegex structure from g_regex_new() + * @string: the string to scan for matches + * @match_options: match options + * @match_info: (out) (allow-none): pointer to location where to store + * the #GMatchInfo, or %NULL if you do not need it + * + * Scans for a match in string for the pattern in @regex. + * The @match_options are combined with the match options specified + * when the @regex structure was created, letting you have more + * flexibility in reusing #GRegex structures. + * + * A #GMatchInfo structure, used to get information on the match, + * is stored in @match_info if not %NULL. Note that if @match_info + * is not %NULL then it is created even if the function returns %FALSE, + * i.e. you must free it regardless if regular expression actually matched. + * + * To retrieve all the non-overlapping matches of the pattern in + * string you can use g_match_info_next(). + * + * |[ + * static void + * print_uppercase_words (const gchar *string) + * { + * /* Print all uppercase-only words. */ + * GRegex *regex; + * GMatchInfo *match_info; + *   + * regex = g_regex_new ("[A-Z]+", 0, 0, NULL); + * g_regex_match (regex, string, 0, &match_info); + * while (g_match_info_matches (match_info)) + * { + * gchar *word = g_match_info_fetch (match_info, 0); + * g_print ("Found: %s\n", word); + * g_free (word); + * g_match_info_next (match_info, NULL); + * } + * g_match_info_free (match_info); + * g_regex_unref (regex); + * } + * ]| + * + * @string is not copied and is used in #GMatchInfo internally. If + * you use any #GMatchInfo method (except g_match_info_free()) after + * freeing or modifying @string then the behaviour is undefined. + * + * Returns: %TRUE is the string matched, %FALSE otherwise + * + * Since: 2.14 + */ +gboolean +g_regex_match (const GRegex *regex, + const gchar *string, + GRegexMatchFlags match_options, + GMatchInfo **match_info) +{ + return g_regex_match_full (regex, string, -1, 0, match_options, + match_info, NULL); +} + +/** + * g_regex_match_full: + * @regex: a #GRegex structure from g_regex_new() + * @string: (array length=string_len): the string to scan for matches + * @string_len: the length of @string, or -1 if @string is nul-terminated + * @start_position: starting index of the string to match + * @match_options: match options + * @match_info: (out) (allow-none): pointer to location where to store + * the #GMatchInfo, or %NULL if you do not need it + * @error: location to store the error occurring, or %NULL to ignore errors + * + * Scans for a match in string for the pattern in @regex. + * The @match_options are combined with the match options specified + * when the @regex structure was created, letting you have more + * flexibility in reusing #GRegex structures. + * + * Setting @start_position differs from just passing over a shortened + * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern + * that begins with any kind of lookbehind assertion, such as "\b". + * + * A #GMatchInfo structure, used to get information on the match, is + * stored in @match_info if not %NULL. Note that if @match_info is + * not %NULL then it is created even if the function returns %FALSE, + * i.e. you must free it regardless if regular expression actually + * matched. + * + * @string is not copied and is used in #GMatchInfo internally. If + * you use any #GMatchInfo method (except g_match_info_free()) after + * freeing or modifying @string then the behaviour is undefined. + * + * To retrieve all the non-overlapping matches of the pattern in + * string you can use g_match_info_next(). + * + * |[ + * static void + * print_uppercase_words (const gchar *string) + * { + * /* Print all uppercase-only words. */ + * GRegex *regex; + * GMatchInfo *match_info; + * GError *error = NULL; + *   + * regex = g_regex_new ("[A-Z]+", 0, 0, NULL); + * g_regex_match_full (regex, string, -1, 0, 0, &match_info, &error); + * while (g_match_info_matches (match_info)) + * { + * gchar *word = g_match_info_fetch (match_info, 0); + * g_print ("Found: %s\n", word); + * g_free (word); + * g_match_info_next (match_info, &error); + * } + * g_match_info_free (match_info); + * g_regex_unref (regex); + * if (error != NULL) + * { + * g_printerr ("Error while matching: %s\n", error->message); + * g_error_free (error); + * } + * } + * ]| + * + * Returns: %TRUE is the string matched, %FALSE otherwise + * + * Since: 2.14 + */ +gboolean +g_regex_match_full (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + GRegexMatchFlags match_options, + GMatchInfo **match_info, + GError **error) +{ + GMatchInfo *info; + gboolean match_ok; + + g_return_val_if_fail (regex != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + g_return_val_if_fail (start_position >= 0, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE); + + info = match_info_new (regex, string, string_len, start_position, + match_options, FALSE); + match_ok = g_match_info_next (info, error); + if (match_info != NULL) + *match_info = info; + else + g_match_info_free (info); + + return match_ok; +} + +/** + * g_regex_match_all: + * @regex: a #GRegex structure from g_regex_new() + * @string: the string to scan for matches + * @match_options: match options + * @match_info: (out) (allow-none): pointer to location where to store + * the #GMatchInfo, or %NULL if you do not need it + * + * Using the standard algorithm for regular expression matching only + * the longest match in the string is retrieved. This function uses + * a different algorithm so it can retrieve all the possible matches. + * For more documentation see g_regex_match_all_full(). + * + * A #GMatchInfo structure, used to get information on the match, is + * stored in @match_info if not %NULL. Note that if @match_info is + * not %NULL then it is created even if the function returns %FALSE, + * i.e. you must free it regardless if regular expression actually + * matched. + * + * @string is not copied and is used in #GMatchInfo internally. If + * you use any #GMatchInfo method (except g_match_info_free()) after + * freeing or modifying @string then the behaviour is undefined. + * + * Returns: %TRUE is the string matched, %FALSE otherwise + * + * Since: 2.14 + */ +gboolean +g_regex_match_all (const GRegex *regex, + const gchar *string, + GRegexMatchFlags match_options, + GMatchInfo **match_info) +{ + return g_regex_match_all_full (regex, string, -1, 0, match_options, + match_info, NULL); +} + +/** + * g_regex_match_all_full: + * @regex: a #GRegex structure from g_regex_new() + * @string: (array length=string_len): the string to scan for matches + * @string_len: the length of @string, or -1 if @string is nul-terminated + * @start_position: starting index of the string to match + * @match_options: match options + * @match_info: (out) (allow-none): pointer to location where to store + * the #GMatchInfo, or %NULL if you do not need it + * @error: location to store the error occurring, or %NULL to ignore errors + * + * Using the standard algorithm for regular expression matching only + * the longest match in the string is retrieved, it is not possible + * to obtain all the available matches. For instance matching + * "<a> <b> <c>" against the pattern "<.*>" + * you get "<a> <b> <c>". + * + * This function uses a different algorithm (called DFA, i.e. deterministic + * finite automaton), so it can retrieve all the possible matches, all + * starting at the same point in the string. For instance matching + * "<a> <b> <c>" against the pattern "<.*>" + * you would obtain three matches: "<a> <b> <c>", + * "<a> <b>" and "<a>". + * + * The number of matched strings is retrieved using + * g_match_info_get_match_count(). To obtain the matched strings and + * their position you can use, respectively, g_match_info_fetch() and + * g_match_info_fetch_pos(). Note that the strings are returned in + * reverse order of length; that is, the longest matching string is + * given first. + * + * Note that the DFA algorithm is slower than the standard one and it + * is not able to capture substrings, so backreferences do not work. + * + * Setting @start_position differs from just passing over a shortened + * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern + * that begins with any kind of lookbehind assertion, such as "\b". + * + * A #GMatchInfo structure, used to get information on the match, is + * stored in @match_info if not %NULL. Note that if @match_info is + * not %NULL then it is created even if the function returns %FALSE, + * i.e. you must free it regardless if regular expression actually + * matched. + * + * @string is not copied and is used in #GMatchInfo internally. If + * you use any #GMatchInfo method (except g_match_info_free()) after + * freeing or modifying @string then the behaviour is undefined. + * + * Returns: %TRUE is the string matched, %FALSE otherwise + * + * Since: 2.14 + */ +gboolean +g_regex_match_all_full (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + GRegexMatchFlags match_options, + GMatchInfo **match_info, + GError **error) +{ + GMatchInfo *info; + gboolean done; + + g_return_val_if_fail (regex != NULL, FALSE); + g_return_val_if_fail (string != NULL, FALSE); + g_return_val_if_fail (start_position >= 0, FALSE); + g_return_val_if_fail (error == NULL || *error == NULL, FALSE); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE); + + info = match_info_new (regex, string, string_len, start_position, + match_options, TRUE); + + done = FALSE; + while (!done) + { + done = TRUE; + info->matches = pcre_dfa_exec (regex->pcre_re, regex->extra, + info->string, info->string_len, + info->pos, + regex->match_opts | match_options, + info->offsets, info->n_offsets, + info->workspace, info->n_workspace); + if (info->matches == PCRE_ERROR_DFA_WSSIZE) + { + /* info->workspace is too small. */ + info->n_workspace *= 2; + info->workspace = g_realloc (info->workspace, + info->n_workspace * sizeof (gint)); + done = FALSE; + } + else if (info->matches == 0) + { + /* info->offsets is too small. */ + info->n_offsets *= 2; + info->offsets = g_realloc (info->offsets, + info->n_offsets * sizeof (gint)); + done = FALSE; + } + else if (IS_PCRE_ERROR (info->matches)) + { + g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH, + _("Error while matching regular expression %s: %s"), + regex->pattern, match_error (info->matches)); + } + } + + /* set info->pos to -1 so that a call to g_match_info_next() fails. */ + info->pos = -1; + + if (match_info != NULL) + *match_info = info; + else + g_match_info_free (info); + + return info->matches >= 0; +} + +/** + * g_regex_get_string_number: + * @regex: #GRegex structure + * @name: name of the subexpression + * + * Retrieves the number of the subexpression named @name. + * + * Returns: The number of the subexpression or -1 if @name + * does not exists + * + * Since: 2.14 + */ +gint +g_regex_get_string_number (const GRegex *regex, + const gchar *name) +{ + gint num; + + g_return_val_if_fail (regex != NULL, -1); + g_return_val_if_fail (name != NULL, -1); + + num = pcre_get_stringnumber (regex->pcre_re, name); + if (num == PCRE_ERROR_NOSUBSTRING) + num = -1; + + return num; +} + +/** + * g_regex_split_simple: + * @pattern: the regular expression + * @string: the string to scan for matches + * @compile_options: compile options for the regular expression, or 0 + * @match_options: match options, or 0 + * + * Breaks the string on the pattern, and returns an array of + * the tokens. If the pattern contains capturing parentheses, + * then the text for each of the substrings will also be returned. + * If the pattern does not match anywhere in the string, then the + * whole string is returned as the first token. + * + * This function is equivalent to g_regex_split() but it does + * not require to compile the pattern with g_regex_new(), avoiding + * some lines of code when you need just to do a split without + * extracting substrings, capture counts, and so on. + * + * If this function is to be called on the same @pattern more than + * once, it's more efficient to compile the pattern once with + * g_regex_new() and then use g_regex_split(). + * + * As a special case, the result of splitting the empty string "" + * is an empty vector, not a vector containing a single string. + * The reason for this special case is that being able to represent + * a empty vector is typically more useful than consistent handling + * of empty elements. If you do need to represent empty elements, + * you'll need to check for the empty string before calling this + * function. + * + * A pattern that can match empty strings splits @string into + * separate characters wherever it matches the empty string between + * characters. For example splitting "ab c" using as a separator + * "\s*", you will get "a", "b" and "c". + * + * Returns: a %NULL-terminated array of strings. Free it using g_strfreev() + * + * Since: 2.14 + **/ +gchar ** +g_regex_split_simple (const gchar *pattern, + const gchar *string, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options) +{ + GRegex *regex; + gchar **result; + + regex = g_regex_new (pattern, compile_options, 0, NULL); + if (!regex) + return NULL; + + result = g_regex_split_full (regex, string, -1, 0, match_options, 0, NULL); + g_regex_unref (regex); + return result; +} + +/** + * g_regex_split: + * @regex: a #GRegex structure + * @string: the string to split with the pattern + * @match_options: match time option flags + * + * Breaks the string on the pattern, and returns an array of the tokens. + * If the pattern contains capturing parentheses, then the text for each + * of the substrings will also be returned. If the pattern does not match + * anywhere in the string, then the whole string is returned as the first + * token. + * + * As a special case, the result of splitting the empty string "" is an + * empty vector, not a vector containing a single string. The reason for + * this special case is that being able to represent a empty vector is + * typically more useful than consistent handling of empty elements. If + * you do need to represent empty elements, you'll need to check for the + * empty string before calling this function. + * + * A pattern that can match empty strings splits @string into separate + * characters wherever it matches the empty string between characters. + * For example splitting "ab c" using as a separator "\s*", you will get + * "a", "b" and "c". + * + * Returns: a %NULL-terminated gchar ** array. Free it using g_strfreev() + * + * Since: 2.14 + **/ +gchar ** +g_regex_split (const GRegex *regex, + const gchar *string, + GRegexMatchFlags match_options) +{ + return g_regex_split_full (regex, string, -1, 0, + match_options, 0, NULL); +} + +/** + * g_regex_split_full: + * @regex: a #GRegex structure + * @string: (array length=string_len): the string to split with the pattern + * @string_len: the length of @string, or -1 if @string is nul-terminated + * @start_position: starting index of the string to match + * @match_options: match time option flags + * @max_tokens: the maximum number of tokens to split @string into. + * If this is less than 1, the string is split completely + * @error: return location for a #GError + * + * Breaks the string on the pattern, and returns an array of the tokens. + * If the pattern contains capturing parentheses, then the text for each + * of the substrings will also be returned. If the pattern does not match + * anywhere in the string, then the whole string is returned as the first + * token. + * + * As a special case, the result of splitting the empty string "" is an + * empty vector, not a vector containing a single string. The reason for + * this special case is that being able to represent a empty vector is + * typically more useful than consistent handling of empty elements. If + * you do need to represent empty elements, you'll need to check for the + * empty string before calling this function. + * + * A pattern that can match empty strings splits @string into separate + * characters wherever it matches the empty string between characters. + * For example splitting "ab c" using as a separator "\s*", you will get + * "a", "b" and "c". + * + * Setting @start_position differs from just passing over a shortened + * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern + * that begins with any kind of lookbehind assertion, such as "\b". + * + * Returns: a %NULL-terminated gchar ** array. Free it using g_strfreev() + * + * Since: 2.14 + **/ +gchar ** +g_regex_split_full (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + GRegexMatchFlags match_options, + gint max_tokens, + GError **error) +{ + GError *tmp_error = NULL; + GMatchInfo *match_info; + GList *list, *last; + gint i; + gint token_count; + gboolean match_ok; + /* position of the last separator. */ + gint last_separator_end; + /* was the last match 0 bytes long? */ + gboolean last_match_is_empty; + /* the returned array of char **s */ + gchar **string_list; + + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL); + + if (max_tokens <= 0) + max_tokens = G_MAXINT; + + if (string_len < 0) + string_len = strlen (string); + + /* zero-length string */ + if (string_len - start_position == 0) + return g_new0 (gchar *, 1); + + if (max_tokens == 1) + { + string_list = g_new0 (gchar *, 2); + string_list[0] = g_strndup (&string[start_position], + string_len - start_position); + return string_list; + } + + list = NULL; + token_count = 0; + last_separator_end = start_position; + last_match_is_empty = FALSE; + + match_ok = g_regex_match_full (regex, string, string_len, start_position, + match_options, &match_info, &tmp_error); + + while (tmp_error == NULL) + { + if (match_ok) + { + last_match_is_empty = + (match_info->offsets[0] == match_info->offsets[1]); + + /* we need to skip empty separators at the same position of the end + * of another separator. e.g. the string is "a b" and the separator + * is " *", so from 1 to 2 we have a match and at position 2 we have + * an empty match. */ + if (last_separator_end != match_info->offsets[1]) + { + gchar *token; + gint match_count; + + token = g_strndup (string + last_separator_end, + match_info->offsets[0] - last_separator_end); + list = g_list_prepend (list, token); + token_count++; + + /* if there were substrings, these need to be added to + * the list. */ + match_count = g_match_info_get_match_count (match_info); + if (match_count > 1) + { + for (i = 1; i < match_count; i++) + list = g_list_prepend (list, g_match_info_fetch (match_info, i)); + } + } + } + else + { + /* if there was no match, copy to end of string. */ + if (!last_match_is_empty) + { + gchar *token = g_strndup (string + last_separator_end, + match_info->string_len - last_separator_end); + list = g_list_prepend (list, token); + } + /* no more tokens, end the loop. */ + break; + } + + /* -1 to leave room for the last part. */ + if (token_count >= max_tokens - 1) + { + /* we have reached the maximum number of tokens, so we copy + * the remaining part of the string. */ + if (last_match_is_empty) + { + /* the last match was empty, so we have moved one char + * after the real position to avoid empty matches at the + * same position. */ + match_info->pos = PREV_CHAR (regex, &string[match_info->pos]) - string; + } + /* the if is needed in the case we have terminated the available + * tokens, but we are at the end of the string, so there are no + * characters left to copy. */ + if (string_len > match_info->pos) + { + gchar *token = g_strndup (string + match_info->pos, + string_len - match_info->pos); + list = g_list_prepend (list, token); + } + /* end the loop. */ + break; + } + + last_separator_end = match_info->pos; + if (last_match_is_empty) + /* if the last match was empty, g_match_info_next() has moved + * forward to avoid infinite loops, but we still need to copy that + * character. */ + last_separator_end = PREV_CHAR (regex, &string[last_separator_end]) - string; + + match_ok = g_match_info_next (match_info, &tmp_error); + } + g_match_info_free (match_info); + if (tmp_error != NULL) + { + g_propagate_error (error, tmp_error); + g_list_free_full (list, g_free); + match_info->pos = -1; + return NULL; + } + + string_list = g_new (gchar *, g_list_length (list) + 1); + i = 0; + for (last = g_list_last (list); last; last = g_list_previous (last)) + string_list[i++] = last->data; + string_list[i] = NULL; + g_list_free (list); + + return string_list; +} + +enum +{ + REPL_TYPE_STRING, + REPL_TYPE_CHARACTER, + REPL_TYPE_SYMBOLIC_REFERENCE, + REPL_TYPE_NUMERIC_REFERENCE, + REPL_TYPE_CHANGE_CASE +}; + +typedef enum +{ + CHANGE_CASE_NONE = 1 << 0, + CHANGE_CASE_UPPER = 1 << 1, + CHANGE_CASE_LOWER = 1 << 2, + CHANGE_CASE_UPPER_SINGLE = 1 << 3, + CHANGE_CASE_LOWER_SINGLE = 1 << 4, + CHANGE_CASE_SINGLE_MASK = CHANGE_CASE_UPPER_SINGLE | CHANGE_CASE_LOWER_SINGLE, + CHANGE_CASE_LOWER_MASK = CHANGE_CASE_LOWER | CHANGE_CASE_LOWER_SINGLE, + CHANGE_CASE_UPPER_MASK = CHANGE_CASE_UPPER | CHANGE_CASE_UPPER_SINGLE +} ChangeCase; + +struct _InterpolationData +{ + gchar *text; + gint type; + gint num; + gchar c; + ChangeCase change_case; +}; + +static void +free_interpolation_data (InterpolationData *data) +{ + g_free (data->text); + g_free (data); +} + +static const gchar * +expand_escape (const gchar *replacement, + const gchar *p, + InterpolationData *data, + GError **error) +{ + const gchar *q, *r; + gint x, d, h, i; + const gchar *error_detail; + gint base = 0; + GError *tmp_error = NULL; + + p++; + switch (*p) + { + case 't': + p++; + data->c = '\t'; + data->type = REPL_TYPE_CHARACTER; + break; + case 'n': + p++; + data->c = '\n'; + data->type = REPL_TYPE_CHARACTER; + break; + case 'v': + p++; + data->c = '\v'; + data->type = REPL_TYPE_CHARACTER; + break; + case 'r': + p++; + data->c = '\r'; + data->type = REPL_TYPE_CHARACTER; + break; + case 'f': + p++; + data->c = '\f'; + data->type = REPL_TYPE_CHARACTER; + break; + case 'a': + p++; + data->c = '\a'; + data->type = REPL_TYPE_CHARACTER; + break; + case 'b': + p++; + data->c = '\b'; + data->type = REPL_TYPE_CHARACTER; + break; + case '\\': + p++; + data->c = '\\'; + data->type = REPL_TYPE_CHARACTER; + break; + case 'x': + p++; + x = 0; + if (*p == '{') + { + p++; + do + { + h = g_ascii_xdigit_value (*p); + if (h < 0) + { + error_detail = _("hexadecimal digit or '}' expected"); + goto error; + } + x = x * 16 + h; + p++; + } + while (*p != '}'); + p++; + } + else + { + for (i = 0; i < 2; i++) + { + h = g_ascii_xdigit_value (*p); + if (h < 0) + { + error_detail = _("hexadecimal digit expected"); + goto error; + } + x = x * 16 + h; + p++; + } + } + data->type = REPL_TYPE_STRING; + data->text = g_new0 (gchar, 8); + g_unichar_to_utf8 (x, data->text); + break; + case 'l': + p++; + data->type = REPL_TYPE_CHANGE_CASE; + data->change_case = CHANGE_CASE_LOWER_SINGLE; + break; + case 'u': + p++; + data->type = REPL_TYPE_CHANGE_CASE; + data->change_case = CHANGE_CASE_UPPER_SINGLE; + break; + case 'L': + p++; + data->type = REPL_TYPE_CHANGE_CASE; + data->change_case = CHANGE_CASE_LOWER; + break; + case 'U': + p++; + data->type = REPL_TYPE_CHANGE_CASE; + data->change_case = CHANGE_CASE_UPPER; + break; + case 'E': + p++; + data->type = REPL_TYPE_CHANGE_CASE; + data->change_case = CHANGE_CASE_NONE; + break; + case 'g': + p++; + if (*p != '<') + { + error_detail = _("missing '<' in symbolic reference"); + goto error; + } + q = p + 1; + do + { + p++; + if (!*p) + { + error_detail = _("unfinished symbolic reference"); + goto error; + } + } + while (*p != '>'); + if (p - q == 0) + { + error_detail = _("zero-length symbolic reference"); + goto error; + } + if (g_ascii_isdigit (*q)) + { + x = 0; + do + { + h = g_ascii_digit_value (*q); + if (h < 0) + { + error_detail = _("digit expected"); + p = q; + goto error; + } + x = x * 10 + h; + q++; + } + while (q != p); + data->num = x; + data->type = REPL_TYPE_NUMERIC_REFERENCE; + } + else + { + r = q; + do + { + if (!g_ascii_isalnum (*r)) + { + error_detail = _("illegal symbolic reference"); + p = r; + goto error; + } + r++; + } + while (r != p); + data->text = g_strndup (q, p - q); + data->type = REPL_TYPE_SYMBOLIC_REFERENCE; + } + p++; + break; + case '0': + /* if \0 is followed by a number is an octal number representing a + * character, else it is a numeric reference. */ + if (g_ascii_digit_value (*g_utf8_next_char (p)) >= 0) + { + base = 8; + p = g_utf8_next_char (p); + } + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + x = 0; + d = 0; + for (i = 0; i < 3; i++) + { + h = g_ascii_digit_value (*p); + if (h < 0) + break; + if (h > 7) + { + if (base == 8) + break; + else + base = 10; + } + if (i == 2 && base == 10) + break; + x = x * 8 + h; + d = d * 10 + h; + p++; + } + if (base == 8 || i == 3) + { + data->type = REPL_TYPE_STRING; + data->text = g_new0 (gchar, 8); + g_unichar_to_utf8 (x, data->text); + } + else + { + data->type = REPL_TYPE_NUMERIC_REFERENCE; + data->num = d; + } + break; + case 0: + error_detail = _("stray final '\\'"); + goto error; + break; + default: + error_detail = _("unknown escape sequence"); + goto error; + } + + return p; + + error: + /* G_GSSIZE_FORMAT doesn't work with gettext, so we use %lu */ + tmp_error = g_error_new (G_REGEX_ERROR, + G_REGEX_ERROR_REPLACE, + _("Error while parsing replacement " + "text \"%s\" at char %lu: %s"), + replacement, + (gulong)(p - replacement), + error_detail); + g_propagate_error (error, tmp_error); + + return NULL; +} + +static GList * +split_replacement (const gchar *replacement, + GError **error) +{ + GList *list = NULL; + InterpolationData *data; + const gchar *p, *start; + + start = p = replacement; + while (*p) + { + if (*p == '\\') + { + data = g_new0 (InterpolationData, 1); + start = p = expand_escape (replacement, p, data, error); + if (p == NULL) + { + g_list_free_full (list, (GDestroyNotify) free_interpolation_data); + free_interpolation_data (data); + + return NULL; + } + list = g_list_prepend (list, data); + } + else + { + p++; + if (*p == '\\' || *p == '\0') + { + if (p - start > 0) + { + data = g_new0 (InterpolationData, 1); + data->text = g_strndup (start, p - start); + data->type = REPL_TYPE_STRING; + list = g_list_prepend (list, data); + } + } + } + } + + return g_list_reverse (list); +} + +/* Change the case of c based on change_case. */ +#define CHANGE_CASE(c, change_case) \ + (((change_case) & CHANGE_CASE_LOWER_MASK) ? \ + g_unichar_tolower (c) : \ + g_unichar_toupper (c)) + +static void +string_append (GString *string, + const gchar *text, + ChangeCase *change_case) +{ + gunichar c; + + if (text[0] == '\0') + return; + + if (*change_case == CHANGE_CASE_NONE) + { + g_string_append (string, text); + } + else if (*change_case & CHANGE_CASE_SINGLE_MASK) + { + c = g_utf8_get_char (text); + g_string_append_unichar (string, CHANGE_CASE (c, *change_case)); + g_string_append (string, g_utf8_next_char (text)); + *change_case = CHANGE_CASE_NONE; + } + else + { + while (*text != '\0') + { + c = g_utf8_get_char (text); + g_string_append_unichar (string, CHANGE_CASE (c, *change_case)); + text = g_utf8_next_char (text); + } + } +} + +static gboolean +interpolate_replacement (const GMatchInfo *match_info, + GString *result, + gpointer data) +{ + GList *list; + InterpolationData *idata; + gchar *match; + ChangeCase change_case = CHANGE_CASE_NONE; + + for (list = data; list; list = list->next) + { + idata = list->data; + switch (idata->type) + { + case REPL_TYPE_STRING: + string_append (result, idata->text, &change_case); + break; + case REPL_TYPE_CHARACTER: + g_string_append_c (result, CHANGE_CASE (idata->c, change_case)); + if (change_case & CHANGE_CASE_SINGLE_MASK) + change_case = CHANGE_CASE_NONE; + break; + case REPL_TYPE_NUMERIC_REFERENCE: + match = g_match_info_fetch (match_info, idata->num); + if (match) + { + string_append (result, match, &change_case); + g_free (match); + } + break; + case REPL_TYPE_SYMBOLIC_REFERENCE: + match = g_match_info_fetch_named (match_info, idata->text); + if (match) + { + string_append (result, match, &change_case); + g_free (match); + } + break; + case REPL_TYPE_CHANGE_CASE: + change_case = idata->change_case; + break; + } + } + + return FALSE; +} + +/* whether actual match_info is needed for replacement, i.e. + * whether there are references + */ +static gboolean +interpolation_list_needs_match (GList *list) +{ + while (list != NULL) + { + InterpolationData *data = list->data; + + if (data->type == REPL_TYPE_SYMBOLIC_REFERENCE || + data->type == REPL_TYPE_NUMERIC_REFERENCE) + { + return TRUE; + } + + list = list->next; + } + + return FALSE; +} + +/** + * g_regex_replace: + * @regex: a #GRegex structure + * @string: (array length=string_len): the string to perform matches against + * @string_len: the length of @string, or -1 if @string is nul-terminated + * @start_position: starting index of the string to match + * @replacement: text to replace each match with + * @match_options: options for the match + * @error: location to store the error occurring, or %NULL to ignore errors + * + * Replaces all occurrences of the pattern in @regex with the + * replacement text. Backreferences of the form '\number' or + * '\g<number>' in the replacement text are interpolated by the + * number-th captured subexpression of the match, '\g<name>' refers + * to the captured subexpression with the given name. '\0' refers to the + * complete match, but '\0' followed by a number is the octal representation + * of a character. To include a literal '\' in the replacement, write '\\'. + * There are also escapes that changes the case of the following text: + * + * + * \l + * + * Convert to lower case the next character + * + * + * \u + * + * Convert to upper case the next character + * + * + * \L + * + * Convert to lower case till \E + * + * + * \U + * + * Convert to upper case till \E + * + * + * \E + * + * End case modification + * + * + * + * + * If you do not need to use backreferences use g_regex_replace_literal(). + * + * The @replacement string must be UTF-8 encoded even if #G_REGEX_RAW was + * passed to g_regex_new(). If you want to use not UTF-8 encoded stings + * you can use g_regex_replace_literal(). + * + * Setting @start_position differs from just passing over a shortened + * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern that + * begins with any kind of lookbehind assertion, such as "\b". + * + * Returns: a newly allocated string containing the replacements + * + * Since: 2.14 + */ +gchar * +g_regex_replace (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + const gchar *replacement, + GRegexMatchFlags match_options, + GError **error) +{ + gchar *result; + GList *list; + GError *tmp_error = NULL; + + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); + g_return_val_if_fail (replacement != NULL, NULL); + g_return_val_if_fail (error == NULL || *error == NULL, NULL); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL); + + list = split_replacement (replacement, &tmp_error); + if (tmp_error != NULL) + { + g_propagate_error (error, tmp_error); + return NULL; + } + + result = g_regex_replace_eval (regex, + string, string_len, start_position, + match_options, + interpolate_replacement, + (gpointer)list, + &tmp_error); + if (tmp_error != NULL) + g_propagate_error (error, tmp_error); + + g_list_free_full (list, (GDestroyNotify) free_interpolation_data); + + return result; +} + +static gboolean +literal_replacement (const GMatchInfo *match_info, + GString *result, + gpointer data) +{ + g_string_append (result, data); + return FALSE; +} + +/** + * g_regex_replace_literal: + * @regex: a #GRegex structure + * @string: (array length=string_len): the string to perform matches against + * @string_len: the length of @string, or -1 if @string is nul-terminated + * @start_position: starting index of the string to match + * @replacement: text to replace each match with + * @match_options: options for the match + * @error: location to store the error occurring, or %NULL to ignore errors + * + * Replaces all occurrences of the pattern in @regex with the + * replacement text. @replacement is replaced literally, to + * include backreferences use g_regex_replace(). + * + * Setting @start_position differs from just passing over a + * shortened string and setting #G_REGEX_MATCH_NOTBOL in the + * case of a pattern that begins with any kind of lookbehind + * assertion, such as "\b". + * + * Returns: a newly allocated string containing the replacements + * + * Since: 2.14 + */ +gchar * +g_regex_replace_literal (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + const gchar *replacement, + GRegexMatchFlags match_options, + GError **error) +{ + g_return_val_if_fail (replacement != NULL, NULL); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL); + + return g_regex_replace_eval (regex, + string, string_len, start_position, + match_options, + literal_replacement, + (gpointer)replacement, + error); +} + +/** + * g_regex_replace_eval: + * @regex: a #GRegex structure from g_regex_new() + * @string: (array length=string_len): string to perform matches against + * @string_len: the length of @string, or -1 if @string is nul-terminated + * @start_position: starting index of the string to match + * @match_options: options for the match + * @eval: a function to call for each match + * @user_data: user data to pass to the function + * @error: location to store the error occurring, or %NULL to ignore errors + * + * Replaces occurrences of the pattern in regex with the output of + * @eval for that occurrence. + * + * Setting @start_position differs from just passing over a shortened + * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern + * that begins with any kind of lookbehind assertion, such as "\b". + * + * The following example uses g_regex_replace_eval() to replace multiple + * strings at once: + * |[ + * static gboolean + * eval_cb (const GMatchInfo *info, + * GString *res, + * gpointer data) + * { + * gchar *match; + * gchar *r; + * + * match = g_match_info_fetch (info, 0); + * r = g_hash_table_lookup ((GHashTable *)data, match); + * g_string_append (res, r); + * g_free (match); + * + * return FALSE; + * } + * + * /* ... */ + * + * GRegex *reg; + * GHashTable *h; + * gchar *res; + * + * h = g_hash_table_new (g_str_hash, g_str_equal); + * + * g_hash_table_insert (h, "1", "ONE"); + * g_hash_table_insert (h, "2", "TWO"); + * g_hash_table_insert (h, "3", "THREE"); + * g_hash_table_insert (h, "4", "FOUR"); + * + * reg = g_regex_new ("1|2|3|4", 0, 0, NULL); + * res = g_regex_replace_eval (reg, text, -1, 0, 0, eval_cb, h, NULL); + * g_hash_table_destroy (h); + * + * /* ... */ + * ]| + * + * Returns: a newly allocated string containing the replacements + * + * Since: 2.14 + */ +gchar * +g_regex_replace_eval (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + GRegexMatchFlags match_options, + GRegexEvalCallback eval, + gpointer user_data, + GError **error) +{ + GMatchInfo *match_info; + GString *result; + gint str_pos = 0; + gboolean done = FALSE; + GError *tmp_error = NULL; + + g_return_val_if_fail (regex != NULL, NULL); + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (start_position >= 0, NULL); + g_return_val_if_fail (eval != NULL, NULL); + g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL); + + if (string_len < 0) + string_len = strlen (string); + + result = g_string_sized_new (string_len); + + /* run down the string making matches. */ + g_regex_match_full (regex, string, string_len, start_position, + match_options, &match_info, &tmp_error); + while (!done && g_match_info_matches (match_info)) + { + g_string_append_len (result, + string + str_pos, + match_info->offsets[0] - str_pos); + done = (*eval) (match_info, result, user_data); + str_pos = match_info->offsets[1]; + g_match_info_next (match_info, &tmp_error); + } + g_match_info_free (match_info); + if (tmp_error != NULL) + { + g_propagate_error (error, tmp_error); + g_string_free (result, TRUE); + return NULL; + } + + g_string_append_len (result, string + str_pos, string_len - str_pos); + return g_string_free (result, FALSE); +} + +/** + * g_regex_check_replacement: + * @replacement: the replacement string + * @has_references: (out) (allow-none): location to store information about + * references in @replacement or %NULL + * @error: location to store error + * + * Checks whether @replacement is a valid replacement string + * (see g_regex_replace()), i.e. that all escape sequences in + * it are valid. + * + * If @has_references is not %NULL then @replacement is checked + * for pattern references. For instance, replacement text 'foo\n' + * does not contain references and may be evaluated without information + * about actual match, but '\0\1' (whole match followed by first + * subpattern) requires valid #GMatchInfo object. + * + * Returns: whether @replacement is a valid replacement string + * + * Since: 2.14 + */ +gboolean +g_regex_check_replacement (const gchar *replacement, + gboolean *has_references, + GError **error) +{ + GList *list; + GError *tmp = NULL; + + list = split_replacement (replacement, &tmp); + + if (tmp) + { + g_propagate_error (error, tmp); + return FALSE; + } + + if (has_references) + *has_references = interpolation_list_needs_match (list); + + g_list_free_full (list, (GDestroyNotify) free_interpolation_data); + + return TRUE; +} + +/** + * g_regex_escape_nul: + * @string: the string to escape + * @length: the length of @string + * + * Escapes the nul characters in @string to "\x00". It can be used + * to compile a regex with embedded nul characters. + * + * For completeness, @length can be -1 for a nul-terminated string. + * In this case the output string will be of course equal to @string. + * + * Returns: a newly-allocated escaped string + * + * Since: 2.30 + */ +gchar * +g_regex_escape_nul (const gchar *string, + gint length) +{ + GString *escaped; + const gchar *p, *piece_start, *end; + gint backslashes; + + g_return_val_if_fail (string != NULL, NULL); + + if (length < 0) + return g_strdup (string); + + end = string + length; + p = piece_start = string; + escaped = g_string_sized_new (length + 1); + + backslashes = 0; + while (p < end) + { + switch (*p) + { + case '\0': + if (p != piece_start) + { + /* copy the previous piece. */ + g_string_append_len (escaped, piece_start, p - piece_start); + } + if ((backslashes & 1) == 0) + g_string_append_c (escaped, '\\'); + g_string_append_c (escaped, 'x'); + g_string_append_c (escaped, '0'); + g_string_append_c (escaped, '0'); + piece_start = ++p; + backslashes = 0; + break; + case '\\': + backslashes++; + ++p; + break; + default: + backslashes = 0; + p = g_utf8_next_char (p); + break; + } + } + + if (piece_start < end) + g_string_append_len (escaped, piece_start, end - piece_start); + + return g_string_free (escaped, FALSE); +} + +/** + * g_regex_escape_string: + * @string: (array length=length): the string to escape + * @length: the length of @string, or -1 if @string is nul-terminated + * + * Escapes the special characters used for regular expressions + * in @string, for instance "a.b*c" becomes "a\.b\*c". This + * function is useful to dynamically generate regular expressions. + * + * @string can contain nul characters that are replaced with "\0", + * in this case remember to specify the correct length of @string + * in @length. + * + * Returns: a newly-allocated escaped string + * + * Since: 2.14 + */ +gchar * +g_regex_escape_string (const gchar *string, + gint length) +{ + GString *escaped; + const char *p, *piece_start, *end; + + g_return_val_if_fail (string != NULL, NULL); + + if (length < 0) + length = strlen (string); + + end = string + length; + p = piece_start = string; + escaped = g_string_sized_new (length + 1); + + while (p < end) + { + switch (*p) + { + case '\0': + case '\\': + case '|': + case '(': + case ')': + case '[': + case ']': + case '{': + case '}': + case '^': + case '$': + case '*': + case '+': + case '?': + case '.': + if (p != piece_start) + /* copy the previous piece. */ + g_string_append_len (escaped, piece_start, p - piece_start); + g_string_append_c (escaped, '\\'); + if (*p == '\0') + g_string_append_c (escaped, '0'); + else + g_string_append_c (escaped, *p); + piece_start = ++p; + break; + default: + p = g_utf8_next_char (p); + break; + } + } + + if (piece_start < end) + g_string_append_len (escaped, piece_start, end - piece_start); + + return g_string_free (escaped, FALSE); +} diff --git a/glib/glib/gregex.h b/glib/glib/gregex.h new file mode 100644 index 0000000..1110ad0 --- /dev/null +++ b/glib/glib/gregex.h @@ -0,0 +1,475 @@ +/* GRegex -- regular expression API wrapper around PCRE. + * + * Copyright (C) 1999, 2000 Scott Wimer + * Copyright (C) 2004, Matthias Clasen + * Copyright (C) 2005 - 2007, Marco Barisione + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_REGEX_H__ +#define __G_REGEX_H__ + +#include +#include + +G_BEGIN_DECLS + +/** + * GRegexError: + * @G_REGEX_ERROR_COMPILE: Compilation of the regular expression failed. + * @G_REGEX_ERROR_OPTIMIZE: Optimization of the regular expression failed. + * @G_REGEX_ERROR_REPLACE: Replacement failed due to an ill-formed replacement + * string. + * @G_REGEX_ERROR_MATCH: The match process failed. + * @G_REGEX_ERROR_INTERNAL: Internal error of the regular expression engine. + * Since 2.16 + * @G_REGEX_ERROR_STRAY_BACKSLASH: "\\" at end of pattern. Since 2.16 + * @G_REGEX_ERROR_MISSING_CONTROL_CHAR: "\\c" at end of pattern. Since 2.16 + * @G_REGEX_ERROR_UNRECOGNIZED_ESCAPE: Unrecognized character follows "\\". + * Since 2.16 + * @G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER: Numbers out of order in "{}" + * quantifier. Since 2.16 + * @G_REGEX_ERROR_QUANTIFIER_TOO_BIG: Number too big in "{}" quantifier. + * Since 2.16 + * @G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS: Missing terminating "]" for + * character class. Since 2.16 + * @G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS: Invalid escape sequence + * in character class. Since 2.16 + * @G_REGEX_ERROR_RANGE_OUT_OF_ORDER: Range out of order in character class. + * Since 2.16 + * @G_REGEX_ERROR_NOTHING_TO_REPEAT: Nothing to repeat. Since 2.16 + * @G_REGEX_ERROR_UNRECOGNIZED_CHARACTER: Unrecognized character after "(?", + * "(?<" or "(?P". Since 2.16 + * @G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS: POSIX named classes are + * supported only within a class. Since 2.16 + * @G_REGEX_ERROR_UNMATCHED_PARENTHESIS: Missing terminating ")" or ")" + * without opening "(". Since 2.16 + * @G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE: Reference to non-existent + * subpattern. Since 2.16 + * @G_REGEX_ERROR_UNTERMINATED_COMMENT: Missing terminating ")" after comment. + * Since 2.16 + * @G_REGEX_ERROR_EXPRESSION_TOO_LARGE: Regular expression too large. + * Since 2.16 + * @G_REGEX_ERROR_MEMORY_ERROR: Failed to get memory. Since 2.16 + * @G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND: Lookbehind assertion is not + * fixed length. Since 2.16 + * @G_REGEX_ERROR_MALFORMED_CONDITION: Malformed number or name after "(?(". + * Since 2.16 + * @G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES: Conditional group contains + * more than two branches. Since 2.16 + * @G_REGEX_ERROR_ASSERTION_EXPECTED: Assertion expected after "(?(". + * Since 2.16 + * @G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME: Unknown POSIX class name. + * Since 2.16 + * @G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED: POSIX collating + * elements are not supported. Since 2.16 + * @G_REGEX_ERROR_HEX_CODE_TOO_LARGE: Character value in "\\x{...}" sequence + * is too large. Since 2.16 + * @G_REGEX_ERROR_INVALID_CONDITION: Invalid condition "(?(0)". Since 2.16 + * @G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND: \\C not allowed in + * lookbehind assertion. Since 2.16 + * @G_REGEX_ERROR_INFINITE_LOOP: Recursive call could loop indefinitely. + * Since 2.16 + * @G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR: Missing terminator + * in subpattern name. Since 2.16 + * @G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME: Two named subpatterns have + * the same name. Since 2.16 + * @G_REGEX_ERROR_MALFORMED_PROPERTY: Malformed "\\P" or "\\p" sequence. + * Since 2.16 + * @G_REGEX_ERROR_UNKNOWN_PROPERTY: Unknown property name after "\\P" or + * "\\p". Since 2.16 + * @G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG: Subpattern name is too long + * (maximum 32 characters). Since 2.16 + * @G_REGEX_ERROR_TOO_MANY_SUBPATTERNS: Too many named subpatterns (maximum + * 10,000). Since 2.16 + * @G_REGEX_ERROR_INVALID_OCTAL_VALUE: Octal value is greater than "\\377". + * Since 2.16 + * @G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE: "DEFINE" group contains more + * than one branch. Since 2.16 + * @G_REGEX_ERROR_DEFINE_REPETION: Repeating a "DEFINE" group is not allowed. + * Since 2.16 + * @G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS: Inconsistent newline options. + * Since 2.16 + * @G_REGEX_ERROR_MISSING_BACK_REFERENCE: "\\g" is not followed by a braced + * name or an optionally braced non-zero number. Since 2.16 + * + * Error codes returned by regular expressions functions. + * + * Since: 2.14 + */ +typedef enum +{ + G_REGEX_ERROR_COMPILE, + G_REGEX_ERROR_OPTIMIZE, + G_REGEX_ERROR_REPLACE, + G_REGEX_ERROR_MATCH, + G_REGEX_ERROR_INTERNAL, + + /* These are the error codes from PCRE + 100 */ + G_REGEX_ERROR_STRAY_BACKSLASH = 101, + G_REGEX_ERROR_MISSING_CONTROL_CHAR = 102, + G_REGEX_ERROR_UNRECOGNIZED_ESCAPE = 103, + G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER = 104, + G_REGEX_ERROR_QUANTIFIER_TOO_BIG = 105, + G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS = 106, + G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS = 107, + G_REGEX_ERROR_RANGE_OUT_OF_ORDER = 108, + G_REGEX_ERROR_NOTHING_TO_REPEAT = 109, + G_REGEX_ERROR_UNRECOGNIZED_CHARACTER = 112, + G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS = 113, + G_REGEX_ERROR_UNMATCHED_PARENTHESIS = 114, + G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE = 115, + G_REGEX_ERROR_UNTERMINATED_COMMENT = 118, + G_REGEX_ERROR_EXPRESSION_TOO_LARGE = 120, + G_REGEX_ERROR_MEMORY_ERROR = 121, + G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND = 125, + G_REGEX_ERROR_MALFORMED_CONDITION = 126, + G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES = 127, + G_REGEX_ERROR_ASSERTION_EXPECTED = 128, + G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME = 130, + G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED = 131, + G_REGEX_ERROR_HEX_CODE_TOO_LARGE = 134, + G_REGEX_ERROR_INVALID_CONDITION = 135, + G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND = 136, + G_REGEX_ERROR_INFINITE_LOOP = 140, + G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR = 142, + G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME = 143, + G_REGEX_ERROR_MALFORMED_PROPERTY = 146, + G_REGEX_ERROR_UNKNOWN_PROPERTY = 147, + G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG = 148, + G_REGEX_ERROR_TOO_MANY_SUBPATTERNS = 149, + G_REGEX_ERROR_INVALID_OCTAL_VALUE = 151, + G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE = 154, + G_REGEX_ERROR_DEFINE_REPETION = 155, + G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS = 156, + G_REGEX_ERROR_MISSING_BACK_REFERENCE = 157 +} GRegexError; + +/** + * G_REGEX_ERROR: + * + * Error domain for regular expressions. Errors in this domain will be + * from the #GRegexError enumeration. See #GError for information on + * error domains. + * + * Since: 2.14 + */ +#define G_REGEX_ERROR g_regex_error_quark () + +GQuark g_regex_error_quark (void); + +/** + * GRegexCompileFlags: + * @G_REGEX_CASELESS: Letters in the pattern match both upper- and + * lowercase letters. This option can be changed within a pattern + * by a "(?i)" option setting. + * @G_REGEX_MULTILINE: By default, GRegex treats the strings as consisting + * of a single line of characters (even if it actually contains + * newlines). The "start of line" metacharacter ("^") matches only + * at the start of the string, while the "end of line" metacharacter + * ("$") matches only at the end of the string, or before a terminating + * newline (unless #G_REGEX_DOLLAR_ENDONLY is set). When + * #G_REGEX_MULTILINE is set, the "start of line" and "end of line" + * constructs match immediately following or immediately before any + * newline in the string, respectively, as well as at the very start + * and end. This can be changed within a pattern by a "(?m)" option + * setting. + * @G_REGEX_DOTALL: A dot metacharater (".") in the pattern matches all + * characters, including newlines. Without it, newlines are excluded. + * This option can be changed within a pattern by a ("?s") option setting. + * @G_REGEX_EXTENDED: Whitespace data characters in the pattern are + * totally ignored except when escaped or inside a character class. + * Whitespace does not include the VT character (code 11). In addition, + * characters between an unescaped "#" outside a character class and + * the next newline character, inclusive, are also ignored. This can + * be changed within a pattern by a "(?x)" option setting. + * @G_REGEX_ANCHORED: The pattern is forced to be "anchored", that is, + * it is constrained to match only at the first matching point in the + * string that is being searched. This effect can also be achieved by + * appropriate constructs in the pattern itself such as the "^" + * metacharater. + * @G_REGEX_DOLLAR_ENDONLY: A dollar metacharacter ("$") in the pattern + * matches only at the end of the string. Without this option, a + * dollar also matches immediately before the final character if + * it is a newline (but not before any other newlines). This option + * is ignored if #G_REGEX_MULTILINE is set. + * @G_REGEX_UNGREEDY: Inverts the "greediness" of the quantifiers so that + * they are not greedy by default, but become greedy if followed by "?". + * It can also be set by a "(?U)" option setting within the pattern. + * @G_REGEX_RAW: Usually strings must be valid UTF-8 strings, using this + * flag they are considered as a raw sequence of bytes. + * @G_REGEX_NO_AUTO_CAPTURE: Disables the use of numbered capturing + * parentheses in the pattern. Any opening parenthesis that is not + * followed by "?" behaves as if it were followed by "?:" but named + * parentheses can still be used for capturing (and they acquire numbers + * in the usual way). + * @G_REGEX_OPTIMIZE: Optimize the regular expression. If the pattern will + * be used many times, then it may be worth the effort to optimize it + * to improve the speed of matches. + * @G_REGEX_DUPNAMES: Names used to identify capturing subpatterns need not + * be unique. This can be helpful for certain types of pattern when it + * is known that only one instance of the named subpattern can ever be + * matched. + * @G_REGEX_NEWLINE_CR: Usually any newline character is recognized, if this + * option is set, the only recognized newline character is '\r'. + * @G_REGEX_NEWLINE_LF: Usually any newline character is recognized, if this + * option is set, the only recognized newline character is '\n'. + * @G_REGEX_NEWLINE_CRLF: Usually any newline character is recognized, if this + * option is set, the only recognized newline character sequence is '\r\n'. + * + * Flags specifying compile-time options. + * + * Since: 2.14 + */ +/* Remember to update G_REGEX_COMPILE_MASK in gregex.c after + * adding a new flag. */ +typedef enum +{ + G_REGEX_CASELESS = 1 << 0, + G_REGEX_MULTILINE = 1 << 1, + G_REGEX_DOTALL = 1 << 2, + G_REGEX_EXTENDED = 1 << 3, + G_REGEX_ANCHORED = 1 << 4, + G_REGEX_DOLLAR_ENDONLY = 1 << 5, + G_REGEX_UNGREEDY = 1 << 9, + G_REGEX_RAW = 1 << 11, + G_REGEX_NO_AUTO_CAPTURE = 1 << 12, + G_REGEX_OPTIMIZE = 1 << 13, + G_REGEX_DUPNAMES = 1 << 19, + G_REGEX_NEWLINE_CR = 1 << 20, + G_REGEX_NEWLINE_LF = 1 << 21, + G_REGEX_NEWLINE_CRLF = G_REGEX_NEWLINE_CR | G_REGEX_NEWLINE_LF +} GRegexCompileFlags; + +/** + * GRegexMatchFlags: + * @G_REGEX_MATCH_ANCHORED: The pattern is forced to be "anchored", that is, + * it is constrained to match only at the first matching point in the + * string that is being searched. This effect can also be achieved by + * appropriate constructs in the pattern itself such as the "^" + * metacharater. + * @G_REGEX_MATCH_NOTBOL: Specifies that first character of the string is + * not the beginning of a line, so the circumflex metacharacter should + * not match before it. Setting this without #G_REGEX_MULTILINE (at + * compile time) causes circumflex never to match. This option affects + * only the behaviour of the circumflex metacharacter, it does not + * affect "\A". + * @G_REGEX_MATCH_NOTEOL: Specifies that the end of the subject string is + * not the end of a line, so the dollar metacharacter should not match + * it nor (except in multiline mode) a newline immediately before it. + * Setting this without #G_REGEX_MULTILINE (at compile time) causes + * dollar never to match. This option affects only the behaviour of + * the dollar metacharacter, it does not affect "\Z" or "\z". + * @G_REGEX_MATCH_NOTEMPTY: An empty string is not considered to be a valid + * match if this option is set. If there are alternatives in the pattern, + * they are tried. If all the alternatives match the empty string, the + * entire match fails. For example, if the pattern "a?b?" is applied to + * a string not beginning with "a" or "b", it matches the empty string + * at the start of the string. With this flag set, this match is not + * valid, so GRegex searches further into the string for occurrences + * of "a" or "b". + * @G_REGEX_MATCH_PARTIAL: Turns on the partial matching feature, for more + * documentation on partial matching see g_match_info_is_partial_match(). + * @G_REGEX_MATCH_NEWLINE_CR: Overrides the newline definition set when + * creating a new #GRegex, setting the '\r' character as line terminator. + * @G_REGEX_MATCH_NEWLINE_LF: Overrides the newline definition set when + * creating a new #GRegex, setting the '\n' character as line terminator. + * @G_REGEX_MATCH_NEWLINE_CRLF: Overrides the newline definition set when + * creating a new #GRegex, setting the '\r\n' characters as line terminator. + * @G_REGEX_MATCH_NEWLINE_ANY: Overrides the newline definition set when + * creating a new #GRegex, any newline character or character sequence + * is recognized. + * + * Flags specifying match-time options. + * + * Since: 2.14 + */ +/* Remember to update G_REGEX_MATCH_MASK in gregex.c after + * adding a new flag. */ +typedef enum +{ + G_REGEX_MATCH_ANCHORED = 1 << 4, + G_REGEX_MATCH_NOTBOL = 1 << 7, + G_REGEX_MATCH_NOTEOL = 1 << 8, + G_REGEX_MATCH_NOTEMPTY = 1 << 10, + G_REGEX_MATCH_PARTIAL = 1 << 15, + G_REGEX_MATCH_NEWLINE_CR = 1 << 20, + G_REGEX_MATCH_NEWLINE_LF = 1 << 21, + G_REGEX_MATCH_NEWLINE_CRLF = G_REGEX_MATCH_NEWLINE_CR | G_REGEX_MATCH_NEWLINE_LF, + G_REGEX_MATCH_NEWLINE_ANY = 1 << 22 +} GRegexMatchFlags; + +/** + * GRegex: + * + * A GRegex is the "compiled" form of a regular expression pattern. This + * structure is opaque and its fields cannot be accessed directly. + * + * Since: 2.14 + */ +typedef struct _GRegex GRegex; + + +typedef struct _GMatchInfo GMatchInfo; + +/** + * GRegexEvalCallback: + * @match_info: the #GMatchInfo generated by the match. + * Use g_match_info_get_regex() and g_match_info_get_string() if you + * need the #GRegex or the matched string. + * @result: a #GString containing the new string + * @user_data: user data passed to g_regex_replace_eval() + * + * Specifies the type of the function passed to g_regex_replace_eval(). + * It is called for each occurrence of the pattern in the string passed + * to g_regex_replace_eval(), and it should append the replacement to + * @result. + * + * Returns: %FALSE to continue the replacement process, %TRUE to stop it + * + * Since: 2.14 + */ +typedef gboolean (*GRegexEvalCallback) (const GMatchInfo *match_info, + GString *result, + gpointer user_data); + + +GRegex *g_regex_new (const gchar *pattern, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options, + GError **error); +GRegex *g_regex_ref (GRegex *regex); +void g_regex_unref (GRegex *regex); +const gchar *g_regex_get_pattern (const GRegex *regex); +gint g_regex_get_max_backref (const GRegex *regex); +gint g_regex_get_capture_count (const GRegex *regex); +gint g_regex_get_string_number (const GRegex *regex, + const gchar *name); +gchar *g_regex_escape_string (const gchar *string, + gint length); +gchar *g_regex_escape_nul (const gchar *string, + gint length); + +GRegexCompileFlags g_regex_get_compile_flags (const GRegex *regex); +GRegexMatchFlags g_regex_get_match_flags (const GRegex *regex); + +/* Matching. */ +gboolean g_regex_match_simple (const gchar *pattern, + const gchar *string, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options); +gboolean g_regex_match (const GRegex *regex, + const gchar *string, + GRegexMatchFlags match_options, + GMatchInfo **match_info); +gboolean g_regex_match_full (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + GRegexMatchFlags match_options, + GMatchInfo **match_info, + GError **error); +gboolean g_regex_match_all (const GRegex *regex, + const gchar *string, + GRegexMatchFlags match_options, + GMatchInfo **match_info); +gboolean g_regex_match_all_full (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + GRegexMatchFlags match_options, + GMatchInfo **match_info, + GError **error); + +/* String splitting. */ +gchar **g_regex_split_simple (const gchar *pattern, + const gchar *string, + GRegexCompileFlags compile_options, + GRegexMatchFlags match_options); +gchar **g_regex_split (const GRegex *regex, + const gchar *string, + GRegexMatchFlags match_options); +gchar **g_regex_split_full (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + GRegexMatchFlags match_options, + gint max_tokens, + GError **error); + +/* String replacement. */ +gchar *g_regex_replace (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + const gchar *replacement, + GRegexMatchFlags match_options, + GError **error); +gchar *g_regex_replace_literal (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + const gchar *replacement, + GRegexMatchFlags match_options, + GError **error); +gchar *g_regex_replace_eval (const GRegex *regex, + const gchar *string, + gssize string_len, + gint start_position, + GRegexMatchFlags match_options, + GRegexEvalCallback eval, + gpointer user_data, + GError **error); +gboolean g_regex_check_replacement (const gchar *replacement, + gboolean *has_references, + GError **error); + +/* Match info */ +GRegex *g_match_info_get_regex (const GMatchInfo *match_info); +const gchar *g_match_info_get_string (const GMatchInfo *match_info); + +GMatchInfo *g_match_info_ref (GMatchInfo *match_info); +void g_match_info_unref (GMatchInfo *match_info); +void g_match_info_free (GMatchInfo *match_info); +gboolean g_match_info_next (GMatchInfo *match_info, + GError **error); +gboolean g_match_info_matches (const GMatchInfo *match_info); +gint g_match_info_get_match_count (const GMatchInfo *match_info); +gboolean g_match_info_is_partial_match (const GMatchInfo *match_info); +gchar *g_match_info_expand_references(const GMatchInfo *match_info, + const gchar *string_to_expand, + GError **error); +gchar *g_match_info_fetch (const GMatchInfo *match_info, + gint match_num); +gboolean g_match_info_fetch_pos (const GMatchInfo *match_info, + gint match_num, + gint *start_pos, + gint *end_pos); +gchar *g_match_info_fetch_named (const GMatchInfo *match_info, + const gchar *name); +gboolean g_match_info_fetch_named_pos (const GMatchInfo *match_info, + const gchar *name, + gint *start_pos, + gint *end_pos); +gchar **g_match_info_fetch_all (const GMatchInfo *match_info); + +G_END_DECLS + +#endif /* __G_REGEX_H__ */ diff --git a/glib/glib/gscanner.c b/glib/glib/gscanner.c new file mode 100644 index 0000000..c933e6d --- /dev/null +++ b/glib/glib/gscanner.c @@ -0,0 +1,2260 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GScanner: Flexible lexical scanner for general purpose. + * Copyright (C) 1997, 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +#include "gscanner.h" + +#include "gprintfint.h" +#include "gstrfuncs.h" +#include "gstring.h" +#include "gtestutils.h" + +#ifdef G_OS_WIN32 +#include /* For _read() */ +#endif + + +/** + * SECTION:scanner + * @title: Lexical Scanner + * @short_description: a general purpose lexical scanner + * + * The #GScanner and its associated functions provide a + * general purpose lexical scanner. + */ + +/** + * GScannerMsgFunc: + * @scanner: a #GScanner + * @message: the message + * @error: %TRUE if the message signals an error, + * %FALSE if it signals a warning. + * + * Specifies the type of the message handler function. + */ + +/** + * G_CSET_a_2_z: + * + * The set of lowercase ASCII alphabet characters. + * Used for specifying valid identifier characters + * in #GScannerConfig. + */ + +/** + * G_CSET_A_2_Z: + * + * The set of uppercase ASCII alphabet characters. + * Used for specifying valid identifier characters + * in #GScannerConfig. + */ + +/** + * G_CSET_LATINC: + * + * The set of uppercase ISO 8859-1 alphabet characters + * which are not ASCII characters. + * Used for specifying valid identifier characters + * in #GScannerConfig. + */ + +/** + * G_CSET_LATINS: + * + * The set of lowercase ISO 8859-1 alphabet characters + * which are not ASCII characters. + * Used for specifying valid identifier characters + * in #GScannerConfig. + */ + +/** + * GTokenType: + * @G_TOKEN_EOF: the end of the file + * @G_TOKEN_LEFT_PAREN: a '(' character + * @G_TOKEN_LEFT_CURLY: a '{' character + * @G_TOKEN_LEFT_BRACE: a '[' character + * @G_TOKEN_RIGHT_CURLY: a '}' character + * @G_TOKEN_RIGHT_PAREN: a ')' character + * @G_TOKEN_RIGHT_BRACE: a ']' character + * @G_TOKEN_EQUAL_SIGN: a '=' character + * @G_TOKEN_COMMA: a ',' character + * @G_TOKEN_NONE: not a token + * @G_TOKEN_ERROR: an error occurred + * @G_TOKEN_CHAR: a character + * @G_TOKEN_BINARY: a binary integer + * @G_TOKEN_OCTAL: an octal integer + * @G_TOKEN_INT: an integer + * @G_TOKEN_HEX: a hex integer + * @G_TOKEN_FLOAT: a floating point number + * @G_TOKEN_STRING: a string + * @G_TOKEN_SYMBOL: a symbol + * @G_TOKEN_IDENTIFIER: an identifier + * @G_TOKEN_IDENTIFIER_NULL: a null identifier + * @G_TOKEN_COMMENT_SINGLE: one line comment + * @G_TOKEN_COMMENT_MULTI: multi line comment + * + * The possible types of token returned from each + * g_scanner_get_next_token() call. + */ + +/** + * GTokenValue: + * @v_symbol: token symbol value + * @v_identifier: token identifier value + * @v_binary: token binary integer value + * @v_octal: octal integer value + * @v_int: integer value + * @v_int64: 64-bit integer value + * @v_float: floating point value + * @v_hex: hex integer value + * @v_string: string value + * @v_comment: comment value + * @v_char: character value + * @v_error: error value + * + * A union holding the value of the token. + */ + +/** + * GErrorType: + * @G_ERR_UNKNOWN: unknown error + * @G_ERR_UNEXP_EOF: unexpected end of file + * @G_ERR_UNEXP_EOF_IN_STRING: unterminated string constant + * @G_ERR_UNEXP_EOF_IN_COMMENT: unterminated comment + * @G_ERR_NON_DIGIT_IN_CONST: non-digit character in a number + * @G_ERR_DIGIT_RADIX: digit beyond radix in a number + * @G_ERR_FLOAT_RADIX: non-decimal floating point number + * @G_ERR_FLOAT_MALFORMED: malformed floating point number + * + * The possible errors, used in the @v_error field + * of #GTokenValue, when the token is a %G_TOKEN_ERROR. + */ + +/** + * GScanner: + * @user_data: unused + * @max_parse_errors: unused + * @parse_errors: g_scanner_error() increments this field + * @input_name: name of input stream, featured by the default message handler + * @qdata: quarked data + * @config: link into the scanner configuration + * @token: token parsed by the last g_scanner_get_next_token() + * @value: value of the last token from g_scanner_get_next_token() + * @line: line number of the last token from g_scanner_get_next_token() + * @position: char number of the last token from g_scanner_get_next_token() + * @next_token: token parsed by the last g_scanner_peek_next_token() + * @next_value: value of the last token from g_scanner_peek_next_token() + * @next_line: line number of the last token from g_scanner_peek_next_token() + * @next_position: char number of the last token from g_scanner_peek_next_token() + * @msg_handler: handler function for _warn and _error + * + * The data structure representing a lexical scanner. + * + * You should set @input_name after creating the scanner, since + * it is used by the default message handler when displaying + * warnings and errors. If you are scanning a file, the filename + * would be a good choice. + * + * The @user_data and @max_parse_errors fields are not used. + * If you need to associate extra data with the scanner you + * can place them here. + * + * If you want to use your own message handler you can set the + * @msg_handler field. The type of the message handler function + * is declared by #GScannerMsgFunc. + */ + +/** + * GScannerConfig: + * @cset_skip_characters: specifies which characters should be skipped + * by the scanner (the default is the whitespace characters: space, + * tab, carriage-return and line-feed). + * @cset_identifier_first: specifies the characters which can start + * identifiers (the default is #G_CSET_a_2_z, "_", and #G_CSET_A_2_Z). + * @cset_identifier_nth: specifies the characters which can be used + * in identifiers, after the first character (the default is + * #G_CSET_a_2_z, "_0123456789", #G_CSET_A_2_Z, #G_CSET_LATINS, + * #G_CSET_LATINC). + * @cpair_comment_single: specifies the characters at the start and + * end of single-line comments. The default is "#\n" which means + * that single-line comments start with a '#' and continue until + * a '\n' (end of line). + * @case_sensitive: specifies if symbols are case sensitive (the + * default is %FALSE). + * @skip_comment_multi: specifies if multi-line comments are skipped + * and not returned as tokens (the default is %TRUE). + * @skip_comment_single: specifies if single-line comments are skipped + * and not returned as tokens (the default is %TRUE). + * @scan_comment_multi: specifies if multi-line comments are recognized + * (the default is %TRUE). + * @scan_identifier: specifies if identifiers are recognized (the + * default is %TRUE). + * @scan_identifier_1char: specifies if single-character + * identifiers are recognized (the default is %FALSE). + * @scan_identifier_NULL: specifies if %NULL is reported as + * %G_TOKEN_IDENTIFIER_NULL (the default is %FALSE). + * @scan_symbols: specifies if symbols are recognized (the default + * is %TRUE). + * @scan_binary: specifies if binary numbers are recognized (the + * default is %FALSE). + * @scan_octal: specifies if octal numbers are recognized (the + * default is %TRUE). + * @scan_float: specifies if floating point numbers are recognized + * (the default is %TRUE). + * @scan_hex: specifies if hexadecimal numbers are recognized (the + * default is %TRUE). + * @scan_hex_dollar: specifies if '$' is recognized as a prefix for + * hexadecimal numbers (the default is %FALSE). + * @scan_string_sq: specifies if strings can be enclosed in single + * quotes (the default is %TRUE). + * @scan_string_dq: specifies if strings can be enclosed in double + * quotes (the default is %TRUE). + * @numbers_2_int: specifies if binary, octal and hexadecimal numbers + * are reported as #G_TOKEN_INT (the default is %TRUE). + * @int_2_float: specifies if all numbers are reported as %G_TOKEN_FLOAT + * (the default is %FALSE). + * @identifier_2_string: specifies if identifiers are reported as strings + * (the default is %FALSE). + * @char_2_token: specifies if characters are reported by setting + * token = ch or as %G_TOKEN_CHAR (the default + * is %TRUE). + * @symbol_2_token: specifies if symbols are reported by setting + * token = v_symbol or as %G_TOKEN_SYMBOL (the + * default is %FALSE). + * @scope_0_fallback: specifies if a symbol is searched for in the + * default scope in addition to the current scope (the default is %FALSE). + * @store_int64: use value.v_int64 rather than v_int + * + * Specifies the #GScanner parser configuration. Most settings can + * be changed during the parsing phase and will affect the lexical + * parsing of the next unpeeked token. + */ + +/* --- defines --- */ +#define to_lower(c) ( \ + (guchar) ( \ + ( (((guchar)(c))>='A' && ((guchar)(c))<='Z') * ('a'-'A') ) | \ + ( (((guchar)(c))>=192 && ((guchar)(c))<=214) * (224-192) ) | \ + ( (((guchar)(c))>=216 && ((guchar)(c))<=222) * (248-216) ) | \ + ((guchar)(c)) \ + ) \ +) +#define READ_BUFFER_SIZE (4000) + + +/* --- typedefs --- */ +typedef struct _GScannerKey GScannerKey; + +struct _GScannerKey +{ + guint scope_id; + gchar *symbol; + gpointer value; +}; + + +/* --- variables --- */ +static const GScannerConfig g_scanner_config_template = +{ + ( + " \t\r\n" + ) /* cset_skip_characters */, + ( + G_CSET_a_2_z + "_" + G_CSET_A_2_Z + ) /* cset_identifier_first */, + ( + G_CSET_a_2_z + "_" + G_CSET_A_2_Z + G_CSET_DIGITS + G_CSET_LATINS + G_CSET_LATINC + ) /* cset_identifier_nth */, + ( "#\n" ) /* cpair_comment_single */, + + FALSE /* case_sensitive */, + + TRUE /* skip_comment_multi */, + TRUE /* skip_comment_single */, + TRUE /* scan_comment_multi */, + TRUE /* scan_identifier */, + FALSE /* scan_identifier_1char */, + FALSE /* scan_identifier_NULL */, + TRUE /* scan_symbols */, + FALSE /* scan_binary */, + TRUE /* scan_octal */, + TRUE /* scan_float */, + TRUE /* scan_hex */, + FALSE /* scan_hex_dollar */, + TRUE /* scan_string_sq */, + TRUE /* scan_string_dq */, + TRUE /* numbers_2_int */, + FALSE /* int_2_float */, + FALSE /* identifier_2_string */, + TRUE /* char_2_token */, + FALSE /* symbol_2_token */, + FALSE /* scope_0_fallback */, + FALSE /* store_int64 */, +}; + + +/* --- prototypes --- */ +static inline +GScannerKey* g_scanner_lookup_internal (GScanner *scanner, + guint scope_id, + const gchar *symbol); +static gboolean g_scanner_key_equal (gconstpointer v1, + gconstpointer v2); +static guint g_scanner_key_hash (gconstpointer v); +static void g_scanner_get_token_ll (GScanner *scanner, + GTokenType *token_p, + GTokenValue *value_p, + guint *line_p, + guint *position_p); +static void g_scanner_get_token_i (GScanner *scanner, + GTokenType *token_p, + GTokenValue *value_p, + guint *line_p, + guint *position_p); + +static guchar g_scanner_peek_next_char (GScanner *scanner); +static guchar g_scanner_get_char (GScanner *scanner, + guint *line_p, + guint *position_p); +static void g_scanner_msg_handler (GScanner *scanner, + gchar *message, + gboolean is_error); + + +/* --- functions --- */ +static inline gint +g_scanner_char_2_num (guchar c, + guchar base) +{ + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A' - 10; + else if (c >= 'a' && c <= 'z') + c -= 'a' - 10; + else + return -1; + + if (c < base) + return c; + + return -1; +} + +/** + * g_scanner_new: + * @config_templ: the initial scanner settings + * + * Creates a new #GScanner. + * + * The @config_templ structure specifies the initial settings + * of the scanner, which are copied into the #GScanner + * @config field. If you pass %NULL then the default settings + * are used. + * + * Returns: the new #GScanner + */ +GScanner * +g_scanner_new (const GScannerConfig *config_templ) +{ + GScanner *scanner; + + if (!config_templ) + config_templ = &g_scanner_config_template; + + scanner = g_new0 (GScanner, 1); + + scanner->user_data = NULL; + scanner->max_parse_errors = 1; + scanner->parse_errors = 0; + scanner->input_name = NULL; + g_datalist_init (&scanner->qdata); + + scanner->config = g_new0 (GScannerConfig, 1); + + scanner->config->case_sensitive = config_templ->case_sensitive; + scanner->config->cset_skip_characters = config_templ->cset_skip_characters; + if (!scanner->config->cset_skip_characters) + scanner->config->cset_skip_characters = ""; + scanner->config->cset_identifier_first = config_templ->cset_identifier_first; + scanner->config->cset_identifier_nth = config_templ->cset_identifier_nth; + scanner->config->cpair_comment_single = config_templ->cpair_comment_single; + scanner->config->skip_comment_multi = config_templ->skip_comment_multi; + scanner->config->skip_comment_single = config_templ->skip_comment_single; + scanner->config->scan_comment_multi = config_templ->scan_comment_multi; + scanner->config->scan_identifier = config_templ->scan_identifier; + scanner->config->scan_identifier_1char = config_templ->scan_identifier_1char; + scanner->config->scan_identifier_NULL = config_templ->scan_identifier_NULL; + scanner->config->scan_symbols = config_templ->scan_symbols; + scanner->config->scan_binary = config_templ->scan_binary; + scanner->config->scan_octal = config_templ->scan_octal; + scanner->config->scan_float = config_templ->scan_float; + scanner->config->scan_hex = config_templ->scan_hex; + scanner->config->scan_hex_dollar = config_templ->scan_hex_dollar; + scanner->config->scan_string_sq = config_templ->scan_string_sq; + scanner->config->scan_string_dq = config_templ->scan_string_dq; + scanner->config->numbers_2_int = config_templ->numbers_2_int; + scanner->config->int_2_float = config_templ->int_2_float; + scanner->config->identifier_2_string = config_templ->identifier_2_string; + scanner->config->char_2_token = config_templ->char_2_token; + scanner->config->symbol_2_token = config_templ->symbol_2_token; + scanner->config->scope_0_fallback = config_templ->scope_0_fallback; + scanner->config->store_int64 = config_templ->store_int64; + + scanner->token = G_TOKEN_NONE; + scanner->value.v_int64 = 0; + scanner->line = 1; + scanner->position = 0; + + scanner->next_token = G_TOKEN_NONE; + scanner->next_value.v_int64 = 0; + scanner->next_line = 1; + scanner->next_position = 0; + + scanner->symbol_table = g_hash_table_new (g_scanner_key_hash, g_scanner_key_equal); + scanner->input_fd = -1; + scanner->text = NULL; + scanner->text_end = NULL; + scanner->buffer = NULL; + scanner->scope_id = 0; + + scanner->msg_handler = g_scanner_msg_handler; + + return scanner; +} + +static inline void +g_scanner_free_value (GTokenType *token_p, + GTokenValue *value_p) +{ + switch (*token_p) + { + case G_TOKEN_STRING: + case G_TOKEN_IDENTIFIER: + case G_TOKEN_IDENTIFIER_NULL: + case G_TOKEN_COMMENT_SINGLE: + case G_TOKEN_COMMENT_MULTI: + g_free (value_p->v_string); + break; + + default: + break; + } + + *token_p = G_TOKEN_NONE; +} + +static void +g_scanner_destroy_symbol_table_entry (gpointer _key, + gpointer _value, + gpointer _data) +{ + GScannerKey *key = _key; + + g_free (key->symbol); + g_free (key); +} + +/** + * g_scanner_destroy: + * @scanner: a #GScanner + * + * Frees all memory used by the #GScanner. + */ +void +g_scanner_destroy (GScanner *scanner) +{ + g_return_if_fail (scanner != NULL); + + g_datalist_clear (&scanner->qdata); + g_hash_table_foreach (scanner->symbol_table, + g_scanner_destroy_symbol_table_entry, NULL); + g_hash_table_destroy (scanner->symbol_table); + g_scanner_free_value (&scanner->token, &scanner->value); + g_scanner_free_value (&scanner->next_token, &scanner->next_value); + g_free (scanner->config); + g_free (scanner->buffer); + g_free (scanner); +} + +static void +g_scanner_msg_handler (GScanner *scanner, + gchar *message, + gboolean is_error) +{ + g_return_if_fail (scanner != NULL); + + _g_fprintf (stderr, "%s:%d: ", + scanner->input_name ? scanner->input_name : "", + scanner->line); + if (is_error) + _g_fprintf (stderr, "error: "); + _g_fprintf (stderr, "%s\n", message); +} + +/** + * g_scanner_error: + * @scanner: a #GScanner + * @format: the message format. See the printf() documentation + * @...: the parameters to insert into the format string + * + * Outputs an error message, via the #GScanner message handler. + */ +void +g_scanner_error (GScanner *scanner, + const gchar *format, + ...) +{ + g_return_if_fail (scanner != NULL); + g_return_if_fail (format != NULL); + + scanner->parse_errors++; + + if (scanner->msg_handler) + { + va_list args; + gchar *string; + + va_start (args, format); + string = g_strdup_vprintf (format, args); + va_end (args); + + scanner->msg_handler (scanner, string, TRUE); + + g_free (string); + } +} + +/** + * g_scanner_warn: + * @scanner: a #GScanner + * @format: the message format. See the printf() documentation + * @...: the parameters to insert into the format string + * + * Outputs a warning message, via the #GScanner message handler. + */ +void +g_scanner_warn (GScanner *scanner, + const gchar *format, + ...) +{ + g_return_if_fail (scanner != NULL); + g_return_if_fail (format != NULL); + + if (scanner->msg_handler) + { + va_list args; + gchar *string; + + va_start (args, format); + string = g_strdup_vprintf (format, args); + va_end (args); + + scanner->msg_handler (scanner, string, FALSE); + + g_free (string); + } +} + +static gboolean +g_scanner_key_equal (gconstpointer v1, + gconstpointer v2) +{ + const GScannerKey *key1 = v1; + const GScannerKey *key2 = v2; + + return (key1->scope_id == key2->scope_id) && (strcmp (key1->symbol, key2->symbol) == 0); +} + +static guint +g_scanner_key_hash (gconstpointer v) +{ + const GScannerKey *key = v; + gchar *c; + guint h; + + h = key->scope_id; + for (c = key->symbol; *c; c++) + h = (h << 5) - h + *c; + + return h; +} + +static inline GScannerKey* +g_scanner_lookup_internal (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + GScannerKey *key_p; + GScannerKey key; + + key.scope_id = scope_id; + + if (!scanner->config->case_sensitive) + { + gchar *d; + const gchar *c; + + key.symbol = g_new (gchar, strlen (symbol) + 1); + for (d = key.symbol, c = symbol; *c; c++, d++) + *d = to_lower (*c); + *d = 0; + key_p = g_hash_table_lookup (scanner->symbol_table, &key); + g_free (key.symbol); + } + else + { + key.symbol = (gchar*) symbol; + key_p = g_hash_table_lookup (scanner->symbol_table, &key); + } + + return key_p; +} + +/** + * g_scanner_add_symbol + * @scanner: a #GScanner + * @symbol: the symbol to add + * @value: the value of the symbol + * + * Adds a symbol to the default scope. + * + * Deprecated: 2.2: Use g_scanner_scope_add_symbol() instead. + */ + +/** + * g_scanner_scope_add_symbol: + * @scanner: a #GScanner + * @scope_id: the scope id + * @symbol: the symbol to add + * @value: the value of the symbol + * + * Adds a symbol to the given scope. + */ +void +g_scanner_scope_add_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol, + gpointer value) +{ + GScannerKey *key; + + g_return_if_fail (scanner != NULL); + g_return_if_fail (symbol != NULL); + + key = g_scanner_lookup_internal (scanner, scope_id, symbol); + + if (!key) + { + key = g_new (GScannerKey, 1); + key->scope_id = scope_id; + key->symbol = g_strdup (symbol); + key->value = value; + if (!scanner->config->case_sensitive) + { + gchar *c; + + c = key->symbol; + while (*c != 0) + { + *c = to_lower (*c); + c++; + } + } + g_hash_table_insert (scanner->symbol_table, key, key); + } + else + key->value = value; +} + +/** + * g_scanner_remove_symbol: + * @scanner: a #GScanner + * @symbol: the symbol to remove + * + * Removes a symbol from the default scope. + * + * Deprecated: 2.2: Use g_scanner_scope_remove_symbol() instead. + */ + +/** + * g_scanner_scope_remove_symbol: + * @scanner: a #GScanner + * @scope_id: the scope id + * @symbol: the symbol to remove + * + * Removes a symbol from a scope. + */ +void +g_scanner_scope_remove_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + GScannerKey *key; + + g_return_if_fail (scanner != NULL); + g_return_if_fail (symbol != NULL); + + key = g_scanner_lookup_internal (scanner, scope_id, symbol); + + if (key) + { + g_hash_table_remove (scanner->symbol_table, key); + g_free (key->symbol); + g_free (key); + } +} + +/** + * g_scanner_freeze_symbol_table: + * @scanner: a #GScanner + * + * There is no reason to use this macro, since it does nothing. + * + * Deprecated: 2.2: This macro does nothing. + */ + +/** + * g_scanner_thaw_symbol_table: + * @scanner: a #GScanner + * + * There is no reason to use this macro, since it does nothing. + * + * Deprecated: 2.2: This macro does nothing. + */ + +/** + * g_scanner_lookup_symbol: + * @scanner: a #GScanner + * @symbol: the symbol to look up + * + * Looks up a symbol in the current scope and return its value. + * If the symbol is not bound in the current scope, %NULL is + * returned. + * + * Returns: the value of @symbol in the current scope, or %NULL + * if @symbol is not bound in the current scope + */ +gpointer +g_scanner_lookup_symbol (GScanner *scanner, + const gchar *symbol) +{ + GScannerKey *key; + guint scope_id; + + g_return_val_if_fail (scanner != NULL, NULL); + + if (!symbol) + return NULL; + + scope_id = scanner->scope_id; + key = g_scanner_lookup_internal (scanner, scope_id, symbol); + if (!key && scope_id && scanner->config->scope_0_fallback) + key = g_scanner_lookup_internal (scanner, 0, symbol); + + if (key) + return key->value; + else + return NULL; +} + +/** + * g_scanner_scope_lookup_symbol: + * @scanner: a #GScanner + * @scope_id: the scope id + * @symbol: the symbol to look up + * + * Looks up a symbol in a scope and return its value. If the + * symbol is not bound in the scope, %NULL is returned. + * + * Returns: the value of @symbol in the given scope, or %NULL + * if @symbol is not bound in the given scope. + * + */ +gpointer +g_scanner_scope_lookup_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol) +{ + GScannerKey *key; + + g_return_val_if_fail (scanner != NULL, NULL); + + if (!symbol) + return NULL; + + key = g_scanner_lookup_internal (scanner, scope_id, symbol); + + if (key) + return key->value; + else + return NULL; +} + +/** + * g_scanner_set_scope: + * @scanner: a #GScanner + * @scope_id: the new scope id + * + * Sets the current scope. + * + * Returns: the old scope id + */ +guint +g_scanner_set_scope (GScanner *scanner, + guint scope_id) +{ + guint old_scope_id; + + g_return_val_if_fail (scanner != NULL, 0); + + old_scope_id = scanner->scope_id; + scanner->scope_id = scope_id; + + return old_scope_id; +} + +static void +g_scanner_foreach_internal (gpointer _key, + gpointer _value, + gpointer _user_data) +{ + GScannerKey *key; + gpointer *d; + GHFunc func; + gpointer user_data; + guint *scope_id; + + d = _user_data; + func = (GHFunc) d[0]; + user_data = d[1]; + scope_id = d[2]; + key = _value; + + if (key->scope_id == *scope_id) + func (key->symbol, key->value, user_data); +} + +/** + * g_scanner_foreach_symbol: + * @scanner: a #GScanner + * @func: the function to call with each symbol + * @data: data to pass to the function + * + * Calls a function for each symbol in the default scope. + * + * Deprecated: 2.2: Use g_scanner_scope_foreach_symbol() instead. + */ + +/** + * g_scanner_scope_foreach_symbol: + * @scanner: a #GScanner + * @scope_id: the scope id + * @func: the function to call for each symbol/value pair + * @user_data: user data to pass to the function + * + * Calls the given function for each of the symbol/value pairs + * in the given scope of the #GScanner. The function is passed + * the symbol and value of each pair, and the given @user_data + * parameter. + */ +void +g_scanner_scope_foreach_symbol (GScanner *scanner, + guint scope_id, + GHFunc func, + gpointer user_data) +{ + gpointer d[3]; + + g_return_if_fail (scanner != NULL); + + d[0] = (gpointer) func; + d[1] = user_data; + d[2] = &scope_id; + + g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d); +} + +/** + * g_scanner_peek_next_token: + * @scanner: a #GScanner + * + * Parses the next token, without removing it from the input stream. + * The token data is placed in the @next_token, @next_value, @next_line, + * and @next_position fields of the #GScanner structure. + * + * Note that, while the token is not removed from the input stream + * (i.e. the next call to g_scanner_get_next_token() will return the + * same token), it will not be reevaluated. This can lead to surprising + * results when changing scope or the scanner configuration after peeking + * the next token. Getting the next token after switching the scope or + * configuration will return whatever was peeked before, regardless of + * any symbols that may have been added or removed in the new scope. + * + * Returns: the type of the token + */ +GTokenType +g_scanner_peek_next_token (GScanner *scanner) +{ + g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF); + + if (scanner->next_token == G_TOKEN_NONE) + { + scanner->next_line = scanner->line; + scanner->next_position = scanner->position; + g_scanner_get_token_i (scanner, + &scanner->next_token, + &scanner->next_value, + &scanner->next_line, + &scanner->next_position); + } + + return scanner->next_token; +} + +/** + * g_scanner_get_next_token: + * @scanner: a #GScanner + * + * Parses the next token just like g_scanner_peek_next_token() + * and also removes it from the input stream. The token data is + * placed in the @token, @value, @line, and @position fields of + * the #GScanner structure. + * + * Returns: the type of the token + */ +GTokenType +g_scanner_get_next_token (GScanner *scanner) +{ + g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF); + + if (scanner->next_token != G_TOKEN_NONE) + { + g_scanner_free_value (&scanner->token, &scanner->value); + + scanner->token = scanner->next_token; + scanner->value = scanner->next_value; + scanner->line = scanner->next_line; + scanner->position = scanner->next_position; + scanner->next_token = G_TOKEN_NONE; + } + else + g_scanner_get_token_i (scanner, + &scanner->token, + &scanner->value, + &scanner->line, + &scanner->position); + + return scanner->token; +} + +/** + * g_scanner_cur_token: + * @scanner: a #GScanner + * + * Gets the current token type. This is simply the @token + * field in the #GScanner structure. + * + * Returns: the current token type + */ +GTokenType +g_scanner_cur_token (GScanner *scanner) +{ + g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF); + + return scanner->token; +} + +/** + * g_scanner_cur_value: + * @scanner: a #GScanner + * + * Gets the current token value. This is simply the @value + * field in the #GScanner structure. + * + * Returns: the current token value + */ +GTokenValue +g_scanner_cur_value (GScanner *scanner) +{ + GTokenValue v; + + v.v_int64 = 0; + + g_return_val_if_fail (scanner != NULL, v); + + /* MSC isn't capable of handling return scanner->value; ? */ + + v = scanner->value; + + return v; +} + +/** + * g_scanner_cur_line: + * @scanner: a #GScanner + * + * Returns the current line in the input stream (counting + * from 1). This is the line of the last token parsed via + * g_scanner_get_next_token(). + * + * Returns: the current line + */ +guint +g_scanner_cur_line (GScanner *scanner) +{ + g_return_val_if_fail (scanner != NULL, 0); + + return scanner->line; +} + +/** + * g_scanner_cur_position: + * @scanner: a #GScanner + * + * Returns the current position in the current line (counting + * from 0). This is the position of the last token parsed via + * g_scanner_get_next_token(). + * + * Returns: the current position on the line + */ +guint +g_scanner_cur_position (GScanner *scanner) +{ + g_return_val_if_fail (scanner != NULL, 0); + + return scanner->position; +} + +/** + * g_scanner_eof: + * @scanner: a #GScanner + * + * Returns %TRUE if the scanner has reached the end of + * the file or text buffer. + * + * Returns: %TRUE if the scanner has reached the end of + * the file or text buffer + */ +gboolean +g_scanner_eof (GScanner *scanner) +{ + g_return_val_if_fail (scanner != NULL, TRUE); + + return scanner->token == G_TOKEN_EOF || scanner->token == G_TOKEN_ERROR; +} + +/** + * g_scanner_input_file: + * @scanner: a #GScanner + * @input_fd: a file descriptor + * + * Prepares to scan a file. + */ +void +g_scanner_input_file (GScanner *scanner, + gint input_fd) +{ + g_return_if_fail (scanner != NULL); + g_return_if_fail (input_fd >= 0); + + if (scanner->input_fd >= 0) + g_scanner_sync_file_offset (scanner); + + scanner->token = G_TOKEN_NONE; + scanner->value.v_int64 = 0; + scanner->line = 1; + scanner->position = 0; + scanner->next_token = G_TOKEN_NONE; + + scanner->input_fd = input_fd; + scanner->text = NULL; + scanner->text_end = NULL; + + if (!scanner->buffer) + scanner->buffer = g_new (gchar, READ_BUFFER_SIZE + 1); +} + +/** + * g_scanner_input_text: + * @scanner: a #GScanner + * @text: the text buffer to scan + * @text_len: the length of the text buffer + * + * Prepares to scan a text buffer. + */ +void +g_scanner_input_text (GScanner *scanner, + const gchar *text, + guint text_len) +{ + g_return_if_fail (scanner != NULL); + if (text_len) + g_return_if_fail (text != NULL); + else + text = NULL; + + if (scanner->input_fd >= 0) + g_scanner_sync_file_offset (scanner); + + scanner->token = G_TOKEN_NONE; + scanner->value.v_int64 = 0; + scanner->line = 1; + scanner->position = 0; + scanner->next_token = G_TOKEN_NONE; + + scanner->input_fd = -1; + scanner->text = text; + scanner->text_end = text + text_len; + + if (scanner->buffer) + { + g_free (scanner->buffer); + scanner->buffer = NULL; + } +} + +static guchar +g_scanner_peek_next_char (GScanner *scanner) +{ + if (scanner->text < scanner->text_end) + { + return *scanner->text; + } + else if (scanner->input_fd >= 0) + { + gint count; + gchar *buffer; + + buffer = scanner->buffer; + do + { + count = read (scanner->input_fd, buffer, READ_BUFFER_SIZE); + } + while (count == -1 && (errno == EINTR || errno == EAGAIN)); + + if (count < 1) + { + scanner->input_fd = -1; + + return 0; + } + else + { + scanner->text = buffer; + scanner->text_end = buffer + count; + + return *buffer; + } + } + else + return 0; +} + +/** + * g_scanner_sync_file_offset: + * @scanner: a #GScanner + * + * Rewinds the filedescriptor to the current buffer position + * and blows the file read ahead buffer. This is useful for + * third party uses of the scanners filedescriptor, which hooks + * onto the current scanning position. + */ +void +g_scanner_sync_file_offset (GScanner *scanner) +{ + g_return_if_fail (scanner != NULL); + + /* for file input, rewind the filedescriptor to the current + * buffer position and blow the file read ahead buffer. useful + * for third party uses of our file descriptor, which hooks + * onto the current scanning position. + */ + + if (scanner->input_fd >= 0 && scanner->text_end > scanner->text) + { + gint buffered; + + buffered = scanner->text_end - scanner->text; + if (lseek (scanner->input_fd, - buffered, SEEK_CUR) >= 0) + { + /* we succeeded, blow our buffer's contents now */ + scanner->text = NULL; + scanner->text_end = NULL; + } + else + errno = 0; + } +} + +static guchar +g_scanner_get_char (GScanner *scanner, + guint *line_p, + guint *position_p) +{ + guchar fchar; + + if (scanner->text < scanner->text_end) + fchar = *(scanner->text++); + else if (scanner->input_fd >= 0) + { + gint count; + gchar *buffer; + + buffer = scanner->buffer; + do + { + count = read (scanner->input_fd, buffer, READ_BUFFER_SIZE); + } + while (count == -1 && (errno == EINTR || errno == EAGAIN)); + + if (count < 1) + { + scanner->input_fd = -1; + fchar = 0; + } + else + { + scanner->text = buffer + 1; + scanner->text_end = buffer + count; + fchar = *buffer; + if (!fchar) + { + g_scanner_sync_file_offset (scanner); + scanner->text_end = scanner->text; + scanner->input_fd = -1; + } + } + } + else + fchar = 0; + + if (fchar == '\n') + { + (*position_p) = 0; + (*line_p)++; + } + else if (fchar) + { + (*position_p)++; + } + + return fchar; +} + +/** + * g_scanner_unexp_token: + * @scanner: a #GScanner + * @expected_token: the expected token + * @identifier_spec: a string describing how the scanner's user + * refers to identifiers (%NULL defaults to "identifier"). + * This is used if @expected_token is %G_TOKEN_IDENTIFIER or + * %G_TOKEN_IDENTIFIER_NULL. + * @symbol_spec: a string describing how the scanner's user refers + * to symbols (%NULL defaults to "symbol"). This is used if + * @expected_token is %G_TOKEN_SYMBOL or any token value greater + * than %G_TOKEN_LAST. + * @symbol_name: the name of the symbol, if the scanner's current + * token is a symbol. + * @message: a message string to output at the end of the + * warning/error, or %NULL. + * @is_error: if %TRUE it is output as an error. If %FALSE it is + * output as a warning. + * + * Outputs a message through the scanner's msg_handler, + * resulting from an unexpected token in the input stream. + * Note that you should not call g_scanner_peek_next_token() + * followed by g_scanner_unexp_token() without an intermediate + * call to g_scanner_get_next_token(), as g_scanner_unexp_token() + * evaluates the scanner's current token (not the peeked token) + * to construct part of the message. + */ +void +g_scanner_unexp_token (GScanner *scanner, + GTokenType expected_token, + const gchar *identifier_spec, + const gchar *symbol_spec, + const gchar *symbol_name, + const gchar *message, + gint is_error) +{ + gchar *token_string; + guint token_string_len; + gchar *expected_string; + guint expected_string_len; + gchar *message_prefix; + gboolean print_unexp; + void (*msg_handler) (GScanner*, const gchar*, ...); + + g_return_if_fail (scanner != NULL); + + if (is_error) + msg_handler = g_scanner_error; + else + msg_handler = g_scanner_warn; + + if (!identifier_spec) + identifier_spec = "identifier"; + if (!symbol_spec) + symbol_spec = "symbol"; + + token_string_len = 56; + token_string = g_new (gchar, token_string_len + 1); + expected_string_len = 64; + expected_string = g_new (gchar, expected_string_len + 1); + print_unexp = TRUE; + + switch (scanner->token) + { + case G_TOKEN_EOF: + _g_snprintf (token_string, token_string_len, "end of file"); + break; + + default: + if (scanner->token >= 1 && scanner->token <= 255) + { + if ((scanner->token >= ' ' && scanner->token <= '~') || + strchr (scanner->config->cset_identifier_first, scanner->token) || + strchr (scanner->config->cset_identifier_nth, scanner->token)) + _g_snprintf (token_string, token_string_len, "character `%c'", scanner->token); + else + _g_snprintf (token_string, token_string_len, "character `\\%o'", scanner->token); + break; + } + else if (!scanner->config->symbol_2_token) + { + _g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token); + break; + } + /* fall through */ + case G_TOKEN_SYMBOL: + if (expected_token == G_TOKEN_SYMBOL || + (scanner->config->symbol_2_token && + expected_token > G_TOKEN_LAST)) + print_unexp = FALSE; + if (symbol_name) + _g_snprintf (token_string, + token_string_len, + "%s%s `%s'", + print_unexp ? "" : "invalid ", + symbol_spec, + symbol_name); + else + _g_snprintf (token_string, + token_string_len, + "%s%s", + print_unexp ? "" : "invalid ", + symbol_spec); + break; + + case G_TOKEN_ERROR: + print_unexp = FALSE; + expected_token = G_TOKEN_NONE; + switch (scanner->value.v_error) + { + case G_ERR_UNEXP_EOF: + _g_snprintf (token_string, token_string_len, "scanner: unexpected end of file"); + break; + + case G_ERR_UNEXP_EOF_IN_STRING: + _g_snprintf (token_string, token_string_len, "scanner: unterminated string constant"); + break; + + case G_ERR_UNEXP_EOF_IN_COMMENT: + _g_snprintf (token_string, token_string_len, "scanner: unterminated comment"); + break; + + case G_ERR_NON_DIGIT_IN_CONST: + _g_snprintf (token_string, token_string_len, "scanner: non digit in constant"); + break; + + case G_ERR_FLOAT_RADIX: + _g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant"); + break; + + case G_ERR_FLOAT_MALFORMED: + _g_snprintf (token_string, token_string_len, "scanner: malformed floating constant"); + break; + + case G_ERR_DIGIT_RADIX: + _g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix"); + break; + + case G_ERR_UNKNOWN: + default: + _g_snprintf (token_string, token_string_len, "scanner: unknown error"); + break; + } + break; + + case G_TOKEN_CHAR: + _g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char); + break; + + case G_TOKEN_IDENTIFIER: + case G_TOKEN_IDENTIFIER_NULL: + if (expected_token == G_TOKEN_IDENTIFIER || + expected_token == G_TOKEN_IDENTIFIER_NULL) + print_unexp = FALSE; + _g_snprintf (token_string, + token_string_len, + "%s%s `%s'", + print_unexp ? "" : "invalid ", + identifier_spec, + scanner->token == G_TOKEN_IDENTIFIER ? scanner->value.v_string : "null"); + break; + + case G_TOKEN_BINARY: + case G_TOKEN_OCTAL: + case G_TOKEN_INT: + case G_TOKEN_HEX: + if (scanner->config->store_int64) + _g_snprintf (token_string, token_string_len, "number `%" G_GUINT64_FORMAT "'", scanner->value.v_int64); + else + _g_snprintf (token_string, token_string_len, "number `%lu'", scanner->value.v_int); + break; + + case G_TOKEN_FLOAT: + _g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float); + break; + + case G_TOKEN_STRING: + if (expected_token == G_TOKEN_STRING) + print_unexp = FALSE; + _g_snprintf (token_string, + token_string_len, + "%s%sstring constant \"%s\"", + print_unexp ? "" : "invalid ", + scanner->value.v_string[0] == 0 ? "empty " : "", + scanner->value.v_string); + token_string[token_string_len - 2] = '"'; + token_string[token_string_len - 1] = 0; + break; + + case G_TOKEN_COMMENT_SINGLE: + case G_TOKEN_COMMENT_MULTI: + _g_snprintf (token_string, token_string_len, "comment"); + break; + + case G_TOKEN_NONE: + /* somehow the user's parsing code is screwed, there isn't much + * we can do about it. + * Note, a common case to trigger this is + * g_scanner_peek_next_token(); g_scanner_unexp_token(); + * without an intermediate g_scanner_get_next_token(). + */ + g_assert_not_reached (); + break; + } + + + switch (expected_token) + { + gboolean need_valid; + gchar *tstring; + case G_TOKEN_EOF: + _g_snprintf (expected_string, expected_string_len, "end of file"); + break; + default: + if (expected_token >= 1 && expected_token <= 255) + { + if ((expected_token >= ' ' && expected_token <= '~') || + strchr (scanner->config->cset_identifier_first, expected_token) || + strchr (scanner->config->cset_identifier_nth, expected_token)) + _g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token); + else + _g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token); + break; + } + else if (!scanner->config->symbol_2_token) + { + _g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token); + break; + } + /* fall through */ + case G_TOKEN_SYMBOL: + need_valid = (scanner->token == G_TOKEN_SYMBOL || + (scanner->config->symbol_2_token && + scanner->token > G_TOKEN_LAST)); + _g_snprintf (expected_string, + expected_string_len, + "%s%s", + need_valid ? "valid " : "", + symbol_spec); + /* FIXME: should we attempt to lookup the symbol_name for symbol_2_token? */ + break; + case G_TOKEN_CHAR: + _g_snprintf (expected_string, expected_string_len, "%scharacter", + scanner->token == G_TOKEN_CHAR ? "valid " : ""); + break; + case G_TOKEN_BINARY: + tstring = "binary"; + _g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_OCTAL: + tstring = "octal"; + _g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_INT: + tstring = "integer"; + _g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_HEX: + tstring = "hexadecimal"; + _g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_FLOAT: + tstring = "float"; + _g_snprintf (expected_string, expected_string_len, "%snumber (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_STRING: + _g_snprintf (expected_string, + expected_string_len, + "%sstring constant", + scanner->token == G_TOKEN_STRING ? "valid " : ""); + break; + case G_TOKEN_IDENTIFIER: + case G_TOKEN_IDENTIFIER_NULL: + need_valid = (scanner->token == G_TOKEN_IDENTIFIER_NULL || + scanner->token == G_TOKEN_IDENTIFIER); + _g_snprintf (expected_string, + expected_string_len, + "%s%s", + need_valid ? "valid " : "", + identifier_spec); + break; + case G_TOKEN_COMMENT_SINGLE: + tstring = "single-line"; + _g_snprintf (expected_string, expected_string_len, "%scomment (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_COMMENT_MULTI: + tstring = "multi-line"; + _g_snprintf (expected_string, expected_string_len, "%scomment (%s)", + scanner->token == expected_token ? "valid " : "", tstring); + break; + case G_TOKEN_NONE: + case G_TOKEN_ERROR: + /* this is handled upon printout */ + break; + } + + if (message && message[0] != 0) + message_prefix = " - "; + else + { + message_prefix = ""; + message = ""; + } + if (expected_token == G_TOKEN_ERROR) + { + msg_handler (scanner, + "failure around %s%s%s", + token_string, + message_prefix, + message); + } + else if (expected_token == G_TOKEN_NONE) + { + if (print_unexp) + msg_handler (scanner, + "unexpected %s%s%s", + token_string, + message_prefix, + message); + else + msg_handler (scanner, + "%s%s%s", + token_string, + message_prefix, + message); + } + else + { + if (print_unexp) + msg_handler (scanner, + "unexpected %s, expected %s%s%s", + token_string, + expected_string, + message_prefix, + message); + else + msg_handler (scanner, + "%s, expected %s%s%s", + token_string, + expected_string, + message_prefix, + message); + } + + g_free (token_string); + g_free (expected_string); +} + +static void +g_scanner_get_token_i (GScanner *scanner, + GTokenType *token_p, + GTokenValue *value_p, + guint *line_p, + guint *position_p) +{ + do + { + g_scanner_free_value (token_p, value_p); + g_scanner_get_token_ll (scanner, token_p, value_p, line_p, position_p); + } + while (((*token_p > 0 && *token_p < 256) && + strchr (scanner->config->cset_skip_characters, *token_p)) || + (*token_p == G_TOKEN_CHAR && + strchr (scanner->config->cset_skip_characters, value_p->v_char)) || + (*token_p == G_TOKEN_COMMENT_MULTI && + scanner->config->skip_comment_multi) || + (*token_p == G_TOKEN_COMMENT_SINGLE && + scanner->config->skip_comment_single)); + + switch (*token_p) + { + case G_TOKEN_IDENTIFIER: + if (scanner->config->identifier_2_string) + *token_p = G_TOKEN_STRING; + break; + + case G_TOKEN_SYMBOL: + if (scanner->config->symbol_2_token) + *token_p = (GTokenType) value_p->v_symbol; + break; + + case G_TOKEN_BINARY: + case G_TOKEN_OCTAL: + case G_TOKEN_HEX: + if (scanner->config->numbers_2_int) + *token_p = G_TOKEN_INT; + break; + + default: + break; + } + + if (*token_p == G_TOKEN_INT && + scanner->config->int_2_float) + { + *token_p = G_TOKEN_FLOAT; + if (scanner->config->store_int64) + { +#ifdef _MSC_VER + /* work around error C2520, see gvaluetransform.c */ + value_p->v_float = (__int64)value_p->v_int64; +#else + value_p->v_float = value_p->v_int64; +#endif + } + else + value_p->v_float = value_p->v_int; + } + + errno = 0; +} + +static void +g_scanner_get_token_ll (GScanner *scanner, + GTokenType *token_p, + GTokenValue *value_p, + guint *line_p, + guint *position_p) +{ + GScannerConfig *config; + GTokenType token; + gboolean in_comment_multi; + gboolean in_comment_single; + gboolean in_string_sq; + gboolean in_string_dq; + GString *gstring; + GTokenValue value; + guchar ch; + + config = scanner->config; + (*value_p).v_int64 = 0; + + if ((scanner->text >= scanner->text_end && scanner->input_fd < 0) || + scanner->token == G_TOKEN_EOF) + { + *token_p = G_TOKEN_EOF; + return; + } + + in_comment_multi = FALSE; + in_comment_single = FALSE; + in_string_sq = FALSE; + in_string_dq = FALSE; + gstring = NULL; + + do /* while (ch != 0) */ + { + gboolean dotted_float = FALSE; + + ch = g_scanner_get_char (scanner, line_p, position_p); + + value.v_int64 = 0; + token = G_TOKEN_NONE; + + /* this is *evil*, but needed ;( + * we first check for identifier first character, because it + * might interfere with other key chars like slashes or numbers + */ + if (config->scan_identifier && + ch && strchr (config->cset_identifier_first, ch)) + goto identifier_precedence; + + switch (ch) + { + case 0: + token = G_TOKEN_EOF; + (*position_p)++; + /* ch = 0; */ + break; + + case '/': + if (!config->scan_comment_multi || + g_scanner_peek_next_char (scanner) != '*') + goto default_case; + g_scanner_get_char (scanner, line_p, position_p); + token = G_TOKEN_COMMENT_MULTI; + in_comment_multi = TRUE; + gstring = g_string_new (NULL); + while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0) + { + if (ch == '*' && g_scanner_peek_next_char (scanner) == '/') + { + g_scanner_get_char (scanner, line_p, position_p); + in_comment_multi = FALSE; + break; + } + else + gstring = g_string_append_c (gstring, ch); + } + ch = 0; + break; + + case '\'': + if (!config->scan_string_sq) + goto default_case; + token = G_TOKEN_STRING; + in_string_sq = TRUE; + gstring = g_string_new (NULL); + while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0) + { + if (ch == '\'') + { + in_string_sq = FALSE; + break; + } + else + gstring = g_string_append_c (gstring, ch); + } + ch = 0; + break; + + case '"': + if (!config->scan_string_dq) + goto default_case; + token = G_TOKEN_STRING; + in_string_dq = TRUE; + gstring = g_string_new (NULL); + while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0) + { + if (ch == '"') + { + in_string_dq = FALSE; + break; + } + else + { + if (ch == '\\') + { + ch = g_scanner_get_char (scanner, line_p, position_p); + switch (ch) + { + guint i; + guint fchar; + + case 0: + break; + + case '\\': + gstring = g_string_append_c (gstring, '\\'); + break; + + case 'n': + gstring = g_string_append_c (gstring, '\n'); + break; + + case 't': + gstring = g_string_append_c (gstring, '\t'); + break; + + case 'r': + gstring = g_string_append_c (gstring, '\r'); + break; + + case 'b': + gstring = g_string_append_c (gstring, '\b'); + break; + + case 'f': + gstring = g_string_append_c (gstring, '\f'); + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + i = ch - '0'; + fchar = g_scanner_peek_next_char (scanner); + if (fchar >= '0' && fchar <= '7') + { + ch = g_scanner_get_char (scanner, line_p, position_p); + i = i * 8 + ch - '0'; + fchar = g_scanner_peek_next_char (scanner); + if (fchar >= '0' && fchar <= '7') + { + ch = g_scanner_get_char (scanner, line_p, position_p); + i = i * 8 + ch - '0'; + } + } + gstring = g_string_append_c (gstring, i); + break; + + default: + gstring = g_string_append_c (gstring, ch); + break; + } + } + else + gstring = g_string_append_c (gstring, ch); + } + } + ch = 0; + break; + + case '.': + if (!config->scan_float) + goto default_case; + token = G_TOKEN_FLOAT; + dotted_float = TRUE; + ch = g_scanner_get_char (scanner, line_p, position_p); + goto number_parsing; + + case '$': + if (!config->scan_hex_dollar) + goto default_case; + token = G_TOKEN_HEX; + ch = g_scanner_get_char (scanner, line_p, position_p); + goto number_parsing; + + case '0': + if (config->scan_octal) + token = G_TOKEN_OCTAL; + else + token = G_TOKEN_INT; + ch = g_scanner_peek_next_char (scanner); + if (config->scan_hex && (ch == 'x' || ch == 'X')) + { + token = G_TOKEN_HEX; + g_scanner_get_char (scanner, line_p, position_p); + ch = g_scanner_get_char (scanner, line_p, position_p); + if (ch == 0) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_UNEXP_EOF; + (*position_p)++; + break; + } + if (g_scanner_char_2_num (ch, 16) < 0) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_DIGIT_RADIX; + ch = 0; + break; + } + } + else if (config->scan_binary && (ch == 'b' || ch == 'B')) + { + token = G_TOKEN_BINARY; + g_scanner_get_char (scanner, line_p, position_p); + ch = g_scanner_get_char (scanner, line_p, position_p); + if (ch == 0) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_UNEXP_EOF; + (*position_p)++; + break; + } + if (g_scanner_char_2_num (ch, 10) < 0) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + ch = 0; + break; + } + } + else + ch = '0'; + /* fall through */ + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + number_parsing: + { + gboolean in_number = TRUE; + gchar *endptr; + + if (token == G_TOKEN_NONE) + token = G_TOKEN_INT; + + gstring = g_string_new (dotted_float ? "0." : ""); + gstring = g_string_append_c (gstring, ch); + + do /* while (in_number) */ + { + gboolean is_E; + + is_E = token == G_TOKEN_FLOAT && (ch == 'e' || ch == 'E'); + + ch = g_scanner_peek_next_char (scanner); + + if (g_scanner_char_2_num (ch, 36) >= 0 || + (config->scan_float && ch == '.') || + (is_E && (ch == '+' || ch == '-'))) + { + ch = g_scanner_get_char (scanner, line_p, position_p); + + switch (ch) + { + case '.': + if (token != G_TOKEN_INT && token != G_TOKEN_OCTAL) + { + value.v_error = token == G_TOKEN_FLOAT ? G_ERR_FLOAT_MALFORMED : G_ERR_FLOAT_RADIX; + token = G_TOKEN_ERROR; + in_number = FALSE; + } + else + { + token = G_TOKEN_FLOAT; + gstring = g_string_append_c (gstring, ch); + } + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + gstring = g_string_append_c (gstring, ch); + break; + + case '-': + case '+': + if (token != G_TOKEN_FLOAT) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + in_number = FALSE; + } + else + gstring = g_string_append_c (gstring, ch); + break; + + case 'e': + case 'E': + if ((token != G_TOKEN_HEX && !config->scan_float) || + (token != G_TOKEN_HEX && + token != G_TOKEN_OCTAL && + token != G_TOKEN_FLOAT && + token != G_TOKEN_INT)) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + in_number = FALSE; + } + else + { + if (token != G_TOKEN_HEX) + token = G_TOKEN_FLOAT; + gstring = g_string_append_c (gstring, ch); + } + break; + + default: + if (token != G_TOKEN_HEX) + { + token = G_TOKEN_ERROR; + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + in_number = FALSE; + } + else + gstring = g_string_append_c (gstring, ch); + break; + } + } + else + in_number = FALSE; + } + while (in_number); + + endptr = NULL; + if (token == G_TOKEN_FLOAT) + value.v_float = g_strtod (gstring->str, &endptr); + else + { + guint64 ui64 = 0; + switch (token) + { + case G_TOKEN_BINARY: + ui64 = g_ascii_strtoull (gstring->str, &endptr, 2); + break; + case G_TOKEN_OCTAL: + ui64 = g_ascii_strtoull (gstring->str, &endptr, 8); + break; + case G_TOKEN_INT: + ui64 = g_ascii_strtoull (gstring->str, &endptr, 10); + break; + case G_TOKEN_HEX: + ui64 = g_ascii_strtoull (gstring->str, &endptr, 16); + break; + default: ; + } + if (scanner->config->store_int64) + value.v_int64 = ui64; + else + value.v_int = ui64; + } + if (endptr && *endptr) + { + token = G_TOKEN_ERROR; + if (*endptr == 'e' || *endptr == 'E') + value.v_error = G_ERR_NON_DIGIT_IN_CONST; + else + value.v_error = G_ERR_DIGIT_RADIX; + } + g_string_free (gstring, TRUE); + gstring = NULL; + ch = 0; + } /* number_parsing:... */ + break; + + default: + default_case: + { + if (config->cpair_comment_single && + ch == config->cpair_comment_single[0]) + { + token = G_TOKEN_COMMENT_SINGLE; + in_comment_single = TRUE; + gstring = g_string_new (NULL); + ch = g_scanner_get_char (scanner, line_p, position_p); + while (ch != 0) + { + if (ch == config->cpair_comment_single[1]) + { + in_comment_single = FALSE; + ch = 0; + break; + } + + gstring = g_string_append_c (gstring, ch); + ch = g_scanner_get_char (scanner, line_p, position_p); + } + /* ignore a missing newline at EOF for single line comments */ + if (in_comment_single && + config->cpair_comment_single[1] == '\n') + in_comment_single = FALSE; + } + else if (config->scan_identifier && ch && + strchr (config->cset_identifier_first, ch)) + { + identifier_precedence: + + if (config->cset_identifier_nth && ch && + strchr (config->cset_identifier_nth, + g_scanner_peek_next_char (scanner))) + { + token = G_TOKEN_IDENTIFIER; + gstring = g_string_new (NULL); + gstring = g_string_append_c (gstring, ch); + do + { + ch = g_scanner_get_char (scanner, line_p, position_p); + gstring = g_string_append_c (gstring, ch); + ch = g_scanner_peek_next_char (scanner); + } + while (ch && strchr (config->cset_identifier_nth, ch)); + ch = 0; + } + else if (config->scan_identifier_1char) + { + token = G_TOKEN_IDENTIFIER; + value.v_identifier = g_new0 (gchar, 2); + value.v_identifier[0] = ch; + ch = 0; + } + } + if (ch) + { + if (config->char_2_token) + token = ch; + else + { + token = G_TOKEN_CHAR; + value.v_char = ch; + } + ch = 0; + } + } /* default_case:... */ + break; + } + g_assert (ch == 0 && token != G_TOKEN_NONE); /* paranoid */ + } + while (ch != 0); + + if (in_comment_multi || in_comment_single || + in_string_sq || in_string_dq) + { + token = G_TOKEN_ERROR; + if (gstring) + { + g_string_free (gstring, TRUE); + gstring = NULL; + } + (*position_p)++; + if (in_comment_multi || in_comment_single) + value.v_error = G_ERR_UNEXP_EOF_IN_COMMENT; + else /* (in_string_sq || in_string_dq) */ + value.v_error = G_ERR_UNEXP_EOF_IN_STRING; + } + + if (gstring) + { + value.v_string = g_string_free (gstring, FALSE); + gstring = NULL; + } + + if (token == G_TOKEN_IDENTIFIER) + { + if (config->scan_symbols) + { + GScannerKey *key; + guint scope_id; + + scope_id = scanner->scope_id; + key = g_scanner_lookup_internal (scanner, scope_id, value.v_identifier); + if (!key && scope_id && scanner->config->scope_0_fallback) + key = g_scanner_lookup_internal (scanner, 0, value.v_identifier); + + if (key) + { + g_free (value.v_identifier); + token = G_TOKEN_SYMBOL; + value.v_symbol = key->value; + } + } + + if (token == G_TOKEN_IDENTIFIER && + config->scan_identifier_NULL && + strlen (value.v_identifier) == 4) + { + gchar *null_upper = "NULL"; + gchar *null_lower = "null"; + + if (scanner->config->case_sensitive) + { + if (value.v_identifier[0] == null_upper[0] && + value.v_identifier[1] == null_upper[1] && + value.v_identifier[2] == null_upper[2] && + value.v_identifier[3] == null_upper[3]) + token = G_TOKEN_IDENTIFIER_NULL; + } + else + { + if ((value.v_identifier[0] == null_upper[0] || + value.v_identifier[0] == null_lower[0]) && + (value.v_identifier[1] == null_upper[1] || + value.v_identifier[1] == null_lower[1]) && + (value.v_identifier[2] == null_upper[2] || + value.v_identifier[2] == null_lower[2]) && + (value.v_identifier[3] == null_upper[3] || + value.v_identifier[3] == null_lower[3])) + token = G_TOKEN_IDENTIFIER_NULL; + } + } + } + + *token_p = token; + *value_p = value; +} diff --git a/glib/glib/gscanner.h b/glib/glib/gscanner.h new file mode 100644 index 0000000..dd932f4 --- /dev/null +++ b/glib/glib/gscanner.h @@ -0,0 +1,284 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_SCANNER_H__ +#define __G_SCANNER_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GScanner GScanner; +typedef struct _GScannerConfig GScannerConfig; +typedef union _GTokenValue GTokenValue; + +typedef void (*GScannerMsgFunc) (GScanner *scanner, + gchar *message, + gboolean error); + +/* GScanner: Flexible lexical scanner for general purpose. + */ + +/* Character sets */ +#define G_CSET_A_2_Z "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define G_CSET_a_2_z "abcdefghijklmnopqrstuvwxyz" +#define G_CSET_DIGITS "0123456789" +#define G_CSET_LATINC "\300\301\302\303\304\305\306"\ + "\307\310\311\312\313\314\315\316\317\320"\ + "\321\322\323\324\325\326"\ + "\330\331\332\333\334\335\336" +#define G_CSET_LATINS "\337\340\341\342\343\344\345\346"\ + "\347\350\351\352\353\354\355\356\357\360"\ + "\361\362\363\364\365\366"\ + "\370\371\372\373\374\375\376\377" + +/* Error types */ +typedef enum +{ + G_ERR_UNKNOWN, + G_ERR_UNEXP_EOF, + G_ERR_UNEXP_EOF_IN_STRING, + G_ERR_UNEXP_EOF_IN_COMMENT, + G_ERR_NON_DIGIT_IN_CONST, + G_ERR_DIGIT_RADIX, + G_ERR_FLOAT_RADIX, + G_ERR_FLOAT_MALFORMED +} GErrorType; + +/* Token types */ +typedef enum +{ + G_TOKEN_EOF = 0, + + G_TOKEN_LEFT_PAREN = '(', + G_TOKEN_RIGHT_PAREN = ')', + G_TOKEN_LEFT_CURLY = '{', + G_TOKEN_RIGHT_CURLY = '}', + G_TOKEN_LEFT_BRACE = '[', + G_TOKEN_RIGHT_BRACE = ']', + G_TOKEN_EQUAL_SIGN = '=', + G_TOKEN_COMMA = ',', + + G_TOKEN_NONE = 256, + + G_TOKEN_ERROR, + + G_TOKEN_CHAR, + G_TOKEN_BINARY, + G_TOKEN_OCTAL, + G_TOKEN_INT, + G_TOKEN_HEX, + G_TOKEN_FLOAT, + G_TOKEN_STRING, + + G_TOKEN_SYMBOL, + G_TOKEN_IDENTIFIER, + G_TOKEN_IDENTIFIER_NULL, + + G_TOKEN_COMMENT_SINGLE, + G_TOKEN_COMMENT_MULTI, + + /*< private >*/ + G_TOKEN_LAST +} GTokenType; + +union _GTokenValue +{ + gpointer v_symbol; + gchar *v_identifier; + gulong v_binary; + gulong v_octal; + gulong v_int; + guint64 v_int64; + gdouble v_float; + gulong v_hex; + gchar *v_string; + gchar *v_comment; + guchar v_char; + guint v_error; +}; + +struct _GScannerConfig +{ + /* Character sets + */ + gchar *cset_skip_characters; /* default: " \t\n" */ + gchar *cset_identifier_first; + gchar *cset_identifier_nth; + gchar *cpair_comment_single; /* default: "#\n" */ + + /* Should symbol lookup work case sensitive? + */ + guint case_sensitive : 1; + + /* Boolean values to be adjusted "on the fly" + * to configure scanning behaviour. + */ + guint skip_comment_multi : 1; /* C like comment */ + guint skip_comment_single : 1; /* single line comment */ + guint scan_comment_multi : 1; /* scan multi line comments? */ + guint scan_identifier : 1; + guint scan_identifier_1char : 1; + guint scan_identifier_NULL : 1; + guint scan_symbols : 1; + guint scan_binary : 1; + guint scan_octal : 1; + guint scan_float : 1; + guint scan_hex : 1; /* `0x0ff0' */ + guint scan_hex_dollar : 1; /* `$0ff0' */ + guint scan_string_sq : 1; /* string: 'anything' */ + guint scan_string_dq : 1; /* string: "\\-escapes!\n" */ + guint numbers_2_int : 1; /* bin, octal, hex => int */ + guint int_2_float : 1; /* int => G_TOKEN_FLOAT? */ + guint identifier_2_string : 1; + guint char_2_token : 1; /* return G_TOKEN_CHAR? */ + guint symbol_2_token : 1; + guint scope_0_fallback : 1; /* try scope 0 on lookups? */ + guint store_int64 : 1; /* use value.v_int64 rather than v_int */ + + /*< private >*/ + guint padding_dummy; +}; + +struct _GScanner +{ + /* unused fields */ + gpointer user_data; + guint max_parse_errors; + + /* g_scanner_error() increments this field */ + guint parse_errors; + + /* name of input stream, featured by the default message handler */ + const gchar *input_name; + + /* quarked data */ + GData *qdata; + + /* link into the scanner configuration */ + GScannerConfig *config; + + /* fields filled in after g_scanner_get_next_token() */ + GTokenType token; + GTokenValue value; + guint line; + guint position; + + /* fields filled in after g_scanner_peek_next_token() */ + GTokenType next_token; + GTokenValue next_value; + guint next_line; + guint next_position; + + /*< private >*/ + /* to be considered private */ + GHashTable *symbol_table; + gint input_fd; + const gchar *text; + const gchar *text_end; + gchar *buffer; + guint scope_id; + + /*< public >*/ + /* handler function for _warn and _error */ + GScannerMsgFunc msg_handler; +}; + +GScanner* g_scanner_new (const GScannerConfig *config_templ); +void g_scanner_destroy (GScanner *scanner); +void g_scanner_input_file (GScanner *scanner, + gint input_fd); +void g_scanner_sync_file_offset (GScanner *scanner); +void g_scanner_input_text (GScanner *scanner, + const gchar *text, + guint text_len); +GTokenType g_scanner_get_next_token (GScanner *scanner); +GTokenType g_scanner_peek_next_token (GScanner *scanner); +GTokenType g_scanner_cur_token (GScanner *scanner); +GTokenValue g_scanner_cur_value (GScanner *scanner); +guint g_scanner_cur_line (GScanner *scanner); +guint g_scanner_cur_position (GScanner *scanner); +gboolean g_scanner_eof (GScanner *scanner); +guint g_scanner_set_scope (GScanner *scanner, + guint scope_id); +void g_scanner_scope_add_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol, + gpointer value); +void g_scanner_scope_remove_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol); +gpointer g_scanner_scope_lookup_symbol (GScanner *scanner, + guint scope_id, + const gchar *symbol); +void g_scanner_scope_foreach_symbol (GScanner *scanner, + guint scope_id, + GHFunc func, + gpointer user_data); +gpointer g_scanner_lookup_symbol (GScanner *scanner, + const gchar *symbol); +void g_scanner_unexp_token (GScanner *scanner, + GTokenType expected_token, + const gchar *identifier_spec, + const gchar *symbol_spec, + const gchar *symbol_name, + const gchar *message, + gint is_error); +void g_scanner_error (GScanner *scanner, + const gchar *format, + ...) G_GNUC_PRINTF (2,3); +void g_scanner_warn (GScanner *scanner, + const gchar *format, + ...) G_GNUC_PRINTF (2,3); + +#ifndef G_DISABLE_DEPRECATED + +/* keep downward source compatibility */ +#define g_scanner_add_symbol( scanner, symbol, value ) G_STMT_START { \ + g_scanner_scope_add_symbol ((scanner), 0, (symbol), (value)); \ +} G_STMT_END +#define g_scanner_remove_symbol( scanner, symbol ) G_STMT_START { \ + g_scanner_scope_remove_symbol ((scanner), 0, (symbol)); \ +} G_STMT_END +#define g_scanner_foreach_symbol( scanner, func, data ) G_STMT_START { \ + g_scanner_scope_foreach_symbol ((scanner), 0, (func), (data)); \ +} G_STMT_END + +/* The following two functions are deprecated and will be removed in + * the next major release. They do no good. */ +#define g_scanner_freeze_symbol_table(scanner) ((void)0) +#define g_scanner_thaw_symbol_table(scanner) ((void)0) + +#endif /* G_DISABLE_DEPRECATED */ + +G_END_DECLS + +#endif /* __G_SCANNER_H__ */ diff --git a/glib/glib/gscripttable.h b/glib/glib/gscripttable.h new file mode 100644 index 0000000..80f9c9c --- /dev/null +++ b/glib/glib/gscripttable.h @@ -0,0 +1,3120 @@ +/* gscripttable.h: Generated by gen-script-table.pl + * + * Date: Fri Feb 10 17:20:57 2012 + * Source: Scripts-6.1.0.txt + * + * Do not edit. + */ + +#define G_EASY_SCRIPTS_RANGE 8192 + +static const guchar g_script_easy_table[8192] = { + + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_BOPOMOFO, + G_UNICODE_SCRIPT_BOPOMOFO, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, + G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, + G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, + G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, + G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARMENIAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, + G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, + G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, + G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_SAMARITAN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_MANDAIC, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_MANDAIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, + G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, + G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, + G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, + G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, + G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, + G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, + G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, + G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, + G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, + G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, + G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, + G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_RUNIC, + G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGALOG, + G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, + G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, + G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, + G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, + G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, + G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, + G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, + G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, + G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, + G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, + G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, + G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, + G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, + G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, + G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, + G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, + G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, + G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, + G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGBANWA, + G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, + G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, + G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, + G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, + G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGBANWA, + G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, + G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, + G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BUGINESE, + G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, + G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_TAI_THAM, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, + G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_BATAK, + G_UNICODE_SCRIPT_BATAK, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_CYRILLIC, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, + G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, + G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, +}; + +static const struct { + gunichar start; + guint16 chars; + guint16 script; +} g_script_table[] = { + { 0x2000, 12, G_UNICODE_SCRIPT_COMMON }, + { 0x200c, 2, G_UNICODE_SCRIPT_INHERITED }, + { 0x200e, 87, G_UNICODE_SCRIPT_COMMON }, + { 0x206a, 7, G_UNICODE_SCRIPT_COMMON }, + { 0x2071, 1, G_UNICODE_SCRIPT_LATIN }, + { 0x2074, 11, G_UNICODE_SCRIPT_COMMON }, + { 0x207f, 1, G_UNICODE_SCRIPT_LATIN }, + { 0x2080, 15, G_UNICODE_SCRIPT_COMMON }, + { 0x2090, 13, G_UNICODE_SCRIPT_LATIN }, + { 0x20a0, 26, G_UNICODE_SCRIPT_COMMON }, + { 0x20d0, 33, G_UNICODE_SCRIPT_INHERITED }, + { 0x2100, 38, G_UNICODE_SCRIPT_COMMON }, + { 0x2126, 1, G_UNICODE_SCRIPT_GREEK }, + { 0x2127, 3, G_UNICODE_SCRIPT_COMMON }, + { 0x212a, 2, G_UNICODE_SCRIPT_LATIN }, + { 0x212c, 6, G_UNICODE_SCRIPT_COMMON }, + { 0x2132, 1, G_UNICODE_SCRIPT_LATIN }, + { 0x2133, 27, G_UNICODE_SCRIPT_COMMON }, + { 0x214e, 1, G_UNICODE_SCRIPT_LATIN }, + { 0x214f, 17, G_UNICODE_SCRIPT_COMMON }, + { 0x2160, 41, G_UNICODE_SCRIPT_LATIN }, + { 0x2189, 1, G_UNICODE_SCRIPT_COMMON }, + { 0x2190, 612, G_UNICODE_SCRIPT_COMMON }, + { 0x2400, 39, G_UNICODE_SCRIPT_COMMON }, + { 0x2440, 11, G_UNICODE_SCRIPT_COMMON }, + { 0x2460, 672, G_UNICODE_SCRIPT_COMMON }, + { 0x2701, 255, G_UNICODE_SCRIPT_COMMON }, + { 0x2800, 256, G_UNICODE_SCRIPT_BRAILLE }, + { 0x2900, 589, G_UNICODE_SCRIPT_COMMON }, + { 0x2b50, 10, G_UNICODE_SCRIPT_COMMON }, + { 0x2c00, 47, G_UNICODE_SCRIPT_GLAGOLITIC }, + { 0x2c30, 47, G_UNICODE_SCRIPT_GLAGOLITIC }, + { 0x2c60, 32, G_UNICODE_SCRIPT_LATIN }, + { 0x2c80, 116, G_UNICODE_SCRIPT_COPTIC }, + { 0x2cf9, 7, G_UNICODE_SCRIPT_COPTIC }, + { 0x2d00, 38, G_UNICODE_SCRIPT_GEORGIAN }, + { 0x2d27, 1, G_UNICODE_SCRIPT_GEORGIAN }, + { 0x2d2d, 1, G_UNICODE_SCRIPT_GEORGIAN }, + { 0x2d30, 56, G_UNICODE_SCRIPT_TIFINAGH }, + { 0x2d6f, 2, G_UNICODE_SCRIPT_TIFINAGH }, + { 0x2d7f, 1, G_UNICODE_SCRIPT_TIFINAGH }, + { 0x2d80, 23, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2da0, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2da8, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2db0, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2db8, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2dc0, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2dc8, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2dd0, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2dd8, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0x2de0, 32, G_UNICODE_SCRIPT_CYRILLIC }, + { 0x2e00, 60, G_UNICODE_SCRIPT_COMMON }, + { 0x2e80, 26, G_UNICODE_SCRIPT_HAN }, + { 0x2e9b, 89, G_UNICODE_SCRIPT_HAN }, + { 0x2f00, 214, G_UNICODE_SCRIPT_HAN }, + { 0x2ff0, 12, G_UNICODE_SCRIPT_COMMON }, + { 0x3000, 5, G_UNICODE_SCRIPT_COMMON }, + { 0x3005, 1, G_UNICODE_SCRIPT_HAN }, + { 0x3006, 1, G_UNICODE_SCRIPT_COMMON }, + { 0x3007, 1, G_UNICODE_SCRIPT_HAN }, + { 0x3008, 25, G_UNICODE_SCRIPT_COMMON }, + { 0x3021, 9, G_UNICODE_SCRIPT_HAN }, + { 0x302a, 4, G_UNICODE_SCRIPT_INHERITED }, + { 0x302e, 2, G_UNICODE_SCRIPT_HANGUL }, + { 0x3030, 8, G_UNICODE_SCRIPT_COMMON }, + { 0x3038, 4, G_UNICODE_SCRIPT_HAN }, + { 0x303c, 4, G_UNICODE_SCRIPT_COMMON }, + { 0x3041, 86, G_UNICODE_SCRIPT_HIRAGANA }, + { 0x3099, 2, G_UNICODE_SCRIPT_INHERITED }, + { 0x309b, 2, G_UNICODE_SCRIPT_COMMON }, + { 0x309d, 3, G_UNICODE_SCRIPT_HIRAGANA }, + { 0x30a0, 1, G_UNICODE_SCRIPT_COMMON }, + { 0x30a1, 90, G_UNICODE_SCRIPT_KATAKANA }, + { 0x30fb, 2, G_UNICODE_SCRIPT_COMMON }, + { 0x30fd, 3, G_UNICODE_SCRIPT_KATAKANA }, + { 0x3105, 41, G_UNICODE_SCRIPT_BOPOMOFO }, + { 0x3131, 94, G_UNICODE_SCRIPT_HANGUL }, + { 0x3190, 16, G_UNICODE_SCRIPT_COMMON }, + { 0x31a0, 27, G_UNICODE_SCRIPT_BOPOMOFO }, + { 0x31c0, 36, G_UNICODE_SCRIPT_COMMON }, + { 0x31f0, 16, G_UNICODE_SCRIPT_KATAKANA }, + { 0x3200, 31, G_UNICODE_SCRIPT_HANGUL }, + { 0x3220, 64, G_UNICODE_SCRIPT_COMMON }, + { 0x3260, 31, G_UNICODE_SCRIPT_HANGUL }, + { 0x327f, 81, G_UNICODE_SCRIPT_COMMON }, + { 0x32d0, 47, G_UNICODE_SCRIPT_KATAKANA }, + { 0x3300, 88, G_UNICODE_SCRIPT_KATAKANA }, + { 0x3358, 168, G_UNICODE_SCRIPT_COMMON }, + { 0x3400, 6582, G_UNICODE_SCRIPT_HAN }, + { 0x4dc0, 64, G_UNICODE_SCRIPT_COMMON }, + { 0x4e00, 20941, G_UNICODE_SCRIPT_HAN }, + { 0xa000, 1165, G_UNICODE_SCRIPT_YI }, + { 0xa490, 55, G_UNICODE_SCRIPT_YI }, + { 0xa4d0, 48, G_UNICODE_SCRIPT_LISU }, + { 0xa500, 300, G_UNICODE_SCRIPT_VAI }, + { 0xa640, 88, G_UNICODE_SCRIPT_CYRILLIC }, + { 0xa69f, 1, G_UNICODE_SCRIPT_CYRILLIC }, + { 0xa6a0, 88, G_UNICODE_SCRIPT_BAMUM }, + { 0xa700, 34, G_UNICODE_SCRIPT_COMMON }, + { 0xa722, 102, G_UNICODE_SCRIPT_LATIN }, + { 0xa788, 3, G_UNICODE_SCRIPT_COMMON }, + { 0xa78b, 4, G_UNICODE_SCRIPT_LATIN }, + { 0xa790, 4, G_UNICODE_SCRIPT_LATIN }, + { 0xa7a0, 11, G_UNICODE_SCRIPT_LATIN }, + { 0xa7f8, 8, G_UNICODE_SCRIPT_LATIN }, + { 0xa800, 44, G_UNICODE_SCRIPT_SYLOTI_NAGRI }, + { 0xa830, 10, G_UNICODE_SCRIPT_COMMON }, + { 0xa840, 56, G_UNICODE_SCRIPT_PHAGS_PA }, + { 0xa880, 69, G_UNICODE_SCRIPT_SAURASHTRA }, + { 0xa8ce, 12, G_UNICODE_SCRIPT_SAURASHTRA }, + { 0xa8e0, 28, G_UNICODE_SCRIPT_DEVANAGARI }, + { 0xa900, 48, G_UNICODE_SCRIPT_KAYAH_LI }, + { 0xa930, 36, G_UNICODE_SCRIPT_REJANG }, + { 0xa95f, 1, G_UNICODE_SCRIPT_REJANG }, + { 0xa960, 29, G_UNICODE_SCRIPT_HANGUL }, + { 0xa980, 78, G_UNICODE_SCRIPT_JAVANESE }, + { 0xa9cf, 11, G_UNICODE_SCRIPT_JAVANESE }, + { 0xa9de, 2, G_UNICODE_SCRIPT_JAVANESE }, + { 0xaa00, 55, G_UNICODE_SCRIPT_CHAM }, + { 0xaa40, 14, G_UNICODE_SCRIPT_CHAM }, + { 0xaa50, 10, G_UNICODE_SCRIPT_CHAM }, + { 0xaa5c, 4, G_UNICODE_SCRIPT_CHAM }, + { 0xaa60, 28, G_UNICODE_SCRIPT_MYANMAR }, + { 0xaa80, 67, G_UNICODE_SCRIPT_TAI_VIET }, + { 0xaadb, 5, G_UNICODE_SCRIPT_TAI_VIET }, + { 0xaae0, 23, G_UNICODE_SCRIPT_MEETEI_MAYEK }, + { 0xab01, 6, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0xab09, 6, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0xab11, 6, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0xab20, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0xab28, 7, G_UNICODE_SCRIPT_ETHIOPIC }, + { 0xabc0, 46, G_UNICODE_SCRIPT_MEETEI_MAYEK }, + { 0xabf0, 10, G_UNICODE_SCRIPT_MEETEI_MAYEK }, + { 0xac00, 11172, G_UNICODE_SCRIPT_HANGUL }, + { 0xd7b0, 23, G_UNICODE_SCRIPT_HANGUL }, + { 0xd7cb, 49, G_UNICODE_SCRIPT_HANGUL }, + { 0xf900, 366, G_UNICODE_SCRIPT_HAN }, + { 0xfa70, 106, G_UNICODE_SCRIPT_HAN }, + { 0xfb00, 7, G_UNICODE_SCRIPT_LATIN }, + { 0xfb13, 5, G_UNICODE_SCRIPT_ARMENIAN }, + { 0xfb1d, 26, G_UNICODE_SCRIPT_HEBREW }, + { 0xfb38, 5, G_UNICODE_SCRIPT_HEBREW }, + { 0xfb3e, 1, G_UNICODE_SCRIPT_HEBREW }, + { 0xfb40, 2, G_UNICODE_SCRIPT_HEBREW }, + { 0xfb43, 2, G_UNICODE_SCRIPT_HEBREW }, + { 0xfb46, 10, G_UNICODE_SCRIPT_HEBREW }, + { 0xfb50, 114, G_UNICODE_SCRIPT_ARABIC }, + { 0xfbd3, 363, G_UNICODE_SCRIPT_ARABIC }, + { 0xfd3e, 2, G_UNICODE_SCRIPT_COMMON }, + { 0xfd50, 64, G_UNICODE_SCRIPT_ARABIC }, + { 0xfd92, 54, G_UNICODE_SCRIPT_ARABIC }, + { 0xfdf0, 13, G_UNICODE_SCRIPT_ARABIC }, + { 0xfdfd, 1, G_UNICODE_SCRIPT_COMMON }, + { 0xfe00, 16, G_UNICODE_SCRIPT_INHERITED }, + { 0xfe10, 10, G_UNICODE_SCRIPT_COMMON }, + { 0xfe20, 7, G_UNICODE_SCRIPT_INHERITED }, + { 0xfe30, 35, G_UNICODE_SCRIPT_COMMON }, + { 0xfe54, 19, G_UNICODE_SCRIPT_COMMON }, + { 0xfe68, 4, G_UNICODE_SCRIPT_COMMON }, + { 0xfe70, 5, G_UNICODE_SCRIPT_ARABIC }, + { 0xfe76, 135, G_UNICODE_SCRIPT_ARABIC }, + { 0xfeff, 1, G_UNICODE_SCRIPT_COMMON }, + { 0xff01, 32, G_UNICODE_SCRIPT_COMMON }, + { 0xff21, 26, G_UNICODE_SCRIPT_LATIN }, + { 0xff3b, 6, G_UNICODE_SCRIPT_COMMON }, + { 0xff41, 26, G_UNICODE_SCRIPT_LATIN }, + { 0xff5b, 11, G_UNICODE_SCRIPT_COMMON }, + { 0xff66, 10, G_UNICODE_SCRIPT_KATAKANA }, + { 0xff70, 1, G_UNICODE_SCRIPT_COMMON }, + { 0xff71, 45, G_UNICODE_SCRIPT_KATAKANA }, + { 0xff9e, 2, G_UNICODE_SCRIPT_COMMON }, + { 0xffa0, 31, G_UNICODE_SCRIPT_HANGUL }, + { 0xffc2, 6, G_UNICODE_SCRIPT_HANGUL }, + { 0xffca, 6, G_UNICODE_SCRIPT_HANGUL }, + { 0xffd2, 6, G_UNICODE_SCRIPT_HANGUL }, + { 0xffda, 3, G_UNICODE_SCRIPT_HANGUL }, + { 0xffe0, 7, G_UNICODE_SCRIPT_COMMON }, + { 0xffe8, 7, G_UNICODE_SCRIPT_COMMON }, + { 0xfff9, 5, G_UNICODE_SCRIPT_COMMON }, + { 0x10000, 12, G_UNICODE_SCRIPT_LINEAR_B }, + { 0x1000d, 26, G_UNICODE_SCRIPT_LINEAR_B }, + { 0x10028, 19, G_UNICODE_SCRIPT_LINEAR_B }, + { 0x1003c, 2, G_UNICODE_SCRIPT_LINEAR_B }, + { 0x1003f, 15, G_UNICODE_SCRIPT_LINEAR_B }, + { 0x10050, 14, G_UNICODE_SCRIPT_LINEAR_B }, + { 0x10080, 123, G_UNICODE_SCRIPT_LINEAR_B }, + { 0x10100, 3, G_UNICODE_SCRIPT_COMMON }, + { 0x10107, 45, G_UNICODE_SCRIPT_COMMON }, + { 0x10137, 9, G_UNICODE_SCRIPT_COMMON }, + { 0x10140, 75, G_UNICODE_SCRIPT_GREEK }, + { 0x10190, 12, G_UNICODE_SCRIPT_COMMON }, + { 0x101d0, 45, G_UNICODE_SCRIPT_COMMON }, + { 0x101fd, 1, G_UNICODE_SCRIPT_INHERITED }, + { 0x10280, 29, G_UNICODE_SCRIPT_LYCIAN }, + { 0x102a0, 49, G_UNICODE_SCRIPT_CARIAN }, + { 0x10300, 31, G_UNICODE_SCRIPT_OLD_ITALIC }, + { 0x10320, 4, G_UNICODE_SCRIPT_OLD_ITALIC }, + { 0x10330, 27, G_UNICODE_SCRIPT_GOTHIC }, + { 0x10380, 30, G_UNICODE_SCRIPT_UGARITIC }, + { 0x1039f, 1, G_UNICODE_SCRIPT_UGARITIC }, + { 0x103a0, 36, G_UNICODE_SCRIPT_OLD_PERSIAN }, + { 0x103c8, 14, G_UNICODE_SCRIPT_OLD_PERSIAN }, + { 0x10400, 80, G_UNICODE_SCRIPT_DESERET }, + { 0x10450, 48, G_UNICODE_SCRIPT_SHAVIAN }, + { 0x10480, 30, G_UNICODE_SCRIPT_OSMANYA }, + { 0x104a0, 10, G_UNICODE_SCRIPT_OSMANYA }, + { 0x10800, 6, G_UNICODE_SCRIPT_CYPRIOT }, + { 0x10808, 1, G_UNICODE_SCRIPT_CYPRIOT }, + { 0x1080a, 44, G_UNICODE_SCRIPT_CYPRIOT }, + { 0x10837, 2, G_UNICODE_SCRIPT_CYPRIOT }, + { 0x1083c, 1, G_UNICODE_SCRIPT_CYPRIOT }, + { 0x1083f, 1, G_UNICODE_SCRIPT_CYPRIOT }, + { 0x10840, 22, G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC }, + { 0x10857, 9, G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC }, + { 0x10900, 28, G_UNICODE_SCRIPT_PHOENICIAN }, + { 0x1091f, 1, G_UNICODE_SCRIPT_PHOENICIAN }, + { 0x10920, 26, G_UNICODE_SCRIPT_LYDIAN }, + { 0x1093f, 1, G_UNICODE_SCRIPT_LYDIAN }, + { 0x10980, 32, G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS }, + { 0x109a0, 24, G_UNICODE_SCRIPT_MEROITIC_CURSIVE }, + { 0x109be, 2, G_UNICODE_SCRIPT_MEROITIC_CURSIVE }, + { 0x10a00, 4, G_UNICODE_SCRIPT_KHAROSHTHI }, + { 0x10a05, 2, G_UNICODE_SCRIPT_KHAROSHTHI }, + { 0x10a0c, 8, G_UNICODE_SCRIPT_KHAROSHTHI }, + { 0x10a15, 3, G_UNICODE_SCRIPT_KHAROSHTHI }, + { 0x10a19, 27, G_UNICODE_SCRIPT_KHAROSHTHI }, + { 0x10a38, 3, G_UNICODE_SCRIPT_KHAROSHTHI }, + { 0x10a3f, 9, G_UNICODE_SCRIPT_KHAROSHTHI }, + { 0x10a50, 9, G_UNICODE_SCRIPT_KHAROSHTHI }, + { 0x10a60, 32, G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN }, + { 0x10b00, 54, G_UNICODE_SCRIPT_AVESTAN }, + { 0x10b39, 7, G_UNICODE_SCRIPT_AVESTAN }, + { 0x10b40, 22, G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN }, + { 0x10b58, 8, G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN }, + { 0x10b60, 19, G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI }, + { 0x10b78, 8, G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI }, + { 0x10c00, 73, G_UNICODE_SCRIPT_OLD_TURKIC }, + { 0x10e60, 31, G_UNICODE_SCRIPT_ARABIC }, + { 0x11000, 78, G_UNICODE_SCRIPT_BRAHMI }, + { 0x11052, 30, G_UNICODE_SCRIPT_BRAHMI }, + { 0x11080, 66, G_UNICODE_SCRIPT_KAITHI }, + { 0x110d0, 25, G_UNICODE_SCRIPT_SORA_SOMPENG }, + { 0x110f0, 10, G_UNICODE_SCRIPT_SORA_SOMPENG }, + { 0x11100, 53, G_UNICODE_SCRIPT_CHAKMA }, + { 0x11136, 14, G_UNICODE_SCRIPT_CHAKMA }, + { 0x11180, 73, G_UNICODE_SCRIPT_SHARADA }, + { 0x111d0, 10, G_UNICODE_SCRIPT_SHARADA }, + { 0x11680, 56, G_UNICODE_SCRIPT_TAKRI }, + { 0x116c0, 10, G_UNICODE_SCRIPT_TAKRI }, + { 0x12000, 879, G_UNICODE_SCRIPT_CUNEIFORM }, + { 0x12400, 99, G_UNICODE_SCRIPT_CUNEIFORM }, + { 0x12470, 4, G_UNICODE_SCRIPT_CUNEIFORM }, + { 0x13000, 1071, G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS }, + { 0x16800, 569, G_UNICODE_SCRIPT_BAMUM }, + { 0x16f00, 69, G_UNICODE_SCRIPT_MIAO }, + { 0x16f50, 47, G_UNICODE_SCRIPT_MIAO }, + { 0x16f8f, 17, G_UNICODE_SCRIPT_MIAO }, + { 0x1b000, 1, G_UNICODE_SCRIPT_KATAKANA }, + { 0x1b001, 1, G_UNICODE_SCRIPT_HIRAGANA }, + { 0x1d000, 246, G_UNICODE_SCRIPT_COMMON }, + { 0x1d100, 39, G_UNICODE_SCRIPT_COMMON }, + { 0x1d129, 62, G_UNICODE_SCRIPT_COMMON }, + { 0x1d167, 3, G_UNICODE_SCRIPT_INHERITED }, + { 0x1d16a, 17, G_UNICODE_SCRIPT_COMMON }, + { 0x1d17b, 8, G_UNICODE_SCRIPT_INHERITED }, + { 0x1d183, 2, G_UNICODE_SCRIPT_COMMON }, + { 0x1d185, 7, G_UNICODE_SCRIPT_INHERITED }, + { 0x1d18c, 30, G_UNICODE_SCRIPT_COMMON }, + { 0x1d1aa, 4, G_UNICODE_SCRIPT_INHERITED }, + { 0x1d1ae, 48, G_UNICODE_SCRIPT_COMMON }, + { 0x1d200, 70, G_UNICODE_SCRIPT_GREEK }, + { 0x1d300, 87, G_UNICODE_SCRIPT_COMMON }, + { 0x1d360, 18, G_UNICODE_SCRIPT_COMMON }, + { 0x1d400, 85, G_UNICODE_SCRIPT_COMMON }, + { 0x1d456, 71, G_UNICODE_SCRIPT_COMMON }, + { 0x1d49e, 2, G_UNICODE_SCRIPT_COMMON }, + { 0x1d4a2, 1, G_UNICODE_SCRIPT_COMMON }, + { 0x1d4a5, 2, G_UNICODE_SCRIPT_COMMON }, + { 0x1d4a9, 4, G_UNICODE_SCRIPT_COMMON }, + { 0x1d4ae, 12, G_UNICODE_SCRIPT_COMMON }, + { 0x1d4bb, 1, G_UNICODE_SCRIPT_COMMON }, + { 0x1d4bd, 7, G_UNICODE_SCRIPT_COMMON }, + { 0x1d4c5, 65, G_UNICODE_SCRIPT_COMMON }, + { 0x1d507, 4, G_UNICODE_SCRIPT_COMMON }, + { 0x1d50d, 8, G_UNICODE_SCRIPT_COMMON }, + { 0x1d516, 7, G_UNICODE_SCRIPT_COMMON }, + { 0x1d51e, 28, G_UNICODE_SCRIPT_COMMON }, + { 0x1d53b, 4, G_UNICODE_SCRIPT_COMMON }, + { 0x1d540, 5, G_UNICODE_SCRIPT_COMMON }, + { 0x1d546, 1, G_UNICODE_SCRIPT_COMMON }, + { 0x1d54a, 7, G_UNICODE_SCRIPT_COMMON }, + { 0x1d552, 340, G_UNICODE_SCRIPT_COMMON }, + { 0x1d6a8, 292, G_UNICODE_SCRIPT_COMMON }, + { 0x1d7ce, 50, G_UNICODE_SCRIPT_COMMON }, + { 0x1ee00, 4, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee05, 27, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee21, 2, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee24, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee27, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee29, 10, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee34, 4, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee39, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee3b, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee42, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee47, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee49, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee4b, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee4d, 3, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee51, 2, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee54, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee57, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee59, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee5b, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee5d, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee5f, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee61, 2, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee64, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee67, 4, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee6c, 7, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee74, 4, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee79, 4, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee7e, 1, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee80, 10, G_UNICODE_SCRIPT_ARABIC }, + { 0x1ee8b, 17, G_UNICODE_SCRIPT_ARABIC }, + { 0x1eea1, 3, G_UNICODE_SCRIPT_ARABIC }, + { 0x1eea5, 5, G_UNICODE_SCRIPT_ARABIC }, + { 0x1eeab, 17, G_UNICODE_SCRIPT_ARABIC }, + { 0x1eef0, 2, G_UNICODE_SCRIPT_ARABIC }, + { 0x1f000, 44, G_UNICODE_SCRIPT_COMMON }, + { 0x1f030, 100, G_UNICODE_SCRIPT_COMMON }, + { 0x1f0a0, 15, G_UNICODE_SCRIPT_COMMON }, + { 0x1f0b1, 14, G_UNICODE_SCRIPT_COMMON }, + { 0x1f0c1, 15, G_UNICODE_SCRIPT_COMMON }, + { 0x1f0d1, 15, G_UNICODE_SCRIPT_COMMON }, + { 0x1f100, 11, G_UNICODE_SCRIPT_COMMON }, + { 0x1f110, 31, G_UNICODE_SCRIPT_COMMON }, + { 0x1f130, 60, G_UNICODE_SCRIPT_COMMON }, + { 0x1f170, 43, G_UNICODE_SCRIPT_COMMON }, + { 0x1f1e6, 26, G_UNICODE_SCRIPT_COMMON }, + { 0x1f200, 1, G_UNICODE_SCRIPT_HIRAGANA }, + { 0x1f201, 2, G_UNICODE_SCRIPT_COMMON }, + { 0x1f210, 43, G_UNICODE_SCRIPT_COMMON }, + { 0x1f240, 9, G_UNICODE_SCRIPT_COMMON }, + { 0x1f250, 2, G_UNICODE_SCRIPT_COMMON }, + { 0x1f300, 33, G_UNICODE_SCRIPT_COMMON }, + { 0x1f330, 6, G_UNICODE_SCRIPT_COMMON }, + { 0x1f337, 70, G_UNICODE_SCRIPT_COMMON }, + { 0x1f380, 20, G_UNICODE_SCRIPT_COMMON }, + { 0x1f3a0, 37, G_UNICODE_SCRIPT_COMMON }, + { 0x1f3c6, 5, G_UNICODE_SCRIPT_COMMON }, + { 0x1f3e0, 17, G_UNICODE_SCRIPT_COMMON }, + { 0x1f400, 63, G_UNICODE_SCRIPT_COMMON }, + { 0x1f440, 1, G_UNICODE_SCRIPT_COMMON }, + { 0x1f442, 182, G_UNICODE_SCRIPT_COMMON }, + { 0x1f4f9, 4, G_UNICODE_SCRIPT_COMMON }, + { 0x1f500, 62, G_UNICODE_SCRIPT_COMMON }, + { 0x1f540, 4, G_UNICODE_SCRIPT_COMMON }, + { 0x1f550, 24, G_UNICODE_SCRIPT_COMMON }, + { 0x1f5fb, 70, G_UNICODE_SCRIPT_COMMON }, + { 0x1f645, 11, G_UNICODE_SCRIPT_COMMON }, + { 0x1f680, 70, G_UNICODE_SCRIPT_COMMON }, + { 0x1f700, 116, G_UNICODE_SCRIPT_COMMON }, + { 0x20000, 42711, G_UNICODE_SCRIPT_HAN }, + { 0x2a700, 4149, G_UNICODE_SCRIPT_HAN }, + { 0x2b740, 222, G_UNICODE_SCRIPT_HAN }, + { 0x2f800, 542, G_UNICODE_SCRIPT_HAN }, + { 0xe0001, 1, G_UNICODE_SCRIPT_COMMON }, + { 0xe0020, 96, G_UNICODE_SCRIPT_COMMON }, + { 0xe0100, 240, G_UNICODE_SCRIPT_INHERITED }, +}; diff --git a/glib/glib/gsequence.c b/glib/glib/gsequence.c new file mode 100644 index 0000000..165fb38 --- /dev/null +++ b/glib/glib/gsequence.c @@ -0,0 +1,2007 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + * Soeren Sandmann (sandmann@daimi.au.dk) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "gsequence.h" + +#include "gmem.h" +#include "gtestutils.h" +#include "gslice.h" +/** + * SECTION:sequence + * @title: Sequences + * @short_description: scalable lists + * + * The #GSequence data structure has the API of a list, but is + * implemented internally with a balanced binary tree. This means that + * it is possible to maintain a sorted list of n elements in time O(n + * log n). The data contained in each element can be either integer + * values, by using of the Type Conversion Macros, + * or simply pointers to any type of data. + * + * A #GSequence is accessed through iterators, + * represented by a #GSequenceIter. An iterator represents a position + * between two elements of the sequence. For example, the + * begin iterator represents the gap immediately + * before the first element of the sequence, and the + * end iterator represents the gap immediately + * after the last element. In an empty sequence, the begin and end + * iterators are the same. + * + * Some methods on #GSequence operate on ranges of items. For example + * g_sequence_foreach_range() will call a user-specified function on + * each element with the given range. The range is delimited by the + * gaps represented by the passed-in iterators, so if you pass in the + * begin and end iterators, the range in question is the entire + * sequence. + * + * The function g_sequence_get() is used with an iterator to access the + * element immediately following the gap that the iterator represents. + * The iterator is said to point to that element. + * + * Iterators are stable across most operations on a #GSequence. For + * example an iterator pointing to some element of a sequence will + * continue to point to that element even after the sequence is sorted. + * Even moving an element to another sequence using for example + * g_sequence_move_range() will not invalidate the iterators pointing + * to it. The only operation that will invalidate an iterator is when + * the element it points to is removed from any sequence. + **/ + +/** + * GSequenceIter: + * + * The #GSequenceIter struct is an opaque data type representing an + * iterator pointing into a #GSequence. + **/ + +/** + * GSequenceIterCompareFunc: + * @a: a #GSequenceIter + * @b: a #GSequenceIter + * @data: user data + * @Returns: zero if the iterators are equal, a negative value if @a + * comes before @b, and a positive value if @b comes before + * @a. + * + * A #GSequenceIterCompareFunc is a function used to compare iterators. + * It must return zero if the iterators compare equal, a negative value + * if @a comes before @b, and a positive value if @b comes before @a. + **/ + +typedef struct _GSequenceNode GSequenceNode; + +/** + * GSequence: + * + * The #GSequence struct is an opaque data type representing a + * Sequence data type. + **/ +struct _GSequence +{ + GSequenceNode * end_node; + GDestroyNotify data_destroy_notify; + gboolean access_prohibited; + + /* The 'real_sequence' is used when temporary sequences are created + * to hold nodes that are being rearranged. The 'real_sequence' of such + * a temporary sequence points to the sequence that is actually being + * manipulated. The only reason we need this is so that when the + * sort/sort_changed/search_iter() functions call out to the application + * g_sequence_iter_get_sequence() will return the correct sequence. + */ + GSequence * real_sequence; +}; + +struct _GSequenceNode +{ + gint n_nodes; + GSequenceNode * parent; + GSequenceNode * left; + GSequenceNode * right; + gpointer data; /* For the end node, this field points + * to the sequence + */ +}; + +/* + * Declaration of GSequenceNode methods + */ +static GSequenceNode *node_new (gpointer data); +static GSequenceNode *node_get_first (GSequenceNode *node); +static GSequenceNode *node_get_last (GSequenceNode *node); +static GSequenceNode *node_get_prev (GSequenceNode *node); +static GSequenceNode *node_get_next (GSequenceNode *node); +static gint node_get_pos (GSequenceNode *node); +static GSequenceNode *node_get_by_pos (GSequenceNode *node, + gint pos); +static GSequenceNode *node_find (GSequenceNode *haystack, + GSequenceNode *needle, + GSequenceNode *end, + GSequenceIterCompareFunc cmp, + gpointer user_data); +static GSequenceNode *node_find_closest (GSequenceNode *haystack, + GSequenceNode *needle, + GSequenceNode *end, + GSequenceIterCompareFunc cmp, + gpointer user_data); +static gint node_get_length (GSequenceNode *node); +static void node_free (GSequenceNode *node, + GSequence *seq); +static void node_cut (GSequenceNode *split); +static void node_insert_before (GSequenceNode *node, + GSequenceNode *new); +static void node_unlink (GSequenceNode *node); +static void node_join (GSequenceNode *left, + GSequenceNode *right); +static void node_insert_sorted (GSequenceNode *node, + GSequenceNode *new, + GSequenceNode *end, + GSequenceIterCompareFunc cmp_func, + gpointer cmp_data); + + +/* + * Various helper functions + */ +static void +check_seq_access (GSequence *seq) +{ + if (G_UNLIKELY (seq->access_prohibited)) + { + g_warning ("Accessing a sequence while it is " + "being sorted or searched is not allowed"); + } +} + +static GSequence * +get_sequence (GSequenceNode *node) +{ + return (GSequence *)node_get_last (node)->data; +} + +static void +check_iter_access (GSequenceIter *iter) +{ + check_seq_access (get_sequence (iter)); +} + +static gboolean +is_end (GSequenceIter *iter) +{ + GSequence *seq; + + if (iter->right) + return FALSE; + + if (!iter->parent) + return TRUE; + + if (iter->parent->right != iter) + return FALSE; + + seq = get_sequence (iter); + + return seq->end_node == iter; +} + +typedef struct +{ + GCompareDataFunc cmp_func; + gpointer cmp_data; + GSequenceNode *end_node; +} SortInfo; + +/* This function compares two iters using a normal compare + * function and user_data passed in in a SortInfo struct + */ +static gint +iter_compare (GSequenceIter *node1, + GSequenceIter *node2, + gpointer data) +{ + const SortInfo *info = data; + gint retval; + + if (node1 == info->end_node) + return 1; + + if (node2 == info->end_node) + return -1; + + retval = info->cmp_func (node1->data, node2->data, info->cmp_data); + + return retval; +} + +/* + * Public API + */ + +/** + * g_sequence_new: + * @data_destroy: a #GDestroyNotify function, or %NULL + * + * Creates a new GSequence. The @data_destroy function, if non-%NULL will + * be called on all items when the sequence is destroyed and on items that + * are removed from the sequence. + * + * Return value: a new #GSequence + * + * Since: 2.14 + **/ +GSequence * +g_sequence_new (GDestroyNotify data_destroy) +{ + GSequence *seq = g_new (GSequence, 1); + seq->data_destroy_notify = data_destroy; + + seq->end_node = node_new (seq); + + seq->access_prohibited = FALSE; + + seq->real_sequence = seq; + + return seq; +} + +/** + * g_sequence_free: + * @seq: a #GSequence + * + * Frees the memory allocated for @seq. If @seq has a data destroy + * function associated with it, that function is called on all items in + * @seq. + * + * Since: 2.14 + **/ +void +g_sequence_free (GSequence *seq) +{ + g_return_if_fail (seq != NULL); + + check_seq_access (seq); + + node_free (seq->end_node, seq); + + g_free (seq); +} + +/** + * g_sequence_foreach_range: + * @begin: a #GSequenceIter + * @end: a #GSequenceIter + * @func: a #GFunc + * @user_data: user data passed to @func + * + * Calls @func for each item in the range (@begin, @end) passing + * @user_data to the function. + * + * Since: 2.14 + **/ +void +g_sequence_foreach_range (GSequenceIter *begin, + GSequenceIter *end, + GFunc func, + gpointer user_data) +{ + GSequence *seq; + GSequenceIter *iter; + + g_return_if_fail (func != NULL); + g_return_if_fail (begin != NULL); + g_return_if_fail (end != NULL); + + seq = get_sequence (begin); + + seq->access_prohibited = TRUE; + + iter = begin; + while (iter != end) + { + GSequenceIter *next = node_get_next (iter); + + func (iter->data, user_data); + + iter = next; + } + + seq->access_prohibited = FALSE; +} + +/** + * g_sequence_foreach: + * @seq: a #GSequence + * @func: the function to call for each item in @seq + * @user_data: user data passed to @func + * + * Calls @func for each item in the sequence passing @user_data + * to the function. + * + * Since: 2.14 + **/ +void +g_sequence_foreach (GSequence *seq, + GFunc func, + gpointer user_data) +{ + GSequenceIter *begin, *end; + + check_seq_access (seq); + + begin = g_sequence_get_begin_iter (seq); + end = g_sequence_get_end_iter (seq); + + g_sequence_foreach_range (begin, end, func, user_data); +} + +/** + * g_sequence_range_get_midpoint: + * @begin: a #GSequenceIter + * @end: a #GSequenceIter + * + * Finds an iterator somewhere in the range (@begin, @end). This + * iterator will be close to the middle of the range, but is not + * guaranteed to be exactly in the middle. + * + * The @begin and @end iterators must both point to the same sequence and + * @begin must come before or be equal to @end in the sequence. + * + * Return value: A #GSequenceIter pointing somewhere in the + * (@begin, @end) range. + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_range_get_midpoint (GSequenceIter *begin, + GSequenceIter *end) +{ + int begin_pos, end_pos, mid_pos; + + g_return_val_if_fail (begin != NULL, NULL); + g_return_val_if_fail (end != NULL, NULL); + g_return_val_if_fail (get_sequence (begin) == get_sequence (end), NULL); + + begin_pos = node_get_pos (begin); + end_pos = node_get_pos (end); + + g_return_val_if_fail (end_pos >= begin_pos, NULL); + + mid_pos = begin_pos + (end_pos - begin_pos) / 2; + + return node_get_by_pos (begin, mid_pos); +} + +/** + * g_sequence_iter_compare: + * @a: a #GSequenceIter + * @b: a #GSequenceIter + * + * Returns a negative number if @a comes before @b, 0 if they are equal, + * and a positive number if @a comes after @b. + * + * The @a and @b iterators must point into the same sequence. + * + * Return value: A negative number if @a comes before @b, 0 if they are + * equal, and a positive number if @a comes after @b. + * + * Since: 2.14 + **/ +gint +g_sequence_iter_compare (GSequenceIter *a, + GSequenceIter *b) +{ + gint a_pos, b_pos; + + g_return_val_if_fail (a != NULL, 0); + g_return_val_if_fail (b != NULL, 0); + g_return_val_if_fail (get_sequence (a) == get_sequence (b), 0); + + check_iter_access (a); + check_iter_access (b); + + a_pos = node_get_pos (a); + b_pos = node_get_pos (b); + + if (a_pos == b_pos) + return 0; + else if (a_pos > b_pos) + return 1; + else + return -1; +} + +/** + * g_sequence_append: + * @seq: a #GSequence + * @data: the data for the new item + * + * Adds a new item to the end of @seq. + * + * Return value: an iterator pointing to the new item + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_append (GSequence *seq, + gpointer data) +{ + GSequenceNode *node; + + g_return_val_if_fail (seq != NULL, NULL); + + check_seq_access (seq); + + node = node_new (data); + node_insert_before (seq->end_node, node); + + return node; +} + +/** + * g_sequence_prepend: + * @seq: a #GSequence + * @data: the data for the new item + * + * Adds a new item to the front of @seq + * + * Return value: an iterator pointing to the new item + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_prepend (GSequence *seq, + gpointer data) +{ + GSequenceNode *node, *first; + + g_return_val_if_fail (seq != NULL, NULL); + + check_seq_access (seq); + + node = node_new (data); + first = node_get_first (seq->end_node); + + node_insert_before (first, node); + + return node; +} + +/** + * g_sequence_insert_before: + * @iter: a #GSequenceIter + * @data: the data for the new item + * + * Inserts a new item just before the item pointed to by @iter. + * + * Return value: an iterator pointing to the new item + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_insert_before (GSequenceIter *iter, + gpointer data) +{ + GSequenceNode *node; + + g_return_val_if_fail (iter != NULL, NULL); + + check_iter_access (iter); + + node = node_new (data); + + node_insert_before (iter, node); + + return node; +} + +/** + * g_sequence_remove: + * @iter: a #GSequenceIter + * + * Removes the item pointed to by @iter. It is an error to pass the + * end iterator to this function. + * + * If the sequence has a data destroy function associated with it, this + * function is called on the data for the removed item. + * + * Since: 2.14 + **/ +void +g_sequence_remove (GSequenceIter *iter) +{ + GSequence *seq; + + g_return_if_fail (iter != NULL); + g_return_if_fail (!is_end (iter)); + + check_iter_access (iter); + + seq = get_sequence (iter); + + node_unlink (iter); + node_free (iter, seq); +} + +/** + * g_sequence_remove_range: + * @begin: a #GSequenceIter + * @end: a #GSequenceIter + * + * Removes all items in the (@begin, @end) range. + * + * If the sequence has a data destroy function associated with it, this + * function is called on the data for the removed items. + * + * Since: 2.14 + **/ +void +g_sequence_remove_range (GSequenceIter *begin, + GSequenceIter *end) +{ + g_return_if_fail (get_sequence (begin) == get_sequence (end)); + + check_iter_access (begin); + check_iter_access (end); + + g_sequence_move_range (NULL, begin, end); +} + +/** + * g_sequence_move_range: + * @dest: a #GSequenceIter + * @begin: a #GSequenceIter + * @end: a #GSequenceIter + * + * Inserts the (@begin, @end) range at the destination pointed to by ptr. + * The @begin and @end iters must point into the same sequence. It is + * allowed for @dest to point to a different sequence than the one pointed + * into by @begin and @end. + * + * If @dest is NULL, the range indicated by @begin and @end is + * removed from the sequence. If @dest iter points to a place within + * the (@begin, @end) range, the range does not move. + * + * Since: 2.14 + **/ +void +g_sequence_move_range (GSequenceIter *dest, + GSequenceIter *begin, + GSequenceIter *end) +{ + GSequence *src_seq; + GSequenceNode *first; + + g_return_if_fail (begin != NULL); + g_return_if_fail (end != NULL); + + check_iter_access (begin); + check_iter_access (end); + if (dest) + check_iter_access (dest); + + src_seq = get_sequence (begin); + + g_return_if_fail (src_seq == get_sequence (end)); + + /* Dest points to begin or end? */ + if (dest == begin || dest == end) + return; + + /* begin comes after end? */ + if (g_sequence_iter_compare (begin, end) >= 0) + return; + + /* dest points somewhere in the (begin, end) range? */ + if (dest && get_sequence (dest) == src_seq && + g_sequence_iter_compare (dest, begin) > 0 && + g_sequence_iter_compare (dest, end) < 0) + { + return; + } + + src_seq = get_sequence (begin); + + first = node_get_first (begin); + + node_cut (begin); + + node_cut (end); + + if (first != begin) + node_join (first, end); + + if (dest) + { + first = node_get_first (dest); + + node_cut (dest); + + node_join (begin, dest); + + if (dest != first) + node_join (first, begin); + } + else + { + node_free (begin, src_seq); + } +} + +/** + * g_sequence_sort: + * @seq: a #GSequence + * @cmp_func: the function used to sort the sequence + * @cmp_data: user data passed to @cmp_func + * + * Sorts @seq using @cmp_func. + * + * @cmp_func is passed two items of @seq and should + * return 0 if they are equal, a negative value if the + * first comes before the second, and a positive value + * if the second comes before the first. + * + * Since: 2.14 + **/ +void +g_sequence_sort (GSequence *seq, + GCompareDataFunc cmp_func, + gpointer cmp_data) +{ + SortInfo info; + + info.cmp_func = cmp_func; + info.cmp_data = cmp_data; + info.end_node = seq->end_node; + + check_seq_access (seq); + + g_sequence_sort_iter (seq, iter_compare, &info); +} + +/** + * g_sequence_insert_sorted: + * @seq: a #GSequence + * @data: the data to insert + * @cmp_func: the function used to compare items in the sequence + * @cmp_data: user data passed to @cmp_func. + * + * Inserts @data into @sequence using @func to determine the new + * position. The sequence must already be sorted according to @cmp_func; + * otherwise the new position of @data is undefined. + * + * @cmp_func is called with two items of the @seq and @user_data. + * It should return 0 if the items are equal, a negative value + * if the first item comes before the second, and a positive value + * if the second item comes before the first. + * + * Return value: a #GSequenceIter pointing to the new item. + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_insert_sorted (GSequence *seq, + gpointer data, + GCompareDataFunc cmp_func, + gpointer cmp_data) +{ + SortInfo info; + + g_return_val_if_fail (seq != NULL, NULL); + g_return_val_if_fail (cmp_func != NULL, NULL); + + info.cmp_func = cmp_func; + info.cmp_data = cmp_data; + info.end_node = seq->end_node; + check_seq_access (seq); + + return g_sequence_insert_sorted_iter (seq, data, iter_compare, &info); +} + +/** + * g_sequence_sort_changed: + * @iter: A #GSequenceIter + * @cmp_func: the function used to compare items in the sequence + * @cmp_data: user data passed to @cmp_func. + * + * Moves the data pointed to a new position as indicated by @cmp_func. This + * function should be called for items in a sequence already sorted according + * to @cmp_func whenever some aspect of an item changes so that @cmp_func + * may return different values for that item. + * + * @cmp_func is called with two items of the @seq and @user_data. + * It should return 0 if the items are equal, a negative value if + * the first item comes before the second, and a positive value if + * the second item comes before the first. + * + * Since: 2.14 + **/ +void +g_sequence_sort_changed (GSequenceIter *iter, + GCompareDataFunc cmp_func, + gpointer cmp_data) +{ + SortInfo info; + + g_return_if_fail (!is_end (iter)); + + info.cmp_func = cmp_func; + info.cmp_data = cmp_data; + info.end_node = get_sequence (iter)->end_node; + check_iter_access (iter); + + g_sequence_sort_changed_iter (iter, iter_compare, &info); +} + +/** + * g_sequence_search: + * @seq: a #GSequence + * @data: data for the new item + * @cmp_func: the function used to compare items in the sequence + * @cmp_data: user data passed to @cmp_func. + * + * Returns an iterator pointing to the position where @data would + * be inserted according to @cmp_func and @cmp_data. + * + * @cmp_func is called with two items of the @seq and @user_data. + * It should return 0 if the items are equal, a negative value if + * the first item comes before the second, and a positive value if + * the second item comes before the first. + * + * If you are simply searching for an existing element of the sequence, + * consider using g_sequence_lookup(). + * + * + * This function will fail if the data contained in the sequence is + * unsorted. Use g_sequence_insert_sorted() or + * g_sequence_insert_sorted_iter() to add data to your sequence or, if + * you want to add a large amount of data, call g_sequence_sort() after + * doing unsorted insertions. + * + * + * Return value: an #GSequenceIter pointing to the position where @data + * would have been inserted according to @cmp_func and @cmp_data. + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_search (GSequence *seq, + gpointer data, + GCompareDataFunc cmp_func, + gpointer cmp_data) +{ + SortInfo info; + + g_return_val_if_fail (seq != NULL, NULL); + + info.cmp_func = cmp_func; + info.cmp_data = cmp_data; + info.end_node = seq->end_node; + check_seq_access (seq); + + return g_sequence_search_iter (seq, data, iter_compare, &info); +} + +/** + * g_sequence_lookup: + * @seq: a #GSequence + * @data: data to lookup + * @cmp_func: the function used to compare items in the sequence + * @cmp_data: user data passed to @cmp_func. + * + * Returns an iterator pointing to the position of the first item found + * equal to @data according to @cmp_func and @cmp_data. If more than one + * item is equal, it is not guaranteed that it is the first which is + * returned. In that case, you can use g_sequence_iter_next() and + * g_sequence_iter_prev() to get others. + * + * @cmp_func is called with two items of the @seq and @user_data. + * It should return 0 if the items are equal, a negative value if + * the first item comes before the second, and a positive value if + * the second item comes before the first. + * + * + * This function will fail if the data contained in the sequence is + * unsorted. Use g_sequence_insert_sorted() or + * g_sequence_insert_sorted_iter() to add data to your sequence or, if + * you want to add a large amount of data, call g_sequence_sort() after + * doing unsorted insertions. + * + * + * Return value: an #GSequenceIter pointing to the position of the + * first item found equal to @data according to @cmp_func and @cmp_data. + * + * Since: 2.28 + **/ +GSequenceIter * +g_sequence_lookup (GSequence *seq, + gpointer data, + GCompareDataFunc cmp_func, + gpointer cmp_data) +{ + SortInfo info; + + g_return_val_if_fail (seq != NULL, NULL); + + info.cmp_func = cmp_func; + info.cmp_data = cmp_data; + info.end_node = seq->end_node; + check_seq_access (seq); + + return g_sequence_lookup_iter (seq, data, iter_compare, &info); +} + +/** + * g_sequence_sort_iter: + * @seq: a #GSequence + * @cmp_func: the function used to compare iterators in the sequence + * @cmp_data: user data passed to @cmp_func + * + * Like g_sequence_sort(), but uses a #GSequenceIterCompareFunc instead + * of a GCompareDataFunc as the compare function + * + * @cmp_func is called with two iterators pointing into @seq. It should + * return 0 if the iterators are equal, a negative value if the first + * iterator comes before the second, and a positive value if the second + * iterator comes before the first. + * + * Since: 2.14 + **/ +void +g_sequence_sort_iter (GSequence *seq, + GSequenceIterCompareFunc cmp_func, + gpointer cmp_data) +{ + GSequence *tmp; + GSequenceNode *begin, *end; + + g_return_if_fail (seq != NULL); + g_return_if_fail (cmp_func != NULL); + + check_seq_access (seq); + + begin = g_sequence_get_begin_iter (seq); + end = g_sequence_get_end_iter (seq); + + tmp = g_sequence_new (NULL); + tmp->real_sequence = seq; + + g_sequence_move_range (g_sequence_get_begin_iter (tmp), begin, end); + + seq->access_prohibited = TRUE; + tmp->access_prohibited = TRUE; + + while (g_sequence_get_length (tmp) > 0) + { + GSequenceNode *node = g_sequence_get_begin_iter (tmp); + + node_insert_sorted (seq->end_node, node, seq->end_node, + cmp_func, cmp_data); + } + + tmp->access_prohibited = FALSE; + seq->access_prohibited = FALSE; + + g_sequence_free (tmp); +} + +/** + * g_sequence_sort_changed_iter: + * @iter: a #GSequenceIter + * @iter_cmp: the function used to compare iterators in the sequence + * @cmp_data: user data passed to @cmp_func + * + * Like g_sequence_sort_changed(), but uses + * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as + * the compare function. + * + * @iter_cmp is called with two iterators pointing into @seq. It should + * return 0 if the iterators are equal, a negative value if the first + * iterator comes before the second, and a positive value if the second + * iterator comes before the first. + * + * Since: 2.14 + **/ +void +g_sequence_sort_changed_iter (GSequenceIter *iter, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data) +{ + GSequence *seq, *tmp_seq; + GSequenceIter *next, *prev; + + g_return_if_fail (iter != NULL); + g_return_if_fail (!is_end (iter)); + g_return_if_fail (iter_cmp != NULL); + check_iter_access (iter); + + /* If one of the neighbours is equal to iter, then + * don't move it. This ensures that sort_changed() is + * a stable operation. + */ + + next = node_get_next (iter); + prev = node_get_prev (iter); + + if (prev != iter && iter_cmp (prev, iter, cmp_data) == 0) + return; + + if (!is_end (next) && iter_cmp (next, iter, cmp_data) == 0) + return; + + seq = get_sequence (iter); + + seq->access_prohibited = TRUE; + + tmp_seq = g_sequence_new (NULL); + tmp_seq->real_sequence = seq; + + node_unlink (iter); + node_insert_before (tmp_seq->end_node, iter); + + node_insert_sorted (seq->end_node, iter, seq->end_node, + iter_cmp, cmp_data); + + g_sequence_free (tmp_seq); + + seq->access_prohibited = FALSE; +} + +/** + * g_sequence_insert_sorted_iter: + * @seq: a #GSequence + * @data: data for the new item + * @iter_cmp: the function used to compare iterators in the sequence + * @cmp_data: user data passed to @cmp_func + * + * Like g_sequence_insert_sorted(), but uses + * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as + * the compare function. + * + * @iter_cmp is called with two iterators pointing into @seq. + * It should return 0 if the iterators are equal, a negative + * value if the first iterator comes before the second, and a + * positive value if the second iterator comes before the first. + * + * It is called with two iterators pointing into @seq. It should + * return 0 if the iterators are equal, a negative value if the + * first iterator comes before the second, and a positive value + * if the second iterator comes before the first. + * + * Return value: a #GSequenceIter pointing to the new item + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_insert_sorted_iter (GSequence *seq, + gpointer data, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data) +{ + GSequenceNode *new_node; + GSequence *tmp_seq; + + g_return_val_if_fail (seq != NULL, NULL); + g_return_val_if_fail (iter_cmp != NULL, NULL); + + check_seq_access (seq); + + seq->access_prohibited = TRUE; + + /* Create a new temporary sequence and put the new node into + * that. The reason for this is that the user compare function + * will be called with the new node, and if it dereferences, + * "is_end" will be called on it. But that will crash if the + * node is not actually in a sequence. + * + * node_insert_sorted() makes sure the node is unlinked before + * it is inserted. + * + * The reason we need the "iter" versions at all is that that + * is the only kind of compare functions GtkTreeView can use. + */ + tmp_seq = g_sequence_new (NULL); + tmp_seq->real_sequence = seq; + + new_node = g_sequence_append (tmp_seq, data); + + node_insert_sorted (seq->end_node, new_node, + seq->end_node, iter_cmp, cmp_data); + + g_sequence_free (tmp_seq); + + seq->access_prohibited = FALSE; + + return new_node; +} + +/** + * g_sequence_search_iter: + * @seq: a #GSequence + * @data: data for the new item + * @iter_cmp: the function used to compare iterators in the sequence + * @cmp_data: user data passed to @iter_cmp + * + * Like g_sequence_search(), but uses a #GSequenceIterCompareFunc + * instead of a #GCompareDataFunc as the compare function. + * + * @iter_cmp is called with two iterators pointing into @seq. + * It should return 0 if the iterators are equal, a negative value + * if the first iterator comes before the second, and a positive + * value if the second iterator comes before the first. + * + * If you are simply searching for an existing element of the sequence, + * consider using g_sequence_lookup_iter(). + * + * + * This function will fail if the data contained in the sequence is + * unsorted. Use g_sequence_insert_sorted() or + * g_sequence_insert_sorted_iter() to add data to your sequence or, if + * you want to add a large amount of data, call g_sequence_sort() after + * doing unsorted insertions. + * + * + * Return value: a #GSequenceIter pointing to the position in @seq + * where @data would have been inserted according to @iter_cmp + * and @cmp_data. + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_search_iter (GSequence *seq, + gpointer data, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data) +{ + GSequenceNode *node; + GSequenceNode *dummy; + GSequence *tmp_seq; + + g_return_val_if_fail (seq != NULL, NULL); + + check_seq_access (seq); + + seq->access_prohibited = TRUE; + + tmp_seq = g_sequence_new (NULL); + tmp_seq->real_sequence = seq; + + dummy = g_sequence_append (tmp_seq, data); + + node = node_find_closest (seq->end_node, dummy, + seq->end_node, iter_cmp, cmp_data); + + g_sequence_free (tmp_seq); + + seq->access_prohibited = FALSE; + + return node; +} + +/** + * g_sequence_lookup_iter: + * @seq: a #GSequence + * @data: data to lookup + * @iter_cmp: the function used to compare iterators in the sequence + * @cmp_data: user data passed to @iter_cmp + * + * Like g_sequence_lookup(), but uses a #GSequenceIterCompareFunc + * instead of a #GCompareDataFunc as the compare function. + * + * @iter_cmp is called with two iterators pointing into @seq. + * It should return 0 if the iterators are equal, a negative value + * if the first iterator comes before the second, and a positive + * value if the second iterator comes before the first. + * + * + * This function will fail if the data contained in the sequence is + * unsorted. Use g_sequence_insert_sorted() or + * g_sequence_insert_sorted_iter() to add data to your sequence or, if + * you want to add a large amount of data, call g_sequence_sort() after + * doing unsorted insertions. + * + * + * Return value: an #GSequenceIter pointing to the position of + * the first item found equal to @data according to @cmp_func + * and @cmp_data. + * + * Since: 2.28 + **/ +GSequenceIter * +g_sequence_lookup_iter (GSequence *seq, + gpointer data, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data) +{ + GSequenceNode *node; + GSequenceNode *dummy; + GSequence *tmp_seq; + + g_return_val_if_fail (seq != NULL, NULL); + + check_seq_access (seq); + + seq->access_prohibited = TRUE; + + tmp_seq = g_sequence_new (NULL); + tmp_seq->real_sequence = seq; + + dummy = g_sequence_append (tmp_seq, data); + + node = node_find (seq->end_node, dummy, + seq->end_node, iter_cmp, cmp_data); + + g_sequence_free (tmp_seq); + + seq->access_prohibited = FALSE; + + return node; +} + +/** + * g_sequence_iter_get_sequence: + * @iter: a #GSequenceIter + * + * Returns the #GSequence that @iter points into. + * + * Return value: the #GSequence that @iter points into. + * + * Since: 2.14 + **/ +GSequence * +g_sequence_iter_get_sequence (GSequenceIter *iter) +{ + GSequence *seq; + + g_return_val_if_fail (iter != NULL, NULL); + + seq = get_sequence (iter); + + /* For temporary sequences, this points to the sequence that + * is actually being manipulated + */ + return seq->real_sequence; +} + +/** + * g_sequence_get: + * @iter: a #GSequenceIter + * + * Returns the data that @iter points to. + * + * Return value: the data that @iter points to + * + * Since: 2.14 + **/ +gpointer +g_sequence_get (GSequenceIter *iter) +{ + g_return_val_if_fail (iter != NULL, NULL); + g_return_val_if_fail (!is_end (iter), NULL); + + return iter->data; +} + +/** + * g_sequence_set: + * @iter: a #GSequenceIter + * @data: new data for the item + * + * Changes the data for the item pointed to by @iter to be @data. If + * the sequence has a data destroy function associated with it, that + * function is called on the existing data that @iter pointed to. + * + * Since: 2.14 + **/ +void +g_sequence_set (GSequenceIter *iter, + gpointer data) +{ + GSequence *seq; + + g_return_if_fail (iter != NULL); + g_return_if_fail (!is_end (iter)); + + seq = get_sequence (iter); + + /* If @data is identical to iter->data, it is destroyed + * here. This will work right in case of ref-counted objects. Also + * it is similar to what ghashtables do. + * + * For non-refcounted data it's a little less convenient, but + * code relying on self-setting not destroying would be + * pretty dubious anyway ... + */ + + if (seq->data_destroy_notify) + seq->data_destroy_notify (iter->data); + + iter->data = data; +} + +/** + * g_sequence_get_length: + * @seq: a #GSequence + * + * Returns the length of @seq + * + * Return value: the length of @seq + * + * Since: 2.14 + **/ +gint +g_sequence_get_length (GSequence *seq) +{ + return node_get_length (seq->end_node) - 1; +} + +/** + * g_sequence_get_end_iter: + * @seq: a #GSequence + * + * Returns the end iterator for @seg + * + * Return value: the end iterator for @seq + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_get_end_iter (GSequence *seq) +{ + g_return_val_if_fail (seq != NULL, NULL); + + return seq->end_node; +} + +/** + * g_sequence_get_begin_iter: + * @seq: a #GSequence + * + * Returns the begin iterator for @seq. + * + * Return value: the begin iterator for @seq. + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_get_begin_iter (GSequence *seq) +{ + g_return_val_if_fail (seq != NULL, NULL); + + return node_get_first (seq->end_node); +} + +static int +clamp_position (GSequence *seq, + int pos) +{ + gint len = g_sequence_get_length (seq); + + if (pos > len || pos < 0) + pos = len; + + return pos; +} + +/* + * if pos > number of items or -1, will return end pointer + */ +/** + * g_sequence_get_iter_at_pos: + * @seq: a #GSequence + * @pos: a position in @seq, or -1 for the end. + * + * Returns the iterator at position @pos. If @pos is negative or larger + * than the number of items in @seq, the end iterator is returned. + * + * Return value: The #GSequenceIter at position @pos + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_get_iter_at_pos (GSequence *seq, + gint pos) +{ + g_return_val_if_fail (seq != NULL, NULL); + + pos = clamp_position (seq, pos); + + return node_get_by_pos (seq->end_node, pos); +} + +/** + * g_sequence_move: + * @src: a #GSequenceIter pointing to the item to move + * @dest: a #GSequenceIter pointing to the position to which + * the item is moved. + * + * Moves the item pointed to by @src to the position indicated by @dest. + * After calling this function @dest will point to the position immediately + * after @src. It is allowed for @src and @dest to point into different + * sequences. + * + * Since: 2.14 + **/ +void +g_sequence_move (GSequenceIter *src, + GSequenceIter *dest) +{ + g_return_if_fail (src != NULL); + g_return_if_fail (dest != NULL); + g_return_if_fail (!is_end (src)); + + if (src == dest) + return; + + node_unlink (src); + node_insert_before (dest, src); +} + +/* GSequenceIter */ + +/** + * g_sequence_iter_is_end: + * @iter: a #GSequenceIter + * + * Returns whether @iter is the end iterator + * + * Return value: Whether @iter is the end iterator. + * + * Since: 2.14 + **/ +gboolean +g_sequence_iter_is_end (GSequenceIter *iter) +{ + g_return_val_if_fail (iter != NULL, FALSE); + + return is_end (iter); +} + +/** + * g_sequence_iter_is_begin: + * @iter: a #GSequenceIter + * + * Returns whether @iter is the begin iterator + * + * Return value: whether @iter is the begin iterator + * + * Since: 2.14 + **/ +gboolean +g_sequence_iter_is_begin (GSequenceIter *iter) +{ + g_return_val_if_fail (iter != NULL, FALSE); + + return (node_get_prev (iter) == iter); +} + +/** + * g_sequence_iter_get_position: + * @iter: a #GSequenceIter + * + * Returns the position of @iter + * + * Return value: the position of @iter + * + * Since: 2.14 + **/ +gint +g_sequence_iter_get_position (GSequenceIter *iter) +{ + g_return_val_if_fail (iter != NULL, -1); + + return node_get_pos (iter); +} + +/** + * g_sequence_iter_next: + * @iter: a #GSequenceIter + * + * Returns an iterator pointing to the next position after @iter. If + * @iter is the end iterator, the end iterator is returned. + * + * Return value: a #GSequenceIter pointing to the next position after @iter. + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_iter_next (GSequenceIter *iter) +{ + g_return_val_if_fail (iter != NULL, NULL); + + return node_get_next (iter); +} + +/** + * g_sequence_iter_prev: + * @iter: a #GSequenceIter + * + * Returns an iterator pointing to the previous position before @iter. If + * @iter is the begin iterator, the begin iterator is returned. + * + * Return value: a #GSequenceIter pointing to the previous position before + * @iter. + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_iter_prev (GSequenceIter *iter) +{ + g_return_val_if_fail (iter != NULL, NULL); + + return node_get_prev (iter); +} + +/** + * g_sequence_iter_move: + * @iter: a #GSequenceIter + * @delta: A positive or negative number indicating how many positions away + * from @iter the returned #GSequenceIter will be. + * + * Returns the #GSequenceIter which is @delta positions away from @iter. + * If @iter is closer than -@delta positions to the beginning of the sequence, + * the begin iterator is returned. If @iter is closer than @delta positions + * to the end of the sequence, the end iterator is returned. + * + * Return value: a #GSequenceIter which is @delta positions away from @iter. + * + * Since: 2.14 + **/ +GSequenceIter * +g_sequence_iter_move (GSequenceIter *iter, + gint delta) +{ + gint new_pos; + gint len; + + g_return_val_if_fail (iter != NULL, NULL); + + len = g_sequence_get_length (get_sequence (iter)); + + new_pos = node_get_pos (iter) + delta; + + if (new_pos < 0) + new_pos = 0; + else if (new_pos > len) + new_pos = len; + + return node_get_by_pos (iter, new_pos); +} + +/** + * g_sequence_swap: + * @a: a #GSequenceIter + * @b: a #GSequenceIter + * + * Swaps the items pointed to by @a and @b. It is allowed for @a and @b + * to point into difference sequences. + * + * Since: 2.14 + **/ +void +g_sequence_swap (GSequenceIter *a, + GSequenceIter *b) +{ + GSequenceNode *leftmost, *rightmost, *rightmost_next; + int a_pos, b_pos; + + g_return_if_fail (!g_sequence_iter_is_end (a)); + g_return_if_fail (!g_sequence_iter_is_end (b)); + + if (a == b) + return; + + a_pos = g_sequence_iter_get_position (a); + b_pos = g_sequence_iter_get_position (b); + + if (a_pos > b_pos) + { + leftmost = b; + rightmost = a; + } + else + { + leftmost = a; + rightmost = b; + } + + rightmost_next = node_get_next (rightmost); + + /* The situation is now like this: + * + * ..., leftmost, ......., rightmost, rightmost_next, ... + * + */ + g_sequence_move (rightmost, leftmost); + g_sequence_move (leftmost, rightmost_next); +} + +/* + * Implementation of a treap + * + * + */ +static guint +get_priority (GSequenceNode *node) +{ + guint key = GPOINTER_TO_UINT (node); + + /* This hash function is based on one found on Thomas Wang's + * web page at + * + * http://www.concentric.net/~Ttwang/tech/inthash.htm + * + */ + key = (key << 15) - key - 1; + key = key ^ (key >> 12); + key = key + (key << 2); + key = key ^ (key >> 4); + key = key + (key << 3) + (key << 11); + key = key ^ (key >> 16); + + /* We rely on 0 being less than all other priorities */ + return key? key : 1; +} + +static GSequenceNode * +find_root (GSequenceNode *node) +{ + while (node->parent) + node = node->parent; + + return node; +} + +static GSequenceNode * +node_new (gpointer data) +{ + GSequenceNode *node = g_slice_new0 (GSequenceNode); + + node->n_nodes = 1; + node->data = data; + node->left = NULL; + node->right = NULL; + node->parent = NULL; + + return node; +} + +static GSequenceNode * +node_get_first (GSequenceNode *node) +{ + node = find_root (node); + + while (node->left) + node = node->left; + + return node; +} + +static GSequenceNode * +node_get_last (GSequenceNode *node) +{ + node = find_root (node); + + while (node->right) + node = node->right; + + return node; +} + +#define NODE_LEFT_CHILD(n) (((n)->parent) && ((n)->parent->left) == (n)) +#define NODE_RIGHT_CHILD(n) (((n)->parent) && ((n)->parent->right) == (n)) + +static GSequenceNode * +node_get_next (GSequenceNode *node) +{ + GSequenceNode *n = node; + + if (n->right) + { + n = n->right; + while (n->left) + n = n->left; + } + else + { + while (NODE_RIGHT_CHILD (n)) + n = n->parent; + + if (n->parent) + n = n->parent; + else + n = node; + } + + return n; +} + +static GSequenceNode * +node_get_prev (GSequenceNode *node) +{ + GSequenceNode *n = node; + + if (n->left) + { + n = n->left; + while (n->right) + n = n->right; + } + else + { + while (NODE_LEFT_CHILD (n)) + n = n->parent; + + if (n->parent) + n = n->parent; + else + n = node; + } + + return n; +} + +#define N_NODES(n) ((n)? (n)->n_nodes : 0) + +static gint +node_get_pos (GSequenceNode *node) +{ + int n_smaller = 0; + + if (node->left) + n_smaller = node->left->n_nodes; + + while (node) + { + if (NODE_RIGHT_CHILD (node)) + n_smaller += N_NODES (node->parent->left) + 1; + + node = node->parent; + } + + return n_smaller; +} + +static GSequenceNode * +node_get_by_pos (GSequenceNode *node, + gint pos) +{ + int i; + + node = find_root (node); + + while ((i = N_NODES (node->left)) != pos) + { + if (i < pos) + { + node = node->right; + pos -= (i + 1); + } + else + { + node = node->left; + } + } + + return node; +} + +static GSequenceNode * +node_find (GSequenceNode *haystack, + GSequenceNode *needle, + GSequenceNode *end, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data) +{ + gint c; + + haystack = find_root (haystack); + + do + { + /* iter_cmp can't be passed the end node, since the function may + * be user-supplied + */ + if (haystack == end) + c = 1; + else + c = iter_cmp (haystack, needle, cmp_data); + + if (c == 0) + break; + + if (c > 0) + haystack = haystack->left; + else + haystack = haystack->right; + } + while (haystack != NULL); + + return haystack; +} + +static GSequenceNode * +node_find_closest (GSequenceNode *haystack, + GSequenceNode *needle, + GSequenceNode *end, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data) +{ + GSequenceNode *best; + gint c; + + haystack = find_root (haystack); + + do + { + best = haystack; + + /* iter_cmp can't be passed the end node, since the function may + * be user-supplied + */ + if (haystack == end) + c = 1; + else + c = iter_cmp (haystack, needle, cmp_data); + + /* In the following we don't break even if c == 0. Instead we go on + * searching along the 'bigger' nodes, so that we find the last one + * that is equal to the needle. + */ + if (c > 0) + haystack = haystack->left; + else + haystack = haystack->right; + } + while (haystack != NULL); + + /* If the best node is smaller or equal to the data, then move one step + * to the right to make sure the best one is strictly bigger than the data + */ + if (best != end && c <= 0) + best = node_get_next (best); + + return best; +} + +static gint +node_get_length (GSequenceNode *node) +{ + node = find_root (node); + + return node->n_nodes; +} + +static void +real_node_free (GSequenceNode *node, + GSequence *seq) +{ + if (node) + { + real_node_free (node->left, seq); + real_node_free (node->right, seq); + + if (seq && seq->data_destroy_notify && node != seq->end_node) + seq->data_destroy_notify (node->data); + + g_slice_free (GSequenceNode, node); + } +} + +static void +node_free (GSequenceNode *node, + GSequence *seq) +{ + node = find_root (node); + + real_node_free (node, seq); +} + +static void +node_update_fields (GSequenceNode *node) +{ + int n_nodes = 1; + + n_nodes += N_NODES (node->left); + n_nodes += N_NODES (node->right); + + node->n_nodes = n_nodes; +} + +static void +node_rotate (GSequenceNode *node) +{ + GSequenceNode *tmp, *old; + + g_assert (node->parent); + g_assert (node->parent != node); + + if (NODE_LEFT_CHILD (node)) + { + /* rotate right */ + tmp = node->right; + + node->right = node->parent; + node->parent = node->parent->parent; + if (node->parent) + { + if (node->parent->left == node->right) + node->parent->left = node; + else + node->parent->right = node; + } + + g_assert (node->right); + + node->right->parent = node; + node->right->left = tmp; + + if (node->right->left) + node->right->left->parent = node->right; + + old = node->right; + } + else + { + /* rotate left */ + tmp = node->left; + + node->left = node->parent; + node->parent = node->parent->parent; + if (node->parent) + { + if (node->parent->right == node->left) + node->parent->right = node; + else + node->parent->left = node; + } + + g_assert (node->left); + + node->left->parent = node; + node->left->right = tmp; + + if (node->left->right) + node->left->right->parent = node->left; + + old = node->left; + } + + node_update_fields (old); + node_update_fields (node); +} + +static void +node_update_fields_deep (GSequenceNode *node) +{ + if (node) + { + node_update_fields (node); + + node_update_fields_deep (node->parent); + } +} + +static void +rotate_down (GSequenceNode *node, + guint priority) +{ + guint left, right; + + left = node->left ? get_priority (node->left) : 0; + right = node->right ? get_priority (node->right) : 0; + + while (priority < left || priority < right) + { + if (left > right) + node_rotate (node->left); + else + node_rotate (node->right); + + left = node->left ? get_priority (node->left) : 0; + right = node->right ? get_priority (node->right) : 0; + } +} + +static void +node_cut (GSequenceNode *node) +{ + while (node->parent) + node_rotate (node); + + if (node->left) + node->left->parent = NULL; + + node->left = NULL; + node_update_fields (node); + + rotate_down (node, get_priority (node)); +} + +static void +node_join (GSequenceNode *left, + GSequenceNode *right) +{ + GSequenceNode *fake = node_new (NULL); + + fake->left = find_root (left); + fake->right = find_root (right); + fake->left->parent = fake; + fake->right->parent = fake; + + node_update_fields (fake); + + node_unlink (fake); + + node_free (fake, NULL); +} + +static void +node_insert_before (GSequenceNode *node, + GSequenceNode *new) +{ + new->left = node->left; + if (new->left) + new->left->parent = new; + + new->parent = node; + node->left = new; + + node_update_fields_deep (new); + + while (new->parent && get_priority (new) > get_priority (new->parent)) + node_rotate (new); + + rotate_down (new, get_priority (new)); +} + +static void +node_unlink (GSequenceNode *node) +{ + rotate_down (node, 0); + + if (NODE_RIGHT_CHILD (node)) + node->parent->right = NULL; + else if (NODE_LEFT_CHILD (node)) + node->parent->left = NULL; + + if (node->parent) + node_update_fields_deep (node->parent); + + node->parent = NULL; +} + +static void +node_insert_sorted (GSequenceNode *node, + GSequenceNode *new, + GSequenceNode *end, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data) +{ + GSequenceNode *closest; + + closest = node_find_closest (node, new, end, iter_cmp, cmp_data); + + node_unlink (new); + + node_insert_before (closest, new); +} diff --git a/glib/glib/gsequence.h b/glib/glib/gsequence.h new file mode 100644 index 0000000..3e5a03d --- /dev/null +++ b/glib/glib/gsequence.h @@ -0,0 +1,136 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 + * Soeren Sandmann (sandmann@daimi.au.dk) + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_SEQUENCE_H__ +#define __G_SEQUENCE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GSequence GSequence; +typedef struct _GSequenceNode GSequenceIter; + +typedef gint (* GSequenceIterCompareFunc) (GSequenceIter *a, + GSequenceIter *b, + gpointer data); + + +/* GSequence */ +GSequence * g_sequence_new (GDestroyNotify data_destroy); +void g_sequence_free (GSequence *seq); +gint g_sequence_get_length (GSequence *seq); +void g_sequence_foreach (GSequence *seq, + GFunc func, + gpointer user_data); +void g_sequence_foreach_range (GSequenceIter *begin, + GSequenceIter *end, + GFunc func, + gpointer user_data); +void g_sequence_sort (GSequence *seq, + GCompareDataFunc cmp_func, + gpointer cmp_data); +void g_sequence_sort_iter (GSequence *seq, + GSequenceIterCompareFunc cmp_func, + gpointer cmp_data); + + +/* Getting iters */ +GSequenceIter *g_sequence_get_begin_iter (GSequence *seq); +GSequenceIter *g_sequence_get_end_iter (GSequence *seq); +GSequenceIter *g_sequence_get_iter_at_pos (GSequence *seq, + gint pos); +GSequenceIter *g_sequence_append (GSequence *seq, + gpointer data); +GSequenceIter *g_sequence_prepend (GSequence *seq, + gpointer data); +GSequenceIter *g_sequence_insert_before (GSequenceIter *iter, + gpointer data); +void g_sequence_move (GSequenceIter *src, + GSequenceIter *dest); +void g_sequence_swap (GSequenceIter *a, + GSequenceIter *b); +GSequenceIter *g_sequence_insert_sorted (GSequence *seq, + gpointer data, + GCompareDataFunc cmp_func, + gpointer cmp_data); +GSequenceIter *g_sequence_insert_sorted_iter (GSequence *seq, + gpointer data, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data); +void g_sequence_sort_changed (GSequenceIter *iter, + GCompareDataFunc cmp_func, + gpointer cmp_data); +void g_sequence_sort_changed_iter (GSequenceIter *iter, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data); +void g_sequence_remove (GSequenceIter *iter); +void g_sequence_remove_range (GSequenceIter *begin, + GSequenceIter *end); +void g_sequence_move_range (GSequenceIter *dest, + GSequenceIter *begin, + GSequenceIter *end); +GSequenceIter *g_sequence_search (GSequence *seq, + gpointer data, + GCompareDataFunc cmp_func, + gpointer cmp_data); +GSequenceIter *g_sequence_search_iter (GSequence *seq, + gpointer data, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data); +GSequenceIter *g_sequence_lookup (GSequence *seq, + gpointer data, + GCompareDataFunc cmp_func, + gpointer cmp_data); +GSequenceIter *g_sequence_lookup_iter (GSequence *seq, + gpointer data, + GSequenceIterCompareFunc iter_cmp, + gpointer cmp_data); + + +/* Dereferencing */ +gpointer g_sequence_get (GSequenceIter *iter); +void g_sequence_set (GSequenceIter *iter, + gpointer data); + +/* Operations on GSequenceIter * */ +gboolean g_sequence_iter_is_begin (GSequenceIter *iter); +gboolean g_sequence_iter_is_end (GSequenceIter *iter); +GSequenceIter *g_sequence_iter_next (GSequenceIter *iter); +GSequenceIter *g_sequence_iter_prev (GSequenceIter *iter); +gint g_sequence_iter_get_position (GSequenceIter *iter); +GSequenceIter *g_sequence_iter_move (GSequenceIter *iter, + gint delta); +GSequence * g_sequence_iter_get_sequence (GSequenceIter *iter); + + +/* Search */ +gint g_sequence_iter_compare (GSequenceIter *a, + GSequenceIter *b); +GSequenceIter *g_sequence_range_get_midpoint (GSequenceIter *begin, + GSequenceIter *end); + +G_END_DECLS + +#endif /* __G_SEQUENCE_H__ */ diff --git a/glib/glib/gshell.c b/glib/glib/gshell.c new file mode 100644 index 0000000..205519e --- /dev/null +++ b/glib/glib/gshell.c @@ -0,0 +1,685 @@ +/* gshell.c - Shell-related utilities + * + * Copyright 2000 Red Hat, Inc. + * g_execvpe implementation based on GNU libc execvp: + * Copyright 1991, 92, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + * + * GLib is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, write + * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "gshell.h" + +#include "gslist.h" +#include "gstrfuncs.h" +#include "gstring.h" +#include "gtestutils.h" +#include "glibintl.h" + +/** + * SECTION:shell + * @title: Shell-related Utilities + * @short_description: shell-like commandline handling + **/ + +/** + * G_SHELL_ERROR: + * + * Error domain for shell functions. Errors in this domain will be from + * the #GShellError enumeration. See #GError for information on error + * domains. + **/ + +/** + * GShellError: + * @G_SHELL_ERROR_BAD_QUOTING: Mismatched or otherwise mangled quoting. + * @G_SHELL_ERROR_EMPTY_STRING: String to be parsed was empty. + * @G_SHELL_ERROR_FAILED: Some other error. + * + * Error codes returned by shell functions. + **/ +GQuark +g_shell_error_quark (void) +{ + return g_quark_from_static_string ("g-shell-error-quark"); +} + +/* Single quotes preserve the literal string exactly. escape + * sequences are not allowed; not even \' - if you want a ' + * in the quoted text, you have to do something like 'foo'\''bar' + * + * Double quotes allow $ ` " \ and newline to be escaped with backslash. + * Otherwise double quotes preserve things literally. + */ + +static gboolean +unquote_string_inplace (gchar* str, gchar** end, GError** err) +{ + gchar* dest; + gchar* s; + gchar quote_char; + + g_return_val_if_fail(end != NULL, FALSE); + g_return_val_if_fail(err == NULL || *err == NULL, FALSE); + g_return_val_if_fail(str != NULL, FALSE); + + dest = s = str; + + quote_char = *s; + + if (!(*s == '"' || *s == '\'')) + { + g_set_error_literal (err, + G_SHELL_ERROR, + G_SHELL_ERROR_BAD_QUOTING, + _("Quoted text doesn't begin with a quotation mark")); + *end = str; + return FALSE; + } + + /* Skip the initial quote mark */ + ++s; + + if (quote_char == '"') + { + while (*s) + { + g_assert(s > dest); /* loop invariant */ + + switch (*s) + { + case '"': + /* End of the string, return now */ + *dest = '\0'; + ++s; + *end = s; + return TRUE; + break; + + case '\\': + /* Possible escaped quote or \ */ + ++s; + switch (*s) + { + case '"': + case '\\': + case '`': + case '$': + case '\n': + *dest = *s; + ++s; + ++dest; + break; + + default: + /* not an escaped char */ + *dest = '\\'; + ++dest; + /* ++s already done. */ + break; + } + break; + + default: + *dest = *s; + ++dest; + ++s; + break; + } + + g_assert(s > dest); /* loop invariant */ + } + } + else + { + while (*s) + { + g_assert(s > dest); /* loop invariant */ + + if (*s == '\'') + { + /* End of the string, return now */ + *dest = '\0'; + ++s; + *end = s; + return TRUE; + } + else + { + *dest = *s; + ++dest; + ++s; + } + + g_assert(s > dest); /* loop invariant */ + } + } + + /* If we reach here this means the close quote was never encountered */ + + *dest = '\0'; + + g_set_error_literal (err, + G_SHELL_ERROR, + G_SHELL_ERROR_BAD_QUOTING, + _("Unmatched quotation mark in command line or other shell-quoted text")); + *end = s; + return FALSE; +} + +/** + * g_shell_quote: + * @unquoted_string: a literal string + * + * Quotes a string so that the shell (/bin/sh) will interpret the + * quoted string to mean @unquoted_string. If you pass a filename to + * the shell, for example, you should first quote it with this + * function. The return value must be freed with g_free(). The + * quoting style used is undefined (single or double quotes may be + * used). + * + * Return value: quoted string + **/ +gchar* +g_shell_quote (const gchar *unquoted_string) +{ + /* We always use single quotes, because the algorithm is cheesier. + * We could use double if we felt like it, that might be more + * human-readable. + */ + + const gchar *p; + GString *dest; + + g_return_val_if_fail (unquoted_string != NULL, NULL); + + dest = g_string_new ("'"); + + p = unquoted_string; + + /* could speed this up a lot by appending chunks of text at a + * time. + */ + while (*p) + { + /* Replace literal ' with a close ', a \', and a open ' */ + if (*p == '\'') + g_string_append (dest, "'\\''"); + else + g_string_append_c (dest, *p); + + ++p; + } + + /* close the quote */ + g_string_append_c (dest, '\''); + + return g_string_free (dest, FALSE); +} + +/** + * g_shell_unquote: + * @quoted_string: shell-quoted string + * @error: error return location or NULL + * + * Unquotes a string as the shell (/bin/sh) would. Only handles + * quotes; if a string contains file globs, arithmetic operators, + * variables, backticks, redirections, or other special-to-the-shell + * features, the result will be different from the result a real shell + * would produce (the variables, backticks, etc. will be passed + * through literally instead of being expanded). This function is + * guaranteed to succeed if applied to the result of + * g_shell_quote(). If it fails, it returns %NULL and sets the + * error. The @quoted_string need not actually contain quoted or + * escaped text; g_shell_unquote() simply goes through the string and + * unquotes/unescapes anything that the shell would. Both single and + * double quotes are handled, as are escapes including escaped + * newlines. The return value must be freed with g_free(). Possible + * errors are in the #G_SHELL_ERROR domain. + * + * Shell quoting rules are a bit strange. Single quotes preserve the + * literal string exactly. escape sequences are not allowed; not even + * \' - if you want a ' in the quoted text, you have to do something + * like 'foo'\''bar'. Double quotes allow $, `, ", \, and newline to + * be escaped with backslash. Otherwise double quotes preserve things + * literally. + * + * Return value: an unquoted string + **/ +gchar* +g_shell_unquote (const gchar *quoted_string, + GError **error) +{ + gchar *unquoted; + gchar *end; + gchar *start; + GString *retval; + + g_return_val_if_fail (quoted_string != NULL, NULL); + + unquoted = g_strdup (quoted_string); + + start = unquoted; + end = unquoted; + retval = g_string_new (NULL); + + /* The loop allows cases such as + * "foo"blah blah'bar'woo foo"baz"la la la\'\''foo' + */ + while (*start) + { + /* Append all non-quoted chars, honoring backslash escape + */ + + while (*start && !(*start == '"' || *start == '\'')) + { + if (*start == '\\') + { + /* all characters can get escaped by backslash, + * except newline, which is removed if it follows + * a backslash outside of quotes + */ + + ++start; + if (*start) + { + if (*start != '\n') + g_string_append_c (retval, *start); + ++start; + } + } + else + { + g_string_append_c (retval, *start); + ++start; + } + } + + if (*start) + { + if (!unquote_string_inplace (start, &end, error)) + { + goto error; + } + else + { + g_string_append (retval, start); + start = end; + } + } + } + + g_free (unquoted); + return g_string_free (retval, FALSE); + + error: + g_assert (error == NULL || *error != NULL); + + g_free (unquoted); + g_string_free (retval, TRUE); + return NULL; +} + +/* g_parse_argv() does a semi-arbitrary weird subset of the way + * the shell parses a command line. We don't do variable expansion, + * don't understand that operators are tokens, don't do tilde expansion, + * don't do command substitution, no arithmetic expansion, IFS gets ignored, + * don't do filename globs, don't remove redirection stuff, etc. + * + * READ THE UNIX98 SPEC on "Shell Command Language" before changing + * the behavior of this code. + * + * Steps to parsing the argv string: + * + * - tokenize the string (but since we ignore operators, + * our tokenization may diverge from what the shell would do) + * note that tokenization ignores the internals of a quoted + * word and it always splits on spaces, not on IFS even + * if we used IFS. We also ignore "end of input indicator" + * (I guess this is control-D?) + * + * Tokenization steps, from UNIX98 with operator stuff removed, + * are: + * + * 1) "If the current character is backslash, single-quote or + * double-quote (\, ' or ") and it is not quoted, it will affect + * quoting for subsequent characters up to the end of the quoted + * text. The rules for quoting are as described in Quoting + * . During token recognition no substitutions will be actually + * performed, and the result token will contain exactly the + * characters that appear in the input (except for newline + * character joining), unmodified, including any embedded or + * enclosing quotes or substitution operators, between the quote + * mark and the end of the quoted text. The token will not be + * delimited by the end of the quoted field." + * + * 2) "If the current character is an unquoted newline character, + * the current token will be delimited." + * + * 3) "If the current character is an unquoted blank character, any + * token containing the previous character is delimited and the + * current character will be discarded." + * + * 4) "If the previous character was part of a word, the current + * character will be appended to that word." + * + * 5) "If the current character is a "#", it and all subsequent + * characters up to, but excluding, the next newline character + * will be discarded as a comment. The newline character that + * ends the line is not considered part of the comment. The + * "#" starts a comment only when it is at the beginning of a + * token. Since the search for the end-of-comment does not + * consider an escaped newline character specially, a comment + * cannot be continued to the next line." + * + * 6) "The current character will be used as the start of a new word." + * + * + * - for each token (word), perform portions of word expansion, namely + * field splitting (using default whitespace IFS) and quote + * removal. Field splitting may increase the number of words. + * Quote removal does not increase the number of words. + * + * "If the complete expansion appropriate for a word results in an + * empty field, that empty field will be deleted from the list of + * fields that form the completely expanded command, unless the + * original word contained single-quote or double-quote characters." + * - UNIX98 spec + * + * + */ + +static inline void +ensure_token (GString **token) +{ + if (*token == NULL) + *token = g_string_new (NULL); +} + +static void +delimit_token (GString **token, + GSList **retval) +{ + if (*token == NULL) + return; + + *retval = g_slist_prepend (*retval, g_string_free (*token, FALSE)); + + *token = NULL; +} + +static GSList* +tokenize_command_line (const gchar *command_line, + GError **error) +{ + gchar current_quote; + const gchar *p; + GString *current_token = NULL; + GSList *retval = NULL; + gboolean quoted; + + current_quote = '\0'; + quoted = FALSE; + p = command_line; + + while (*p) + { + if (current_quote == '\\') + { + if (*p == '\n') + { + /* we append nothing; backslash-newline become nothing */ + } + else + { + /* we append the backslash and the current char, + * to be interpreted later after tokenization + */ + ensure_token (¤t_token); + g_string_append_c (current_token, '\\'); + g_string_append_c (current_token, *p); + } + + current_quote = '\0'; + } + else if (current_quote == '#') + { + /* Discard up to and including next newline */ + while (*p && *p != '\n') + ++p; + + current_quote = '\0'; + + if (*p == '\0') + break; + } + else if (current_quote) + { + if (*p == current_quote && + /* check that it isn't an escaped double quote */ + !(current_quote == '"' && quoted)) + { + /* close the quote */ + current_quote = '\0'; + } + + /* Everything inside quotes, and the close quote, + * gets appended literally. + */ + + ensure_token (¤t_token); + g_string_append_c (current_token, *p); + } + else + { + switch (*p) + { + case '\n': + delimit_token (¤t_token, &retval); + break; + + case ' ': + case '\t': + /* If the current token contains the previous char, delimit + * the current token. A nonzero length + * token should always contain the previous char. + */ + if (current_token && + current_token->len > 0) + { + delimit_token (¤t_token, &retval); + } + + /* discard all unquoted blanks (don't add them to a token) */ + break; + + + /* single/double quotes are appended to the token, + * escapes are maybe appended next time through the loop, + * comment chars are never appended. + */ + + case '\'': + case '"': + ensure_token (¤t_token); + g_string_append_c (current_token, *p); + + /* FALL THRU */ + + case '#': + case '\\': + current_quote = *p; + break; + + default: + /* Combines rules 4) and 6) - if we have a token, append to it, + * otherwise create a new token. + */ + ensure_token (¤t_token); + g_string_append_c (current_token, *p); + break; + } + } + + /* We need to count consecutive backslashes mod 2, + * to detect escaped doublequotes. + */ + if (*p != '\\') + quoted = FALSE; + else + quoted = !quoted; + + ++p; + } + + delimit_token (¤t_token, &retval); + + if (current_quote) + { + if (current_quote == '\\') + g_set_error (error, + G_SHELL_ERROR, + G_SHELL_ERROR_BAD_QUOTING, + _("Text ended just after a '\\' character." + " (The text was '%s')"), + command_line); + else + g_set_error (error, + G_SHELL_ERROR, + G_SHELL_ERROR_BAD_QUOTING, + _("Text ended before matching quote was found for %c." + " (The text was '%s')"), + current_quote, command_line); + + goto error; + } + + if (retval == NULL) + { + g_set_error_literal (error, + G_SHELL_ERROR, + G_SHELL_ERROR_EMPTY_STRING, + _("Text was empty (or contained only whitespace)")); + + goto error; + } + + /* we appended backward */ + retval = g_slist_reverse (retval); + + return retval; + + error: + g_assert (error == NULL || *error != NULL); + + g_slist_free_full (retval, g_free); + + return NULL; +} + +/** + * g_shell_parse_argv: + * @command_line: command line to parse + * @argcp: (out): return location for number of args + * @argvp: (out) (array length=argcp zero-terminated=1): return location for array of args + * @error: return location for error + * + * Parses a command line into an argument vector, in much the same way + * the shell would, but without many of the expansions the shell would + * perform (variable expansion, globs, operators, filename expansion, + * etc. are not supported). The results are defined to be the same as + * those you would get from a UNIX98 /bin/sh, as long as the input + * contains none of the unsupported shell expansions. If the input + * does contain such expansions, they are passed through + * literally. Possible errors are those from the #G_SHELL_ERROR + * domain. Free the returned vector with g_strfreev(). + * + * Return value: %TRUE on success, %FALSE if error set + **/ +gboolean +g_shell_parse_argv (const gchar *command_line, + gint *argcp, + gchar ***argvp, + GError **error) +{ + /* Code based on poptParseArgvString() from libpopt */ + gint argc = 0; + gchar **argv = NULL; + GSList *tokens = NULL; + gint i; + GSList *tmp_list; + + g_return_val_if_fail (command_line != NULL, FALSE); + + tokens = tokenize_command_line (command_line, error); + if (tokens == NULL) + return FALSE; + + /* Because we can't have introduced any new blank space into the + * tokens (we didn't do any new expansions), we don't need to + * perform field splitting. If we were going to honor IFS or do any + * expansions, we would have to do field splitting on each word + * here. Also, if we were going to do any expansion we would need to + * remove any zero-length words that didn't contain quotes + * originally; but since there's no expansion we know all words have + * nonzero length, unless they contain quotes. + * + * So, we simply remove quotes, and don't do any field splitting or + * empty word removal, since we know there was no way to introduce + * such things. + */ + + argc = g_slist_length (tokens); + argv = g_new0 (gchar*, argc + 1); + i = 0; + tmp_list = tokens; + while (tmp_list) + { + argv[i] = g_shell_unquote (tmp_list->data, error); + + /* Since we already checked that quotes matched up in the + * tokenizer, this shouldn't be possible to reach I guess. + */ + if (argv[i] == NULL) + goto failed; + + tmp_list = g_slist_next (tmp_list); + ++i; + } + + g_slist_free_full (tokens, g_free); + + if (argcp) + *argcp = argc; + + if (argvp) + *argvp = argv; + else + g_strfreev (argv); + + return TRUE; + + failed: + + g_assert (error == NULL || *error != NULL); + g_strfreev (argv); + g_slist_free_full (tokens, g_free); + + return FALSE; +} diff --git a/glib/glib/gshell.h b/glib/glib/gshell.h new file mode 100644 index 0000000..ddb4ec5 --- /dev/null +++ b/glib/glib/gshell.h @@ -0,0 +1,55 @@ +/* gshell.h - Shell-related utilities + * + * Copyright 2000 Red Hat, Inc. + * + * GLib is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, write + * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_SHELL_H__ +#define __G_SHELL_H__ + +#include + +G_BEGIN_DECLS + +#define G_SHELL_ERROR g_shell_error_quark () + +typedef enum +{ + /* mismatched or otherwise mangled quoting */ + G_SHELL_ERROR_BAD_QUOTING, + /* string to be parsed was empty */ + G_SHELL_ERROR_EMPTY_STRING, + G_SHELL_ERROR_FAILED +} GShellError; + +GQuark g_shell_error_quark (void); + +gchar* g_shell_quote (const gchar *unquoted_string); +gchar* g_shell_unquote (const gchar *quoted_string, + GError **error); +gboolean g_shell_parse_argv (const gchar *command_line, + gint *argcp, + gchar ***argvp, + GError **error); + +G_END_DECLS + +#endif /* __G_SHELL_H__ */ diff --git a/glib/glib/gslice.c b/glib/glib/gslice.c new file mode 100644 index 0000000..b70724d --- /dev/null +++ b/glib/glib/gslice.c @@ -0,0 +1,1718 @@ +/* GLIB sliced memory - fast concurrent memory chunk allocator + * Copyright (C) 2005 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +/* MT safe */ + +#include "config.h" +#include "glibconfig.h" + +#if defined HAVE_POSIX_MEMALIGN && defined POSIX_MEMALIGN_WITH_COMPLIANT_ALLOCS +# define HAVE_COMPLIANT_POSIX_MEMALIGN 1 +#endif + +#if defined(HAVE_COMPLIANT_POSIX_MEMALIGN) && !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 600 /* posix_memalign() */ +#endif +#include /* posix_memalign() */ +#include +#include + +#ifdef HAVE_UNISTD_H +#include /* sysconf() */ +#endif +#ifdef G_OS_WIN32 +#include +#include +#endif + +#include /* fputs/fprintf */ + +#include "gslice.h" + +#include "gmain.h" +#include "gmem.h" /* gslice.h */ +#include "gstrfuncs.h" +#include "gutils.h" +#include "gtrashstack.h" +#include "gtestutils.h" +#include "gthread.h" +#include "glib_trace.h" + +/** + * SECTION:memory_slices + * @title: Memory Slices + * @short_description: efficient way to allocate groups of equal-sized + * chunks of memory + * + * Memory slices provide a space-efficient and multi-processing scalable + * way to allocate equal-sized pieces of memory, just like the original + * #GMemChunks (from GLib 2.8), while avoiding their excessive + * memory-waste, scalability and performance problems. + * + * To achieve these goals, the slice allocator uses a sophisticated, + * layered design that has been inspired by Bonwick's slab allocator + * + * [Bonwick94] Jeff Bonwick, The slab allocator: An object-caching kernel + * memory allocator. USENIX 1994, and + * [Bonwick01] Bonwick and Jonathan Adams, Magazines and vmem: Extending the + * slab allocator to many cpu's and arbitrary resources. USENIX 2001 + * . + * It uses posix_memalign() to optimize allocations of many equally-sized + * chunks, and has per-thread free lists (the so-called magazine layer) + * to quickly satisfy allocation requests of already known structure sizes. + * This is accompanied by extra caching logic to keep freed memory around + * for some time before returning it to the system. Memory that is unused + * due to alignment constraints is used for cache colorization (random + * distribution of chunk addresses) to improve CPU cache utilization. The + * caching layer of the slice allocator adapts itself to high lock contention + * to improve scalability. + * + * The slice allocator can allocate blocks as small as two pointers, and + * unlike malloc(), it does not reserve extra space per block. For large block + * sizes, g_slice_new() and g_slice_alloc() will automatically delegate to the + * system malloc() implementation. For newly written code it is recommended + * to use the new g_slice API instead of g_malloc() and + * friends, as long as objects are not resized during their lifetime and the + * object size used at allocation time is still available when freeing. + * + * + * Using the slice allocator + * + * gchar *mem[10000]; + * gint i; + * + * /* Allocate 10000 blocks. */ + * for (i = 0; i < 10000; i++) + * { + * mem[i] = g_slice_alloc (50); + * + * /* Fill in the memory with some junk. */ + * for (j = 0; j < 50; j++) + * mem[i][j] = i * j; + * } + * + * /* Now free all of the blocks. */ + * for (i = 0; i < 10000; i++) + * { + * g_slice_free1 (50, mem[i]); + * } + * + * + * + * Using the slice allocator with data structures + * + * GRealArray *array; + * + * /* Allocate one block, using the g_slice_new() macro. */ + * array = g_slice_new (GRealArray); + + * /* We can now use array just like a normal pointer to a structure. */ + * array->data = NULL; + * array->len = 0; + * array->alloc = 0; + * array->zero_terminated = (zero_terminated ? 1 : 0); + * array->clear = (clear ? 1 : 0); + * array->elt_size = elt_size; + * + * /* We can free the block, so it can be reused. */ + * g_slice_free (GRealArray, array); + * + */ + +/* the GSlice allocator is split up into 4 layers, roughly modelled after the slab + * allocator and magazine extensions as outlined in: + * + [Bonwick94] Jeff Bonwick, The slab allocator: An object-caching kernel + * memory allocator. USENIX 1994, http://citeseer.ist.psu.edu/bonwick94slab.html + * + [Bonwick01] Bonwick and Jonathan Adams, Magazines and vmem: Extending the + * slab allocator to many cpu's and arbitrary resources. + * USENIX 2001, http://citeseer.ist.psu.edu/bonwick01magazines.html + * the layers are: + * - the thread magazines. for each (aligned) chunk size, a magazine (a list) + * of recently freed and soon to be allocated chunks is maintained per thread. + * this way, most alloc/free requests can be quickly satisfied from per-thread + * free lists which only require one g_private_get() call to retrive the + * thread handle. + * - the magazine cache. allocating and freeing chunks to/from threads only + * occours at magazine sizes from a global depot of magazines. the depot + * maintaines a 15 second working set of allocated magazines, so full + * magazines are not allocated and released too often. + * the chunk size dependent magazine sizes automatically adapt (within limits, + * see [3]) to lock contention to properly scale performance across a variety + * of SMP systems. + * - the slab allocator. this allocator allocates slabs (blocks of memory) close + * to the system page size or multiples thereof which have to be page aligned. + * the blocks are divided into smaller chunks which are used to satisfy + * allocations from the upper layers. the space provided by the reminder of + * the chunk size division is used for cache colorization (random distribution + * of chunk addresses) to improve processor cache utilization. multiple slabs + * with the same chunk size are kept in a partially sorted ring to allow O(1) + * freeing and allocation of chunks (as long as the allocation of an entirely + * new slab can be avoided). + * - the page allocator. on most modern systems, posix_memalign(3) or + * memalign(3) should be available, so this is used to allocate blocks with + * system page size based alignments and sizes or multiples thereof. + * if no memalign variant is provided, valloc() is used instead and + * block sizes are limited to the system page size (no multiples thereof). + * as a fallback, on system without even valloc(), a malloc(3)-based page + * allocator with alloc-only behaviour is used. + * + * NOTES: + * [1] some systems memalign(3) implementations may rely on boundary tagging for + * the handed out memory chunks. to avoid excessive page-wise fragmentation, + * we reserve 2 * sizeof (void*) per block size for the systems memalign(3), + * specified in NATIVE_MALLOC_PADDING. + * [2] using the slab allocator alone already provides for a fast and efficient + * allocator, it doesn't properly scale beyond single-threaded uses though. + * also, the slab allocator implements eager free(3)-ing, i.e. does not + * provide any form of caching or working set maintenance. so if used alone, + * it's vulnerable to trashing for sequences of balanced (alloc, free) pairs + * at certain thresholds. + * [3] magazine sizes are bound by an implementation specific minimum size and + * a chunk size specific maximum to limit magazine storage sizes to roughly + * 16KB. + * [4] allocating ca. 8 chunks per block/page keeps a good balance between + * external and internal fragmentation (<= 12.5%). [Bonwick94] + */ + +/* --- macros and constants --- */ +#define LARGEALIGNMENT (256) +#define P2ALIGNMENT (2 * sizeof (gsize)) /* fits 2 pointers (assumed to be 2 * GLIB_SIZEOF_SIZE_T below) */ +#define ALIGN(size, base) ((base) * (gsize) (((size) + (base) - 1) / (base))) +#define NATIVE_MALLOC_PADDING P2ALIGNMENT /* per-page padding left for native malloc(3) see [1] */ +#define SLAB_INFO_SIZE P2ALIGN (sizeof (SlabInfo) + NATIVE_MALLOC_PADDING) +#define MAX_MAGAZINE_SIZE (256) /* see [3] and allocator_get_magazine_threshold() for this */ +#define MIN_MAGAZINE_SIZE (4) +#define MAX_STAMP_COUNTER (7) /* distributes the load of gettimeofday() */ +#define MAX_SLAB_CHUNK_SIZE(al) (((al)->max_page_size - SLAB_INFO_SIZE) / 8) /* we want at last 8 chunks per page, see [4] */ +#define MAX_SLAB_INDEX(al) (SLAB_INDEX (al, MAX_SLAB_CHUNK_SIZE (al)) + 1) +#define SLAB_INDEX(al, asize) ((asize) / P2ALIGNMENT - 1) /* asize must be P2ALIGNMENT aligned */ +#define SLAB_CHUNK_SIZE(al, ix) (((ix) + 1) * P2ALIGNMENT) +#define SLAB_BPAGE_SIZE(al,csz) (8 * (csz) + SLAB_INFO_SIZE) + +/* optimized version of ALIGN (size, P2ALIGNMENT) */ +#if GLIB_SIZEOF_SIZE_T * 2 == 8 /* P2ALIGNMENT */ +#define P2ALIGN(size) (((size) + 0x7) & ~(gsize) 0x7) +#elif GLIB_SIZEOF_SIZE_T * 2 == 16 /* P2ALIGNMENT */ +#define P2ALIGN(size) (((size) + 0xf) & ~(gsize) 0xf) +#else +#define P2ALIGN(size) ALIGN (size, P2ALIGNMENT) +#endif + +/* special helpers to avoid gmessage.c dependency */ +static void mem_error (const char *format, ...) G_GNUC_PRINTF (1,2); +#define mem_assert(cond) do { if (G_LIKELY (cond)) ; else mem_error ("assertion failed: %s", #cond); } while (0) + +/* --- structures --- */ +typedef struct _ChunkLink ChunkLink; +typedef struct _SlabInfo SlabInfo; +typedef struct _CachedMagazine CachedMagazine; +struct _ChunkLink { + ChunkLink *next; + ChunkLink *data; +}; +struct _SlabInfo { + ChunkLink *chunks; + guint n_allocated; + SlabInfo *next, *prev; +}; +typedef struct { + ChunkLink *chunks; + gsize count; /* approximative chunks list length */ +} Magazine; +typedef struct { + Magazine *magazine1; /* array of MAX_SLAB_INDEX (allocator) */ + Magazine *magazine2; /* array of MAX_SLAB_INDEX (allocator) */ +} ThreadMemory; +typedef struct { + gboolean always_malloc; + gboolean bypass_magazines; + gboolean debug_blocks; + gsize working_set_msecs; + guint color_increment; +} SliceConfig; +typedef struct { + /* const after initialization */ + gsize min_page_size, max_page_size; + SliceConfig config; + gsize max_slab_chunk_size_for_magazine_cache; + /* magazine cache */ + GMutex magazine_mutex; + ChunkLink **magazines; /* array of MAX_SLAB_INDEX (allocator) */ + guint *contention_counters; /* array of MAX_SLAB_INDEX (allocator) */ + gint mutex_counter; + guint stamp_counter; + guint last_stamp; + /* slab allocator */ + GMutex slab_mutex; + SlabInfo **slab_stack; /* array of MAX_SLAB_INDEX (allocator) */ + guint color_accu; +} Allocator; + +/* --- g-slice prototypes --- */ +static gpointer slab_allocator_alloc_chunk (gsize chunk_size); +static void slab_allocator_free_chunk (gsize chunk_size, + gpointer mem); +static void private_thread_memory_cleanup (gpointer data); +static gpointer allocator_memalign (gsize alignment, + gsize memsize); +static void allocator_memfree (gsize memsize, + gpointer mem); +static inline void magazine_cache_update_stamp (void); +static inline gsize allocator_get_magazine_threshold (Allocator *allocator, + guint ix); + +/* --- g-slice memory checker --- */ +static void smc_notify_alloc (void *pointer, + size_t size); +static int smc_notify_free (void *pointer, + size_t size); + +/* --- variables --- */ +static GPrivate private_thread_memory = G_PRIVATE_INIT (private_thread_memory_cleanup); +static gsize sys_page_size = 0; +static Allocator allocator[1] = { { 0, }, }; +static SliceConfig slice_config = { + FALSE, /* always_malloc */ + FALSE, /* bypass_magazines */ + FALSE, /* debug_blocks */ + 15 * 1000, /* working_set_msecs */ + 1, /* color increment, alt: 0x7fffffff */ +}; +static GMutex smc_tree_mutex; /* mutex for G_SLICE=debug-blocks */ + +/* --- auxiliary funcitons --- */ +void +g_slice_set_config (GSliceConfig ckey, + gint64 value) +{ + g_return_if_fail (sys_page_size == 0); + switch (ckey) + { + case G_SLICE_CONFIG_ALWAYS_MALLOC: + slice_config.always_malloc = value != 0; + break; + case G_SLICE_CONFIG_BYPASS_MAGAZINES: + slice_config.bypass_magazines = value != 0; + break; + case G_SLICE_CONFIG_WORKING_SET_MSECS: + slice_config.working_set_msecs = value; + break; + case G_SLICE_CONFIG_COLOR_INCREMENT: + slice_config.color_increment = value; + default: ; + } +} + +gint64 +g_slice_get_config (GSliceConfig ckey) +{ + switch (ckey) + { + case G_SLICE_CONFIG_ALWAYS_MALLOC: + return slice_config.always_malloc; + case G_SLICE_CONFIG_BYPASS_MAGAZINES: + return slice_config.bypass_magazines; + case G_SLICE_CONFIG_WORKING_SET_MSECS: + return slice_config.working_set_msecs; + case G_SLICE_CONFIG_CHUNK_SIZES: + return MAX_SLAB_INDEX (allocator); + case G_SLICE_CONFIG_COLOR_INCREMENT: + return slice_config.color_increment; + default: + return 0; + } +} + +gint64* +g_slice_get_config_state (GSliceConfig ckey, + gint64 address, + guint *n_values) +{ + guint i = 0; + g_return_val_if_fail (n_values != NULL, NULL); + *n_values = 0; + switch (ckey) + { + gint64 array[64]; + case G_SLICE_CONFIG_CONTENTION_COUNTER: + array[i++] = SLAB_CHUNK_SIZE (allocator, address); + array[i++] = allocator->contention_counters[address]; + array[i++] = allocator_get_magazine_threshold (allocator, address); + *n_values = i; + return g_memdup (array, sizeof (array[0]) * *n_values); + default: + return NULL; + } +} + +static void +slice_config_init (SliceConfig *config) +{ + const gchar *val; + + *config = slice_config; + + val = getenv ("G_SLICE"); + if (val != NULL) + { + gint flags; + const GDebugKey keys[] = { + { "always-malloc", 1 << 0 }, + { "debug-blocks", 1 << 1 }, + }; + + flags = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys)); + if (flags & (1 << 0)) + config->always_malloc = TRUE; + if (flags & (1 << 1)) + config->debug_blocks = TRUE; + } +} + +static void +g_slice_init_nomessage (void) +{ + /* we may not use g_error() or friends here */ + mem_assert (sys_page_size == 0); + mem_assert (MIN_MAGAZINE_SIZE >= 4); + +#ifdef G_OS_WIN32 + { + SYSTEM_INFO system_info; + GetSystemInfo (&system_info); + sys_page_size = system_info.dwPageSize; + } +#else + sys_page_size = sysconf (_SC_PAGESIZE); /* = sysconf (_SC_PAGE_SIZE); = getpagesize(); */ +#endif + mem_assert (sys_page_size >= 2 * LARGEALIGNMENT); + mem_assert ((sys_page_size & (sys_page_size - 1)) == 0); + slice_config_init (&allocator->config); + allocator->min_page_size = sys_page_size; +#if HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN + /* allow allocation of pages up to 8KB (with 8KB alignment). + * this is useful because many medium to large sized structures + * fit less than 8 times (see [4]) into 4KB pages. + * we allow very small page sizes here, to reduce wastage in + * threads if only small allocations are required (this does + * bear the risk of increasing allocation times and fragmentation + * though). + */ + allocator->min_page_size = MAX (allocator->min_page_size, 4096); + allocator->max_page_size = MAX (allocator->min_page_size, 8192); + allocator->min_page_size = MIN (allocator->min_page_size, 128); +#else + /* we can only align to system page size */ + allocator->max_page_size = sys_page_size; +#endif + if (allocator->config.always_malloc) + { + allocator->contention_counters = NULL; + allocator->magazines = NULL; + allocator->slab_stack = NULL; + } + else + { + allocator->contention_counters = g_new0 (guint, MAX_SLAB_INDEX (allocator)); + allocator->magazines = g_new0 (ChunkLink*, MAX_SLAB_INDEX (allocator)); + allocator->slab_stack = g_new0 (SlabInfo*, MAX_SLAB_INDEX (allocator)); + } + + g_mutex_init (&allocator->magazine_mutex); + allocator->mutex_counter = 0; + allocator->stamp_counter = MAX_STAMP_COUNTER; /* force initial update */ + allocator->last_stamp = 0; + g_mutex_init (&allocator->slab_mutex); + allocator->color_accu = 0; + magazine_cache_update_stamp(); + /* values cached for performance reasons */ + allocator->max_slab_chunk_size_for_magazine_cache = MAX_SLAB_CHUNK_SIZE (allocator); + if (allocator->config.always_malloc || allocator->config.bypass_magazines) + allocator->max_slab_chunk_size_for_magazine_cache = 0; /* non-optimized cases */ +} + +static inline guint +allocator_categorize (gsize aligned_chunk_size) +{ + /* speed up the likely path */ + if (G_LIKELY (aligned_chunk_size && aligned_chunk_size <= allocator->max_slab_chunk_size_for_magazine_cache)) + return 1; /* use magazine cache */ + + if (!allocator->config.always_malloc && + aligned_chunk_size && + aligned_chunk_size <= MAX_SLAB_CHUNK_SIZE (allocator)) + { + if (allocator->config.bypass_magazines) + return 2; /* use slab allocator, see [2] */ + return 1; /* use magazine cache */ + } + return 0; /* use malloc() */ +} + +static inline void +g_mutex_lock_a (GMutex *mutex, + guint *contention_counter) +{ + gboolean contention = FALSE; + if (!g_mutex_trylock (mutex)) + { + g_mutex_lock (mutex); + contention = TRUE; + } + if (contention) + { + allocator->mutex_counter++; + if (allocator->mutex_counter >= 1) /* quickly adapt to contention */ + { + allocator->mutex_counter = 0; + *contention_counter = MIN (*contention_counter + 1, MAX_MAGAZINE_SIZE); + } + } + else /* !contention */ + { + allocator->mutex_counter--; + if (allocator->mutex_counter < -11) /* moderately recover magazine sizes */ + { + allocator->mutex_counter = 0; + *contention_counter = MAX (*contention_counter, 1) - 1; + } + } +} + +static inline ThreadMemory* +thread_memory_from_self (void) +{ + ThreadMemory *tmem = g_private_get (&private_thread_memory); + if (G_UNLIKELY (!tmem)) + { + static GMutex init_mutex; + guint n_magazines; + + g_mutex_lock (&init_mutex); + if G_UNLIKELY (sys_page_size == 0) + g_slice_init_nomessage (); + g_mutex_unlock (&init_mutex); + + n_magazines = MAX_SLAB_INDEX (allocator); + tmem = g_malloc0 (sizeof (ThreadMemory) + sizeof (Magazine) * 2 * n_magazines); + tmem->magazine1 = (Magazine*) (tmem + 1); + tmem->magazine2 = &tmem->magazine1[n_magazines]; + g_private_set (&private_thread_memory, tmem); + } + return tmem; +} + +static inline ChunkLink* +magazine_chain_pop_head (ChunkLink **magazine_chunks) +{ + /* magazine chains are linked via ChunkLink->next. + * each ChunkLink->data of the toplevel chain may point to a subchain, + * linked via ChunkLink->next. ChunkLink->data of the subchains just + * contains uninitialized junk. + */ + ChunkLink *chunk = (*magazine_chunks)->data; + if (G_UNLIKELY (chunk)) + { + /* allocating from freed list */ + (*magazine_chunks)->data = chunk->next; + } + else + { + chunk = *magazine_chunks; + *magazine_chunks = chunk->next; + } + return chunk; +} + +#if 0 /* useful for debugging */ +static guint +magazine_count (ChunkLink *head) +{ + guint count = 0; + if (!head) + return 0; + while (head) + { + ChunkLink *child = head->data; + count += 1; + for (child = head->data; child; child = child->next) + count += 1; + head = head->next; + } + return count; +} +#endif + +static inline gsize +allocator_get_magazine_threshold (Allocator *allocator, + guint ix) +{ + /* the magazine size calculated here has a lower bound of MIN_MAGAZINE_SIZE, + * which is required by the implementation. also, for moderately sized chunks + * (say >= 64 bytes), magazine sizes shouldn't be much smaller then the number + * of chunks available per page/2 to avoid excessive traffic in the magazine + * cache for small to medium sized structures. + * the upper bound of the magazine size is effectively provided by + * MAX_MAGAZINE_SIZE. for larger chunks, this number is scaled down so that + * the content of a single magazine doesn't exceed ca. 16KB. + */ + gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix); + guint threshold = MAX (MIN_MAGAZINE_SIZE, allocator->max_page_size / MAX (5 * chunk_size, 5 * 32)); + guint contention_counter = allocator->contention_counters[ix]; + if (G_UNLIKELY (contention_counter)) /* single CPU bias */ + { + /* adapt contention counter thresholds to chunk sizes */ + contention_counter = contention_counter * 64 / chunk_size; + threshold = MAX (threshold, contention_counter); + } + return threshold; +} + +/* --- magazine cache --- */ +static inline void +magazine_cache_update_stamp (void) +{ + if (allocator->stamp_counter >= MAX_STAMP_COUNTER) + { + GTimeVal tv; + g_get_current_time (&tv); + allocator->last_stamp = tv.tv_sec * 1000 + tv.tv_usec / 1000; /* milli seconds */ + allocator->stamp_counter = 0; + } + else + allocator->stamp_counter++; +} + +static inline ChunkLink* +magazine_chain_prepare_fields (ChunkLink *magazine_chunks) +{ + ChunkLink *chunk1; + ChunkLink *chunk2; + ChunkLink *chunk3; + ChunkLink *chunk4; + /* checked upon initialization: mem_assert (MIN_MAGAZINE_SIZE >= 4); */ + /* ensure a magazine with at least 4 unused data pointers */ + chunk1 = magazine_chain_pop_head (&magazine_chunks); + chunk2 = magazine_chain_pop_head (&magazine_chunks); + chunk3 = magazine_chain_pop_head (&magazine_chunks); + chunk4 = magazine_chain_pop_head (&magazine_chunks); + chunk4->next = magazine_chunks; + chunk3->next = chunk4; + chunk2->next = chunk3; + chunk1->next = chunk2; + return chunk1; +} + +/* access the first 3 fields of a specially prepared magazine chain */ +#define magazine_chain_prev(mc) ((mc)->data) +#define magazine_chain_stamp(mc) ((mc)->next->data) +#define magazine_chain_uint_stamp(mc) GPOINTER_TO_UINT ((mc)->next->data) +#define magazine_chain_next(mc) ((mc)->next->next->data) +#define magazine_chain_count(mc) ((mc)->next->next->next->data) + +static void +magazine_cache_trim (Allocator *allocator, + guint ix, + guint stamp) +{ + /* g_mutex_lock (allocator->mutex); done by caller */ + /* trim magazine cache from tail */ + ChunkLink *current = magazine_chain_prev (allocator->magazines[ix]); + ChunkLink *trash = NULL; + while (ABS (stamp - magazine_chain_uint_stamp (current)) >= allocator->config.working_set_msecs) + { + /* unlink */ + ChunkLink *prev = magazine_chain_prev (current); + ChunkLink *next = magazine_chain_next (current); + magazine_chain_next (prev) = next; + magazine_chain_prev (next) = prev; + /* clear special fields, put on trash stack */ + magazine_chain_next (current) = NULL; + magazine_chain_count (current) = NULL; + magazine_chain_stamp (current) = NULL; + magazine_chain_prev (current) = trash; + trash = current; + /* fixup list head if required */ + if (current == allocator->magazines[ix]) + { + allocator->magazines[ix] = NULL; + break; + } + current = prev; + } + g_mutex_unlock (&allocator->magazine_mutex); + /* free trash */ + if (trash) + { + const gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix); + g_mutex_lock (&allocator->slab_mutex); + while (trash) + { + current = trash; + trash = magazine_chain_prev (current); + magazine_chain_prev (current) = NULL; /* clear special field */ + while (current) + { + ChunkLink *chunk = magazine_chain_pop_head (¤t); + slab_allocator_free_chunk (chunk_size, chunk); + } + } + g_mutex_unlock (&allocator->slab_mutex); + } +} + +static void +magazine_cache_push_magazine (guint ix, + ChunkLink *magazine_chunks, + gsize count) /* must be >= MIN_MAGAZINE_SIZE */ +{ + ChunkLink *current = magazine_chain_prepare_fields (magazine_chunks); + ChunkLink *next, *prev; + g_mutex_lock (&allocator->magazine_mutex); + /* add magazine at head */ + next = allocator->magazines[ix]; + if (next) + prev = magazine_chain_prev (next); + else + next = prev = current; + magazine_chain_next (prev) = current; + magazine_chain_prev (next) = current; + magazine_chain_prev (current) = prev; + magazine_chain_next (current) = next; + magazine_chain_count (current) = (gpointer) count; + /* stamp magazine */ + magazine_cache_update_stamp(); + magazine_chain_stamp (current) = GUINT_TO_POINTER (allocator->last_stamp); + allocator->magazines[ix] = current; + /* free old magazines beyond a certain threshold */ + magazine_cache_trim (allocator, ix, allocator->last_stamp); + /* g_mutex_unlock (allocator->mutex); was done by magazine_cache_trim() */ +} + +static ChunkLink* +magazine_cache_pop_magazine (guint ix, + gsize *countp) +{ + g_mutex_lock_a (&allocator->magazine_mutex, &allocator->contention_counters[ix]); + if (!allocator->magazines[ix]) + { + guint magazine_threshold = allocator_get_magazine_threshold (allocator, ix); + gsize i, chunk_size = SLAB_CHUNK_SIZE (allocator, ix); + ChunkLink *chunk, *head; + g_mutex_unlock (&allocator->magazine_mutex); + g_mutex_lock (&allocator->slab_mutex); + head = slab_allocator_alloc_chunk (chunk_size); + head->data = NULL; + chunk = head; + for (i = 1; i < magazine_threshold; i++) + { + chunk->next = slab_allocator_alloc_chunk (chunk_size); + chunk = chunk->next; + chunk->data = NULL; + } + chunk->next = NULL; + g_mutex_unlock (&allocator->slab_mutex); + *countp = i; + return head; + } + else + { + ChunkLink *current = allocator->magazines[ix]; + ChunkLink *prev = magazine_chain_prev (current); + ChunkLink *next = magazine_chain_next (current); + /* unlink */ + magazine_chain_next (prev) = next; + magazine_chain_prev (next) = prev; + allocator->magazines[ix] = next == current ? NULL : next; + g_mutex_unlock (&allocator->magazine_mutex); + /* clear special fields and hand out */ + *countp = (gsize) magazine_chain_count (current); + magazine_chain_prev (current) = NULL; + magazine_chain_next (current) = NULL; + magazine_chain_count (current) = NULL; + magazine_chain_stamp (current) = NULL; + return current; + } +} + +/* --- thread magazines --- */ +static void +private_thread_memory_cleanup (gpointer data) +{ + ThreadMemory *tmem = data; + const guint n_magazines = MAX_SLAB_INDEX (allocator); + guint ix; + for (ix = 0; ix < n_magazines; ix++) + { + Magazine *mags[2]; + guint j; + mags[0] = &tmem->magazine1[ix]; + mags[1] = &tmem->magazine2[ix]; + for (j = 0; j < 2; j++) + { + Magazine *mag = mags[j]; + if (mag->count >= MIN_MAGAZINE_SIZE) + magazine_cache_push_magazine (ix, mag->chunks, mag->count); + else + { + const gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix); + g_mutex_lock (&allocator->slab_mutex); + while (mag->chunks) + { + ChunkLink *chunk = magazine_chain_pop_head (&mag->chunks); + slab_allocator_free_chunk (chunk_size, chunk); + } + g_mutex_unlock (&allocator->slab_mutex); + } + } + } + g_free (tmem); +} + +static void +thread_memory_magazine1_reload (ThreadMemory *tmem, + guint ix) +{ + Magazine *mag = &tmem->magazine1[ix]; + mem_assert (mag->chunks == NULL); /* ensure that we may reset mag->count */ + mag->count = 0; + mag->chunks = magazine_cache_pop_magazine (ix, &mag->count); +} + +static void +thread_memory_magazine2_unload (ThreadMemory *tmem, + guint ix) +{ + Magazine *mag = &tmem->magazine2[ix]; + magazine_cache_push_magazine (ix, mag->chunks, mag->count); + mag->chunks = NULL; + mag->count = 0; +} + +static inline void +thread_memory_swap_magazines (ThreadMemory *tmem, + guint ix) +{ + Magazine xmag = tmem->magazine1[ix]; + tmem->magazine1[ix] = tmem->magazine2[ix]; + tmem->magazine2[ix] = xmag; +} + +static inline gboolean +thread_memory_magazine1_is_empty (ThreadMemory *tmem, + guint ix) +{ + return tmem->magazine1[ix].chunks == NULL; +} + +static inline gboolean +thread_memory_magazine2_is_full (ThreadMemory *tmem, + guint ix) +{ + return tmem->magazine2[ix].count >= allocator_get_magazine_threshold (allocator, ix); +} + +static inline gpointer +thread_memory_magazine1_alloc (ThreadMemory *tmem, + guint ix) +{ + Magazine *mag = &tmem->magazine1[ix]; + ChunkLink *chunk = magazine_chain_pop_head (&mag->chunks); + if (G_LIKELY (mag->count > 0)) + mag->count--; + return chunk; +} + +static inline void +thread_memory_magazine2_free (ThreadMemory *tmem, + guint ix, + gpointer mem) +{ + Magazine *mag = &tmem->magazine2[ix]; + ChunkLink *chunk = mem; + chunk->data = NULL; + chunk->next = mag->chunks; + mag->chunks = chunk; + mag->count++; +} + +/* --- API functions --- */ + +/** + * g_slice_new: + * @type: the type to allocate, typically a structure name + * + * A convenience macro to allocate a block of memory from the + * slice allocator. + * + * It calls g_slice_alloc() with sizeof (@type) + * and casts the returned pointer to a pointer of the given type, + * avoiding a type cast in the source code. + * Note that the underlying slice allocation mechanism can + * be changed with the G_SLICE=always-malloc + * environment variable. + * + * Returns: a pointer to the allocated block, cast to a pointer to @type + * + * Since: 2.10 + */ + +/** + * g_slice_new0: + * @type: the type to allocate, typically a structure name + * + * A convenience macro to allocate a block of memory from the + * slice allocator and set the memory to 0. + * + * It calls g_slice_alloc0() with sizeof (@type) + * and casts the returned pointer to a pointer of the given type, + * avoiding a type cast in the source code. + * Note that the underlying slice allocation mechanism can + * be changed with the G_SLICE=always-malloc + * environment variable. + * + * Since: 2.10 + */ + +/** + * g_slice_dup: + * @type: the type to duplicate, typically a structure name + * @mem: the memory to copy into the allocated block + * + * A convenience macro to duplicate a block of memory using + * the slice allocator. + * + * It calls g_slice_copy() with sizeof (@type) + * and casts the returned pointer to a pointer of the given type, + * avoiding a type cast in the source code. + * Note that the underlying slice allocation mechanism can + * be changed with the G_SLICE=always-malloc + * environment variable. + * + * Returns: a pointer to the allocated block, cast to a pointer to @type + * + * Since: 2.14 + */ + +/** + * g_slice_free: + * @type: the type of the block to free, typically a structure name + * @mem: a pointer to the block to free + * + * A convenience macro to free a block of memory that has + * been allocated from the slice allocator. + * + * It calls g_slice_free1() using sizeof (type) + * as the block size. + * Note that the exact release behaviour can be changed with the + * G_DEBUG=gc-friendly environment + * variable, also see G_SLICE for + * related debugging options. + * + * Since: 2.10 + */ + +/** + * g_slice_free_chain: + * @type: the type of the @mem_chain blocks + * @mem_chain: a pointer to the first block of the chain + * @next: the field name of the next pointer in @type + * + * Frees a linked list of memory blocks of structure type @type. + * The memory blocks must be equal-sized, allocated via + * g_slice_alloc() or g_slice_alloc0() and linked together by + * a @next pointer (similar to #GSList). The name of the + * @next field in @type is passed as third argument. + * Note that the exact release behaviour can be changed with the + * G_DEBUG=gc-friendly environment + * variable, also see G_SLICE for + * related debugging options. + * + * Since: 2.10 + */ + +/** + * g_slice_alloc: + * @block_size: the number of bytes to allocate + * + * Allocates a block of memory from the slice allocator. + * The block adress handed out can be expected to be aligned + * to at least 1 * sizeof (void*), + * though in general slices are 2 * sizeof (void*) bytes aligned, + * if a malloc() fallback implementation is used instead, + * the alignment may be reduced in a libc dependent fashion. + * Note that the underlying slice allocation mechanism can + * be changed with the G_SLICE=always-malloc + * environment variable. + * + * Returns: a pointer to the allocated memory block + * + * Since: 2.10 + */ +gpointer +g_slice_alloc (gsize mem_size) +{ + ThreadMemory *tmem; + gsize chunk_size; + gpointer mem; + guint acat; + + /* This gets the private structure for this thread. If the private + * structure does not yet exist, it is created. + * + * This has a side effect of causing GSlice to be initialised, so it + * must come first. + */ + tmem = thread_memory_from_self (); + + chunk_size = P2ALIGN (mem_size); + acat = allocator_categorize (chunk_size); + if (G_LIKELY (acat == 1)) /* allocate through magazine layer */ + { + guint ix = SLAB_INDEX (allocator, chunk_size); + if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix))) + { + thread_memory_swap_magazines (tmem, ix); + if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix))) + thread_memory_magazine1_reload (tmem, ix); + } + mem = thread_memory_magazine1_alloc (tmem, ix); + } + else if (acat == 2) /* allocate through slab allocator */ + { + g_mutex_lock (&allocator->slab_mutex); + mem = slab_allocator_alloc_chunk (chunk_size); + g_mutex_unlock (&allocator->slab_mutex); + } + else /* delegate to system malloc */ + mem = g_malloc (mem_size); + if (G_UNLIKELY (allocator->config.debug_blocks)) + smc_notify_alloc (mem, mem_size); + + TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size)); + + return mem; +} + +/** + * g_slice_alloc0: + * @block_size: the number of bytes to allocate + * + * Allocates a block of memory via g_slice_alloc() and initializes + * the returned memory to 0. Note that the underlying slice allocation + * mechanism can be changed with the + * G_SLICE=always-malloc + * environment variable. + * + * Returns: a pointer to the allocated block + * + * Since: 2.10 + */ +gpointer +g_slice_alloc0 (gsize mem_size) +{ + gpointer mem = g_slice_alloc (mem_size); + if (mem) + memset (mem, 0, mem_size); + return mem; +} + +/** + * g_slice_copy: + * @block_size: the number of bytes to allocate + * @mem_block: the memory to copy + * + * Allocates a block of memory from the slice allocator + * and copies @block_size bytes into it from @mem_block. + * + * Returns: a pointer to the allocated memory block + * + * Since: 2.14 + */ +gpointer +g_slice_copy (gsize mem_size, + gconstpointer mem_block) +{ + gpointer mem = g_slice_alloc (mem_size); + if (mem) + memcpy (mem, mem_block, mem_size); + return mem; +} + +/** + * g_slice_free1: + * @block_size: the size of the block + * @mem_block: a pointer to the block to free + * + * Frees a block of memory. + * + * The memory must have been allocated via g_slice_alloc() or + * g_slice_alloc0() and the @block_size has to match the size + * specified upon allocation. Note that the exact release behaviour + * can be changed with the + * G_DEBUG=gc-friendly environment + * variable, also see G_SLICE for + * related debugging options. + * + * Since: 2.10 + */ +void +g_slice_free1 (gsize mem_size, + gpointer mem_block) +{ + gsize chunk_size = P2ALIGN (mem_size); + guint acat = allocator_categorize (chunk_size); + if (G_UNLIKELY (!mem_block)) + return; + if (G_UNLIKELY (allocator->config.debug_blocks) && + !smc_notify_free (mem_block, mem_size)) + abort(); + if (G_LIKELY (acat == 1)) /* allocate through magazine layer */ + { + ThreadMemory *tmem = thread_memory_from_self(); + guint ix = SLAB_INDEX (allocator, chunk_size); + if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix))) + { + thread_memory_swap_magazines (tmem, ix); + if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix))) + thread_memory_magazine2_unload (tmem, ix); + } + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (mem_block, 0, chunk_size); + thread_memory_magazine2_free (tmem, ix, mem_block); + } + else if (acat == 2) /* allocate through slab allocator */ + { + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (mem_block, 0, chunk_size); + g_mutex_lock (&allocator->slab_mutex); + slab_allocator_free_chunk (chunk_size, mem_block); + g_mutex_unlock (&allocator->slab_mutex); + } + else /* delegate to system malloc */ + { + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (mem_block, 0, mem_size); + g_free (mem_block); + } + TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size)); +} + +/** + * g_slice_free_chain_with_offset: + * @block_size: the size of the blocks + * @mem_chain: a pointer to the first block of the chain + * @next_offset: the offset of the @next field in the blocks + * + * Frees a linked list of memory blocks of structure type @type. + * + * The memory blocks must be equal-sized, allocated via + * g_slice_alloc() or g_slice_alloc0() and linked together by a + * @next pointer (similar to #GSList). The offset of the @next + * field in each block is passed as third argument. + * Note that the exact release behaviour can be changed with the + * G_DEBUG=gc-friendly environment + * variable, also see G_SLICE for + * related debugging options. + * + * Since: 2.10 + */ +void +g_slice_free_chain_with_offset (gsize mem_size, + gpointer mem_chain, + gsize next_offset) +{ + gpointer slice = mem_chain; + /* while the thread magazines and the magazine cache are implemented so that + * they can easily be extended to allow for free lists containing more free + * lists for the first level nodes, which would allow O(1) freeing in this + * function, the benefit of such an extension is questionable, because: + * - the magazine size counts will become mere lower bounds which confuses + * the code adapting to lock contention; + * - freeing a single node to the thread magazines is very fast, so this + * O(list_length) operation is multiplied by a fairly small factor; + * - memory usage histograms on larger applications seem to indicate that + * the amount of released multi node lists is negligible in comparison + * to single node releases. + * - the major performance bottle neck, namely g_private_get() or + * g_mutex_lock()/g_mutex_unlock() has already been moved out of the + * inner loop for freeing chained slices. + */ + gsize chunk_size = P2ALIGN (mem_size); + guint acat = allocator_categorize (chunk_size); + if (G_LIKELY (acat == 1)) /* allocate through magazine layer */ + { + ThreadMemory *tmem = thread_memory_from_self(); + guint ix = SLAB_INDEX (allocator, chunk_size); + while (slice) + { + guint8 *current = slice; + slice = *(gpointer*) (current + next_offset); + if (G_UNLIKELY (allocator->config.debug_blocks) && + !smc_notify_free (current, mem_size)) + abort(); + if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix))) + { + thread_memory_swap_magazines (tmem, ix); + if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix))) + thread_memory_magazine2_unload (tmem, ix); + } + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (current, 0, chunk_size); + thread_memory_magazine2_free (tmem, ix, current); + } + } + else if (acat == 2) /* allocate through slab allocator */ + { + g_mutex_lock (&allocator->slab_mutex); + while (slice) + { + guint8 *current = slice; + slice = *(gpointer*) (current + next_offset); + if (G_UNLIKELY (allocator->config.debug_blocks) && + !smc_notify_free (current, mem_size)) + abort(); + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (current, 0, chunk_size); + slab_allocator_free_chunk (chunk_size, current); + } + g_mutex_unlock (&allocator->slab_mutex); + } + else /* delegate to system malloc */ + while (slice) + { + guint8 *current = slice; + slice = *(gpointer*) (current + next_offset); + if (G_UNLIKELY (allocator->config.debug_blocks) && + !smc_notify_free (current, mem_size)) + abort(); + if (G_UNLIKELY (g_mem_gc_friendly)) + memset (current, 0, mem_size); + g_free (current); + } +} + +/* --- single page allocator --- */ +static void +allocator_slab_stack_push (Allocator *allocator, + guint ix, + SlabInfo *sinfo) +{ + /* insert slab at slab ring head */ + if (!allocator->slab_stack[ix]) + { + sinfo->next = sinfo; + sinfo->prev = sinfo; + } + else + { + SlabInfo *next = allocator->slab_stack[ix], *prev = next->prev; + next->prev = sinfo; + prev->next = sinfo; + sinfo->next = next; + sinfo->prev = prev; + } + allocator->slab_stack[ix] = sinfo; +} + +static gsize +allocator_aligned_page_size (Allocator *allocator, + gsize n_bytes) +{ + gsize val = 1 << g_bit_storage (n_bytes - 1); + val = MAX (val, allocator->min_page_size); + return val; +} + +static void +allocator_add_slab (Allocator *allocator, + guint ix, + gsize chunk_size) +{ + ChunkLink *chunk; + SlabInfo *sinfo; + gsize addr, padding, n_chunks, color = 0; + gsize page_size = allocator_aligned_page_size (allocator, SLAB_BPAGE_SIZE (allocator, chunk_size)); + /* allocate 1 page for the chunks and the slab */ + gpointer aligned_memory = allocator_memalign (page_size, page_size - NATIVE_MALLOC_PADDING); + guint8 *mem = aligned_memory; + guint i; + if (!mem) + { + const gchar *syserr = "unknown error"; +#if HAVE_STRERROR + syserr = strerror (errno); +#endif + mem_error ("failed to allocate %u bytes (alignment: %u): %s\n", + (guint) (page_size - NATIVE_MALLOC_PADDING), (guint) page_size, syserr); + } + /* mask page address */ + addr = ((gsize) mem / page_size) * page_size; + /* assert alignment */ + mem_assert (aligned_memory == (gpointer) addr); + /* basic slab info setup */ + sinfo = (SlabInfo*) (mem + page_size - SLAB_INFO_SIZE); + sinfo->n_allocated = 0; + sinfo->chunks = NULL; + /* figure cache colorization */ + n_chunks = ((guint8*) sinfo - mem) / chunk_size; + padding = ((guint8*) sinfo - mem) - n_chunks * chunk_size; + if (padding) + { + color = (allocator->color_accu * P2ALIGNMENT) % padding; + allocator->color_accu += allocator->config.color_increment; + } + /* add chunks to free list */ + chunk = (ChunkLink*) (mem + color); + sinfo->chunks = chunk; + for (i = 0; i < n_chunks - 1; i++) + { + chunk->next = (ChunkLink*) ((guint8*) chunk + chunk_size); + chunk = chunk->next; + } + chunk->next = NULL; /* last chunk */ + /* add slab to slab ring */ + allocator_slab_stack_push (allocator, ix, sinfo); +} + +static gpointer +slab_allocator_alloc_chunk (gsize chunk_size) +{ + ChunkLink *chunk; + guint ix = SLAB_INDEX (allocator, chunk_size); + /* ensure non-empty slab */ + if (!allocator->slab_stack[ix] || !allocator->slab_stack[ix]->chunks) + allocator_add_slab (allocator, ix, chunk_size); + /* allocate chunk */ + chunk = allocator->slab_stack[ix]->chunks; + allocator->slab_stack[ix]->chunks = chunk->next; + allocator->slab_stack[ix]->n_allocated++; + /* rotate empty slabs */ + if (!allocator->slab_stack[ix]->chunks) + allocator->slab_stack[ix] = allocator->slab_stack[ix]->next; + return chunk; +} + +static void +slab_allocator_free_chunk (gsize chunk_size, + gpointer mem) +{ + ChunkLink *chunk; + gboolean was_empty; + guint ix = SLAB_INDEX (allocator, chunk_size); + gsize page_size = allocator_aligned_page_size (allocator, SLAB_BPAGE_SIZE (allocator, chunk_size)); + gsize addr = ((gsize) mem / page_size) * page_size; + /* mask page address */ + guint8 *page = (guint8*) addr; + SlabInfo *sinfo = (SlabInfo*) (page + page_size - SLAB_INFO_SIZE); + /* assert valid chunk count */ + mem_assert (sinfo->n_allocated > 0); + /* add chunk to free list */ + was_empty = sinfo->chunks == NULL; + chunk = (ChunkLink*) mem; + chunk->next = sinfo->chunks; + sinfo->chunks = chunk; + sinfo->n_allocated--; + /* keep slab ring partially sorted, empty slabs at end */ + if (was_empty) + { + /* unlink slab */ + SlabInfo *next = sinfo->next, *prev = sinfo->prev; + next->prev = prev; + prev->next = next; + if (allocator->slab_stack[ix] == sinfo) + allocator->slab_stack[ix] = next == sinfo ? NULL : next; + /* insert slab at head */ + allocator_slab_stack_push (allocator, ix, sinfo); + } + /* eagerly free complete unused slabs */ + if (!sinfo->n_allocated) + { + /* unlink slab */ + SlabInfo *next = sinfo->next, *prev = sinfo->prev; + next->prev = prev; + prev->next = next; + if (allocator->slab_stack[ix] == sinfo) + allocator->slab_stack[ix] = next == sinfo ? NULL : next; + /* free slab */ + allocator_memfree (page_size, page); + } +} + +/* --- memalign implementation --- */ +#ifdef HAVE_MALLOC_H +#include /* memalign() */ +#endif + +/* from config.h: + * define HAVE_POSIX_MEMALIGN 1 // if free(posix_memalign(3)) works, + * define HAVE_COMPLIANT_POSIX_MEMALIGN 1 // if free(posix_memalign(3)) works for sizes != 2^n, + * define HAVE_MEMALIGN 1 // if free(memalign(3)) works, + * define HAVE_VALLOC 1 // if free(valloc(3)) works, or + * if none is provided, we implement malloc(3)-based alloc-only page alignment + */ + +#if !(HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN || HAVE_VALLOC) +static GTrashStack *compat_valloc_trash = NULL; +#endif + +static gpointer +allocator_memalign (gsize alignment, + gsize memsize) +{ + gpointer aligned_memory = NULL; + gint err = ENOMEM; +#if HAVE_COMPLIANT_POSIX_MEMALIGN + err = posix_memalign (&aligned_memory, alignment, memsize); +#elif HAVE_MEMALIGN + errno = 0; + aligned_memory = memalign (alignment, memsize); + err = errno; +#elif HAVE_VALLOC + errno = 0; + aligned_memory = valloc (memsize); + err = errno; +#else + /* simplistic non-freeing page allocator */ + mem_assert (alignment == sys_page_size); + mem_assert (memsize <= sys_page_size); + if (!compat_valloc_trash) + { + const guint n_pages = 16; + guint8 *mem = malloc (n_pages * sys_page_size); + err = errno; + if (mem) + { + gint i = n_pages; + guint8 *amem = (guint8*) ALIGN ((gsize) mem, sys_page_size); + if (amem != mem) + i--; /* mem wasn't page aligned */ + while (--i >= 0) + g_trash_stack_push (&compat_valloc_trash, amem + i * sys_page_size); + } + } + aligned_memory = g_trash_stack_pop (&compat_valloc_trash); +#endif + if (!aligned_memory) + errno = err; + return aligned_memory; +} + +static void +allocator_memfree (gsize memsize, + gpointer mem) +{ +#if HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN || HAVE_VALLOC + free (mem); +#else + mem_assert (memsize <= sys_page_size); + g_trash_stack_push (&compat_valloc_trash, mem); +#endif +} + +static void +mem_error (const char *format, + ...) +{ + const char *pname; + va_list args; + /* at least, put out "MEMORY-ERROR", in case we segfault during the rest of the function */ + fputs ("\n***MEMORY-ERROR***: ", stderr); + pname = g_get_prgname(); + fprintf (stderr, "%s[%ld]: GSlice: ", pname ? pname : "", (long)getpid()); + va_start (args, format); + vfprintf (stderr, format, args); + va_end (args); + fputs ("\n", stderr); + abort(); + _exit (1); +} + +/* --- g-slice memory checker tree --- */ +typedef size_t SmcKType; /* key type */ +typedef size_t SmcVType; /* value type */ +typedef struct { + SmcKType key; + SmcVType value; +} SmcEntry; +static void smc_tree_insert (SmcKType key, + SmcVType value); +static gboolean smc_tree_lookup (SmcKType key, + SmcVType *value_p); +static gboolean smc_tree_remove (SmcKType key); + + +/* --- g-slice memory checker implementation --- */ +static void +smc_notify_alloc (void *pointer, + size_t size) +{ + size_t adress = (size_t) pointer; + if (pointer) + smc_tree_insert (adress, size); +} + +#if 0 +static void +smc_notify_ignore (void *pointer) +{ + size_t adress = (size_t) pointer; + if (pointer) + smc_tree_remove (adress); +} +#endif + +static int +smc_notify_free (void *pointer, + size_t size) +{ + size_t adress = (size_t) pointer; + SmcVType real_size; + gboolean found_one; + + if (!pointer) + return 1; /* ignore */ + found_one = smc_tree_lookup (adress, &real_size); + if (!found_one) + { + fprintf (stderr, "GSlice: MemChecker: attempt to release non-allocated block: %p size=%" G_GSIZE_FORMAT "\n", pointer, size); + return 0; + } + if (real_size != size && (real_size || size)) + { + fprintf (stderr, "GSlice: MemChecker: attempt to release block with invalid size: %p size=%" G_GSIZE_FORMAT " invalid-size=%" G_GSIZE_FORMAT "\n", pointer, real_size, size); + return 0; + } + if (!smc_tree_remove (adress)) + { + fprintf (stderr, "GSlice: MemChecker: attempt to release non-allocated block: %p size=%" G_GSIZE_FORMAT "\n", pointer, size); + return 0; + } + return 1; /* all fine */ +} + +/* --- g-slice memory checker tree implementation --- */ +#define SMC_TRUNK_COUNT (4093 /* 16381 */) /* prime, to distribute trunk collisions (big, allocated just once) */ +#define SMC_BRANCH_COUNT (511) /* prime, to distribute branch collisions */ +#define SMC_TRUNK_EXTENT (SMC_BRANCH_COUNT * 2039) /* key address space per trunk, should distribute uniformly across BRANCH_COUNT */ +#define SMC_TRUNK_HASH(k) ((k / SMC_TRUNK_EXTENT) % SMC_TRUNK_COUNT) /* generate new trunk hash per megabyte (roughly) */ +#define SMC_BRANCH_HASH(k) (k % SMC_BRANCH_COUNT) + +typedef struct { + SmcEntry *entries; + unsigned int n_entries; +} SmcBranch; + +static SmcBranch **smc_tree_root = NULL; + +static void +smc_tree_abort (int errval) +{ + const char *syserr = "unknown error"; +#if HAVE_STRERROR + syserr = strerror (errval); +#endif + mem_error ("MemChecker: failure in debugging tree: %s", syserr); +} + +static inline SmcEntry* +smc_tree_branch_grow_L (SmcBranch *branch, + unsigned int index) +{ + unsigned int old_size = branch->n_entries * sizeof (branch->entries[0]); + unsigned int new_size = old_size + sizeof (branch->entries[0]); + SmcEntry *entry; + mem_assert (index <= branch->n_entries); + branch->entries = (SmcEntry*) realloc (branch->entries, new_size); + if (!branch->entries) + smc_tree_abort (errno); + entry = branch->entries + index; + g_memmove (entry + 1, entry, (branch->n_entries - index) * sizeof (entry[0])); + branch->n_entries += 1; + return entry; +} + +static inline SmcEntry* +smc_tree_branch_lookup_nearest_L (SmcBranch *branch, + SmcKType key) +{ + unsigned int n_nodes = branch->n_entries, offs = 0; + SmcEntry *check = branch->entries; + int cmp = 0; + while (offs < n_nodes) + { + unsigned int i = (offs + n_nodes) >> 1; + check = branch->entries + i; + cmp = key < check->key ? -1 : key != check->key; + if (cmp == 0) + return check; /* return exact match */ + else if (cmp < 0) + n_nodes = i; + else /* (cmp > 0) */ + offs = i + 1; + } + /* check points at last mismatch, cmp > 0 indicates greater key */ + return cmp > 0 ? check + 1 : check; /* return insertion position for inexact match */ +} + +static void +smc_tree_insert (SmcKType key, + SmcVType value) +{ + unsigned int ix0, ix1; + SmcEntry *entry; + + g_mutex_lock (&smc_tree_mutex); + ix0 = SMC_TRUNK_HASH (key); + ix1 = SMC_BRANCH_HASH (key); + if (!smc_tree_root) + { + smc_tree_root = calloc (SMC_TRUNK_COUNT, sizeof (smc_tree_root[0])); + if (!smc_tree_root) + smc_tree_abort (errno); + } + if (!smc_tree_root[ix0]) + { + smc_tree_root[ix0] = calloc (SMC_BRANCH_COUNT, sizeof (smc_tree_root[0][0])); + if (!smc_tree_root[ix0]) + smc_tree_abort (errno); + } + entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key); + if (!entry || /* need create */ + entry >= smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries || /* need append */ + entry->key != key) /* need insert */ + entry = smc_tree_branch_grow_L (&smc_tree_root[ix0][ix1], entry - smc_tree_root[ix0][ix1].entries); + entry->key = key; + entry->value = value; + g_mutex_unlock (&smc_tree_mutex); +} + +static gboolean +smc_tree_lookup (SmcKType key, + SmcVType *value_p) +{ + SmcEntry *entry = NULL; + unsigned int ix0 = SMC_TRUNK_HASH (key), ix1 = SMC_BRANCH_HASH (key); + gboolean found_one = FALSE; + *value_p = 0; + g_mutex_lock (&smc_tree_mutex); + if (smc_tree_root && smc_tree_root[ix0]) + { + entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key); + if (entry && + entry < smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries && + entry->key == key) + { + found_one = TRUE; + *value_p = entry->value; + } + } + g_mutex_unlock (&smc_tree_mutex); + return found_one; +} + +static gboolean +smc_tree_remove (SmcKType key) +{ + unsigned int ix0 = SMC_TRUNK_HASH (key), ix1 = SMC_BRANCH_HASH (key); + gboolean found_one = FALSE; + g_mutex_lock (&smc_tree_mutex); + if (smc_tree_root && smc_tree_root[ix0]) + { + SmcEntry *entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key); + if (entry && + entry < smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries && + entry->key == key) + { + unsigned int i = entry - smc_tree_root[ix0][ix1].entries; + smc_tree_root[ix0][ix1].n_entries -= 1; + g_memmove (entry, entry + 1, (smc_tree_root[ix0][ix1].n_entries - i) * sizeof (entry[0])); + if (!smc_tree_root[ix0][ix1].n_entries) + { + /* avoid useless pressure on the memory system */ + free (smc_tree_root[ix0][ix1].entries); + smc_tree_root[ix0][ix1].entries = NULL; + } + found_one = TRUE; + } + } + g_mutex_unlock (&smc_tree_mutex); + return found_one; +} + +#ifdef G_ENABLE_DEBUG +void +g_slice_debug_tree_statistics (void) +{ + g_mutex_lock (&smc_tree_mutex); + if (smc_tree_root) + { + unsigned int i, j, t = 0, o = 0, b = 0, su = 0, ex = 0, en = 4294967295u; + double tf, bf; + for (i = 0; i < SMC_TRUNK_COUNT; i++) + if (smc_tree_root[i]) + { + t++; + for (j = 0; j < SMC_BRANCH_COUNT; j++) + if (smc_tree_root[i][j].n_entries) + { + b++; + su += smc_tree_root[i][j].n_entries; + en = MIN (en, smc_tree_root[i][j].n_entries); + ex = MAX (ex, smc_tree_root[i][j].n_entries); + } + else if (smc_tree_root[i][j].entries) + o++; /* formerly used, now empty */ + } + en = b ? en : 0; + tf = MAX (t, 1.0); /* max(1) to be a valid divisor */ + bf = MAX (b, 1.0); /* max(1) to be a valid divisor */ + fprintf (stderr, "GSlice: MemChecker: %u trunks, %u branches, %u old branches\n", t, b, o); + fprintf (stderr, "GSlice: MemChecker: %f branches per trunk, %.2f%% utilization\n", + b / tf, + 100.0 - (SMC_BRANCH_COUNT - b / tf) / (0.01 * SMC_BRANCH_COUNT)); + fprintf (stderr, "GSlice: MemChecker: %f entries per branch, %u minimum, %u maximum\n", + su / bf, en, ex); + } + else + fprintf (stderr, "GSlice: MemChecker: root=NULL\n"); + g_mutex_unlock (&smc_tree_mutex); + + /* sample statistics (beast + GSLice + 24h scripted core & GUI activity): + * PID %CPU %MEM VSZ RSS COMMAND + * 8887 30.3 45.8 456068 414856 beast-0.7.1 empty.bse + * $ cat /proc/8887/statm # total-program-size resident-set-size shared-pages text/code data/stack library dirty-pages + * 114017 103714 2354 344 0 108676 0 + * $ cat /proc/8887/status + * Name: beast-0.7.1 + * VmSize: 456068 kB + * VmLck: 0 kB + * VmRSS: 414856 kB + * VmData: 434620 kB + * VmStk: 84 kB + * VmExe: 1376 kB + * VmLib: 13036 kB + * VmPTE: 456 kB + * Threads: 3 + * (gdb) print g_slice_debug_tree_statistics () + * GSlice: MemChecker: 422 trunks, 213068 branches, 0 old branches + * GSlice: MemChecker: 504.900474 branches per trunk, 98.81% utilization + * GSlice: MemChecker: 4.965039 entries per branch, 1 minimum, 37 maximum + */ +} +#endif /* G_ENABLE_DEBUG */ diff --git a/glib/glib/gslice.h b/glib/glib/gslice.h new file mode 100644 index 0000000..4b4b9e5 --- /dev/null +++ b/glib/glib/gslice.h @@ -0,0 +1,86 @@ +/* GLIB sliced memory - fast threaded memory chunk allocator + * Copyright (C) 2005 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_SLICE_H__ +#define __G_SLICE_H__ + +#include + +G_BEGIN_DECLS + +/* slices - fast allocation/release of small memory blocks + */ +gpointer g_slice_alloc (gsize block_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); +gpointer g_slice_alloc0 (gsize block_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); +gpointer g_slice_copy (gsize block_size, + gconstpointer mem_block) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1); +void g_slice_free1 (gsize block_size, + gpointer mem_block); +void g_slice_free_chain_with_offset (gsize block_size, + gpointer mem_chain, + gsize next_offset); +#define g_slice_new(type) ((type*) g_slice_alloc (sizeof (type))) +#define g_slice_new0(type) ((type*) g_slice_alloc0 (sizeof (type))) +/* MemoryBlockType * + * g_slice_dup (MemoryBlockType, + * MemoryBlockType *mem_block); + * g_slice_free (MemoryBlockType, + * MemoryBlockType *mem_block); + * g_slice_free_chain (MemoryBlockType, + * MemoryBlockType *first_chain_block, + * memory_block_next_field); + * pseudo prototypes for the macro + * definitions following below. + */ + +/* we go through extra hoops to ensure type safety */ +#define g_slice_dup(type, mem) \ + (1 ? (type*) g_slice_copy (sizeof (type), (mem)) \ + : ((void) ((type*) 0 == (mem)), (type*) 0)) +#define g_slice_free(type, mem) do { \ + if (1) g_slice_free1 (sizeof (type), (mem)); \ + else (void) ((type*) 0 == (mem)); \ +} while (0) +#define g_slice_free_chain(type, mem_chain, next) do { \ + if (1) g_slice_free_chain_with_offset (sizeof (type), \ + (mem_chain), G_STRUCT_OFFSET (type, next)); \ + else (void) ((type*) 0 == (mem_chain)); \ +} while (0) + + +/* --- internal debugging API --- */ +typedef enum { + G_SLICE_CONFIG_ALWAYS_MALLOC = 1, + G_SLICE_CONFIG_BYPASS_MAGAZINES, + G_SLICE_CONFIG_WORKING_SET_MSECS, + G_SLICE_CONFIG_COLOR_INCREMENT, + G_SLICE_CONFIG_CHUNK_SIZES, + G_SLICE_CONFIG_CONTENTION_COUNTER +} GSliceConfig; +void g_slice_set_config (GSliceConfig ckey, gint64 value); +gint64 g_slice_get_config (GSliceConfig ckey); +gint64* g_slice_get_config_state (GSliceConfig ckey, gint64 address, guint *n_values); + +G_END_DECLS + +#endif /* __G_SLICE_H__ */ diff --git a/glib/glib/gslist.c b/glib/glib/gslist.c new file mode 100644 index 0000000..89e0f2d --- /dev/null +++ b/glib/glib/gslist.c @@ -0,0 +1,1042 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "gslist.h" + +#include "gtestutils.h" +#include "gslice.h" + +/** + * SECTION:linked_lists_single + * @title: Singly-Linked Lists + * @short_description: linked lists that can be iterated in one direction + * + * The #GSList structure and its associated functions provide a + * standard singly-linked list data structure. + * + * Each element in the list contains a piece of data, together with a + * pointer which links to the next element in the list. Using this + * pointer it is possible to move through the list in one direction + * only (unlike the Doubly-Linked Lists which + * allow movement in both directions). + * + * The data contained in each element can be either integer values, by + * using one of the Type + * Conversion Macros, or simply pointers to any type of data. + * + * List elements are allocated from the slice allocator, which is more + * efficient than allocating elements individually. + * + * Note that most of the #GSList functions expect to be passed a + * pointer to the first element in the list. The functions which insert + * elements return the new start of the list, which may have changed. + * + * There is no function to create a #GSList. %NULL is considered to be + * the empty list so you simply set a #GSList* to %NULL. + * + * To add elements, use g_slist_append(), g_slist_prepend(), + * g_slist_insert() and g_slist_insert_sorted(). + * + * To remove elements, use g_slist_remove(). + * + * To find elements in the list use g_slist_last(), g_slist_next(), + * g_slist_nth(), g_slist_nth_data(), g_slist_find() and + * g_slist_find_custom(). + * + * To find the index of an element use g_slist_position() and + * g_slist_index(). + * + * To call a function for each element in the list use + * g_slist_foreach(). + * + * To free the entire list, use g_slist_free(). + **/ + +/** + * GSList: + * @data: holds the element's data, which can be a pointer to any kind + * of data, or any integer value using the Type Conversion + * Macros. + * @next: contains the link to the next element in the list. + * + * The #GSList struct is used for each element in the singly-linked + * list. + **/ + +/** + * g_slist_next: + * @slist: an element in a #GSList. + * @Returns: the next element, or %NULL if there are no more elements. + * + * A convenience macro to get the next element in a #GSList. + **/ + +#define _g_slist_alloc0() g_slice_new0 (GSList) +#define _g_slist_alloc() g_slice_new (GSList) +#define _g_slist_free1(slist) g_slice_free (GSList, slist) + +/** + * g_slist_alloc: + * @Returns: a pointer to the newly-allocated #GSList element. + * + * Allocates space for one #GSList element. It is called by the + * g_slist_append(), g_slist_prepend(), g_slist_insert() and + * g_slist_insert_sorted() functions and so is rarely used on its own. + **/ +GSList* +g_slist_alloc (void) +{ + return _g_slist_alloc0 (); +} + +/** + * g_slist_free: + * @list: a #GSList + * + * Frees all of the memory used by a #GSList. + * The freed elements are returned to the slice allocator. + * + * + * If list elements contain dynamically-allocated memory, + * you should either use g_slist_free_full() or free them manually + * first. + * + */ +void +g_slist_free (GSList *list) +{ + g_slice_free_chain (GSList, list, next); +} + +/** + * g_slist_free_1: + * @list: a #GSList element + * + * Frees one #GSList element. + * It is usually used after g_slist_remove_link(). + */ +/** + * g_slist_free1: + * + * A macro which does the same as g_slist_free_1(). + * + * Since: 2.10 + **/ +void +g_slist_free_1 (GSList *list) +{ + _g_slist_free1 (list); +} + +/** + * g_slist_free_full: + * @list: a pointer to a #GSList + * @free_func: the function to be called to free each element's data + * + * Convenience method, which frees all the memory used by a #GSList, and + * calls the specified destroy function on every element's data. + * + * Since: 2.28 + **/ +void +g_slist_free_full (GSList *list, + GDestroyNotify free_func) +{ + g_slist_foreach (list, (GFunc) free_func, NULL); + g_slist_free (list); +} + +/** + * g_slist_append: + * @list: a #GSList + * @data: the data for the new element + * + * Adds a new element on to the end of the list. + * + * + * The return value is the new start of the list, which may + * have changed, so make sure you store the new value. + * + * + * + * Note that g_slist_append() has to traverse the entire list + * to find the end, which is inefficient when adding multiple + * elements. A common idiom to avoid the inefficiency is to prepend + * the elements and reverse the list when all elements have been added. + * + * + * |[ + * /* Notice that these are initialized to the empty list. */ + * GSList *list = NULL, *number_list = NULL; + * + * /* This is a list of strings. */ + * list = g_slist_append (list, "first"); + * list = g_slist_append (list, "second"); + * + * /* This is a list of integers. */ + * number_list = g_slist_append (number_list, GINT_TO_POINTER (27)); + * number_list = g_slist_append (number_list, GINT_TO_POINTER (14)); + * ]| + * + * Returns: the new start of the #GSList + */ +GSList* +g_slist_append (GSList *list, + gpointer data) +{ + GSList *new_list; + GSList *last; + + new_list = _g_slist_alloc (); + new_list->data = data; + new_list->next = NULL; + + if (list) + { + last = g_slist_last (list); + /* g_assert (last != NULL); */ + last->next = new_list; + + return list; + } + else + return new_list; +} + +/** + * g_slist_prepend: + * @list: a #GSList + * @data: the data for the new element + * + * Adds a new element on to the start of the list. + * + * + * The return value is the new start of the list, which + * may have changed, so make sure you store the new value. + * + * + * |[ + * /* Notice that it is initialized to the empty list. */ + * GSList *list = NULL; + * list = g_slist_prepend (list, "last"); + * list = g_slist_prepend (list, "first"); + * ]| + * + * Returns: the new start of the #GSList + */ +GSList* +g_slist_prepend (GSList *list, + gpointer data) +{ + GSList *new_list; + + new_list = _g_slist_alloc (); + new_list->data = data; + new_list->next = list; + + return new_list; +} + +/** + * g_slist_insert: + * @list: a #GSList + * @data: the data for the new element + * @position: the position to insert the element. + * If this is negative, or is larger than the number + * of elements in the list, the new element is added on + * to the end of the list. + * + * Inserts a new element into the list at the given position. + * + * Returns: the new start of the #GSList + */ +GSList* +g_slist_insert (GSList *list, + gpointer data, + gint position) +{ + GSList *prev_list; + GSList *tmp_list; + GSList *new_list; + + if (position < 0) + return g_slist_append (list, data); + else if (position == 0) + return g_slist_prepend (list, data); + + new_list = _g_slist_alloc (); + new_list->data = data; + + if (!list) + { + new_list->next = NULL; + return new_list; + } + + prev_list = NULL; + tmp_list = list; + + while ((position-- > 0) && tmp_list) + { + prev_list = tmp_list; + tmp_list = tmp_list->next; + } + + new_list->next = prev_list->next; + prev_list->next = new_list; + + return list; +} + +/** + * g_slist_insert_before: + * @slist: a #GSList + * @sibling: node to insert @data before + * @data: data to put in the newly-inserted node + * + * Inserts a node before @sibling containing @data. + * + * Returns: the new head of the list. + */ +GSList* +g_slist_insert_before (GSList *slist, + GSList *sibling, + gpointer data) +{ + if (!slist) + { + slist = _g_slist_alloc (); + slist->data = data; + slist->next = NULL; + g_return_val_if_fail (sibling == NULL, slist); + return slist; + } + else + { + GSList *node, *last = NULL; + + for (node = slist; node; last = node, node = last->next) + if (node == sibling) + break; + if (!last) + { + node = _g_slist_alloc (); + node->data = data; + node->next = slist; + + return node; + } + else + { + node = _g_slist_alloc (); + node->data = data; + node->next = last->next; + last->next = node; + + return slist; + } + } +} + +/** + * g_slist_concat: + * @list1: a #GSList + * @list2: the #GSList to add to the end of the first #GSList + * + * Adds the second #GSList onto the end of the first #GSList. + * Note that the elements of the second #GSList are not copied. + * They are used directly. + * + * Returns: the start of the new #GSList + */ +GSList * +g_slist_concat (GSList *list1, GSList *list2) +{ + if (list2) + { + if (list1) + g_slist_last (list1)->next = list2; + else + list1 = list2; + } + + return list1; +} + +/** + * g_slist_remove: + * @list: a #GSList + * @data: the data of the element to remove + * + * Removes an element from a #GSList. + * If two elements contain the same data, only the first is removed. + * If none of the elements contain the data, the #GSList is unchanged. + * + * Returns: the new start of the #GSList + */ +GSList* +g_slist_remove (GSList *list, + gconstpointer data) +{ + GSList *tmp, *prev = NULL; + + tmp = list; + while (tmp) + { + if (tmp->data == data) + { + if (prev) + prev->next = tmp->next; + else + list = tmp->next; + + g_slist_free_1 (tmp); + break; + } + prev = tmp; + tmp = prev->next; + } + + return list; +} + +/** + * g_slist_remove_all: + * @list: a #GSList + * @data: data to remove + * + * Removes all list nodes with data equal to @data. + * Returns the new head of the list. Contrast with + * g_slist_remove() which removes only the first node + * matching the given data. + * + * Returns: new head of @list + */ +GSList* +g_slist_remove_all (GSList *list, + gconstpointer data) +{ + GSList *tmp, *prev = NULL; + + tmp = list; + while (tmp) + { + if (tmp->data == data) + { + GSList *next = tmp->next; + + if (prev) + prev->next = next; + else + list = next; + + g_slist_free_1 (tmp); + tmp = next; + } + else + { + prev = tmp; + tmp = prev->next; + } + } + + return list; +} + +static inline GSList* +_g_slist_remove_link (GSList *list, + GSList *link) +{ + GSList *tmp; + GSList *prev; + + prev = NULL; + tmp = list; + + while (tmp) + { + if (tmp == link) + { + if (prev) + prev->next = tmp->next; + if (list == tmp) + list = list->next; + + tmp->next = NULL; + break; + } + + prev = tmp; + tmp = tmp->next; + } + + return list; +} + +/** + * g_slist_remove_link: + * @list: a #GSList + * @link_: an element in the #GSList + * + * Removes an element from a #GSList, without + * freeing the element. The removed element's next + * link is set to %NULL, so that it becomes a + * self-contained list with one element. + * + * Returns: the new start of the #GSList, without the element + */ +GSList* +g_slist_remove_link (GSList *list, + GSList *link_) +{ + return _g_slist_remove_link (list, link_); +} + +/** + * g_slist_delete_link: + * @list: a #GSList + * @link_: node to delete + * + * Removes the node link_ from the list and frees it. + * Compare this to g_slist_remove_link() which removes the node + * without freeing it. + * + * Returns: the new head of @list + */ +GSList* +g_slist_delete_link (GSList *list, + GSList *link_) +{ + list = _g_slist_remove_link (list, link_); + _g_slist_free1 (link_); + + return list; +} + +/** + * g_slist_copy: + * @list: a #GSList + * + * Copies a #GSList. + * + * + * Note that this is a "shallow" copy. If the list elements + * consist of pointers to data, the pointers are copied but + * the actual data isn't. + * + * + * Returns: a copy of @list + */ +GSList* +g_slist_copy (GSList *list) +{ + GSList *new_list = NULL; + + if (list) + { + GSList *last; + + new_list = _g_slist_alloc (); + new_list->data = list->data; + last = new_list; + list = list->next; + while (list) + { + last->next = _g_slist_alloc (); + last = last->next; + last->data = list->data; + list = list->next; + } + last->next = NULL; + } + + return new_list; +} + +/** + * g_slist_reverse: + * @list: a #GSList + * + * Reverses a #GSList. + * + * Returns: the start of the reversed #GSList + */ +GSList* +g_slist_reverse (GSList *list) +{ + GSList *prev = NULL; + + while (list) + { + GSList *next = list->next; + + list->next = prev; + + prev = list; + list = next; + } + + return prev; +} + +/** + * g_slist_nth: + * @list: a #GSList + * @n: the position of the element, counting from 0 + * + * Gets the element at the given position in a #GSList. + * + * Returns: the element, or %NULL if the position is off + * the end of the #GSList + */ +GSList* +g_slist_nth (GSList *list, + guint n) +{ + while (n-- > 0 && list) + list = list->next; + + return list; +} + +/** + * g_slist_nth_data: + * @list: a #GSList + * @n: the position of the element + * + * Gets the data of the element at the given position. + * + * Returns: the element's data, or %NULL if the position + * is off the end of the #GSList + */ +gpointer +g_slist_nth_data (GSList *list, + guint n) +{ + while (n-- > 0 && list) + list = list->next; + + return list ? list->data : NULL; +} + +/** + * g_slist_find: + * @list: a #GSList + * @data: the element data to find + * + * Finds the element in a #GSList which + * contains the given data. + * + * Returns: the found #GSList element, + * or %NULL if it is not found + */ +GSList* +g_slist_find (GSList *list, + gconstpointer data) +{ + while (list) + { + if (list->data == data) + break; + list = list->next; + } + + return list; +} + + +/** + * g_slist_find_custom: + * @list: a #GSList + * @data: user data passed to the function + * @func: the function to call for each element. + * It should return 0 when the desired element is found + * + * Finds an element in a #GSList, using a supplied function to + * find the desired element. It iterates over the list, calling + * the given function which should return 0 when the desired + * element is found. The function takes two #gconstpointer arguments, + * the #GSList element's data as the first argument and the + * given user data. + * + * Returns: the found #GSList element, or %NULL if it is not found + */ +GSList* +g_slist_find_custom (GSList *list, + gconstpointer data, + GCompareFunc func) +{ + g_return_val_if_fail (func != NULL, list); + + while (list) + { + if (! func (list->data, data)) + return list; + list = list->next; + } + + return NULL; +} + +/** + * g_slist_position: + * @list: a #GSList + * @llink: an element in the #GSList + * + * Gets the position of the given element + * in the #GSList (starting from 0). + * + * Returns: the position of the element in the #GSList, + * or -1 if the element is not found + */ +gint +g_slist_position (GSList *list, + GSList *llink) +{ + gint i; + + i = 0; + while (list) + { + if (list == llink) + return i; + i++; + list = list->next; + } + + return -1; +} + +/** + * g_slist_index: + * @list: a #GSList + * @data: the data to find + * + * Gets the position of the element containing + * the given data (starting from 0). + * + * Returns: the index of the element containing the data, + * or -1 if the data is not found + */ +gint +g_slist_index (GSList *list, + gconstpointer data) +{ + gint i; + + i = 0; + while (list) + { + if (list->data == data) + return i; + i++; + list = list->next; + } + + return -1; +} + +/** + * g_slist_last: + * @list: a #GSList + * + * Gets the last element in a #GSList. + * + * + * This function iterates over the whole list. + * + * + * Returns: the last element in the #GSList, + * or %NULL if the #GSList has no elements + */ +GSList* +g_slist_last (GSList *list) +{ + if (list) + { + while (list->next) + list = list->next; + } + + return list; +} + +/** + * g_slist_length: + * @list: a #GSList + * + * Gets the number of elements in a #GSList. + * + * + * This function iterates over the whole list to + * count its elements. + * + * + * Returns: the number of elements in the #GSList + */ +guint +g_slist_length (GSList *list) +{ + guint length; + + length = 0; + while (list) + { + length++; + list = list->next; + } + + return length; +} + +/** + * g_slist_foreach: + * @list: a #GSList + * @func: the function to call with each element's data + * @user_data: user data to pass to the function + * + * Calls a function for each element of a #GSList. + */ +void +g_slist_foreach (GSList *list, + GFunc func, + gpointer user_data) +{ + while (list) + { + GSList *next = list->next; + (*func) (list->data, user_data); + list = next; + } +} + +static GSList* +g_slist_insert_sorted_real (GSList *list, + gpointer data, + GFunc func, + gpointer user_data) +{ + GSList *tmp_list = list; + GSList *prev_list = NULL; + GSList *new_list; + gint cmp; + + g_return_val_if_fail (func != NULL, list); + + if (!list) + { + new_list = _g_slist_alloc (); + new_list->data = data; + new_list->next = NULL; + return new_list; + } + + cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); + + while ((tmp_list->next) && (cmp > 0)) + { + prev_list = tmp_list; + tmp_list = tmp_list->next; + + cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data); + } + + new_list = _g_slist_alloc (); + new_list->data = data; + + if ((!tmp_list->next) && (cmp > 0)) + { + tmp_list->next = new_list; + new_list->next = NULL; + return list; + } + + if (prev_list) + { + prev_list->next = new_list; + new_list->next = tmp_list; + return list; + } + else + { + new_list->next = list; + return new_list; + } +} + +/** + * g_slist_insert_sorted: + * @list: a #GSList + * @data: the data for the new element + * @func: the function to compare elements in the list. + * It should return a number > 0 if the first parameter + * comes after the second parameter in the sort order. + * + * Inserts a new element into the list, using the given + * comparison function to determine its position. + * + * Returns: the new start of the #GSList + */ +GSList* +g_slist_insert_sorted (GSList *list, + gpointer data, + GCompareFunc func) +{ + return g_slist_insert_sorted_real (list, data, (GFunc) func, NULL); +} + +/** + * g_slist_insert_sorted_with_data: + * @list: a #GSList + * @data: the data for the new element + * @func: the function to compare elements in the list. + * It should return a number > 0 if the first parameter + * comes after the second parameter in the sort order. + * @user_data: data to pass to comparison function + * + * Inserts a new element into the list, using the given + * comparison function to determine its position. + * + * Returns: the new start of the #GSList + * + * Since: 2.10 + */ +GSList* +g_slist_insert_sorted_with_data (GSList *list, + gpointer data, + GCompareDataFunc func, + gpointer user_data) +{ + return g_slist_insert_sorted_real (list, data, (GFunc) func, user_data); +} + +static GSList * +g_slist_sort_merge (GSList *l1, + GSList *l2, + GFunc compare_func, + gpointer user_data) +{ + GSList list, *l; + gint cmp; + + l=&list; + + while (l1 && l2) + { + cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data); + + if (cmp <= 0) + { + l=l->next=l1; + l1=l1->next; + } + else + { + l=l->next=l2; + l2=l2->next; + } + } + l->next= l1 ? l1 : l2; + + return list.next; +} + +static GSList * +g_slist_sort_real (GSList *list, + GFunc compare_func, + gpointer user_data) +{ + GSList *l1, *l2; + + if (!list) + return NULL; + if (!list->next) + return list; + + l1 = list; + l2 = list->next; + + while ((l2 = l2->next) != NULL) + { + if ((l2 = l2->next) == NULL) + break; + l1=l1->next; + } + l2 = l1->next; + l1->next = NULL; + + return g_slist_sort_merge (g_slist_sort_real (list, compare_func, user_data), + g_slist_sort_real (l2, compare_func, user_data), + compare_func, + user_data); +} + +/** + * g_slist_sort: + * @list: a #GSList + * @compare_func: the comparison function used to sort the #GSList. + * This function is passed the data from 2 elements of the #GSList + * and should return 0 if they are equal, a negative value if the + * first element comes before the second, or a positive value if + * the first element comes after the second. + * + * Sorts a #GSList using the given comparison function. + * + * Returns: the start of the sorted #GSList + */ +GSList * +g_slist_sort (GSList *list, + GCompareFunc compare_func) +{ + return g_slist_sort_real (list, (GFunc) compare_func, NULL); +} + +/** + * g_slist_sort_with_data: + * @list: a #GSList + * @compare_func: comparison function + * @user_data: data to pass to comparison function + * + * Like g_slist_sort(), but the sort function accepts a user data argument. + * + * Returns: new head of the list + */ +GSList * +g_slist_sort_with_data (GSList *list, + GCompareDataFunc compare_func, + gpointer user_data) +{ + return g_slist_sort_real (list, (GFunc) compare_func, user_data); +} diff --git a/glib/glib/gslist.h b/glib/glib/gslist.h new file mode 100644 index 0000000..5652145 --- /dev/null +++ b/glib/glib/gslist.h @@ -0,0 +1,111 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_SLIST_H__ +#define __G_SLIST_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GSList GSList; + +struct _GSList +{ + gpointer data; + GSList *next; +}; + +/* Singly linked lists + */ +GSList* g_slist_alloc (void) G_GNUC_WARN_UNUSED_RESULT; +void g_slist_free (GSList *list); +void g_slist_free_1 (GSList *list); +#define g_slist_free1 g_slist_free_1 +void g_slist_free_full (GSList *list, + GDestroyNotify free_func); +GSList* g_slist_append (GSList *list, + gpointer data) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_prepend (GSList *list, + gpointer data) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_insert (GSList *list, + gpointer data, + gint position) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_insert_sorted (GSList *list, + gpointer data, + GCompareFunc func) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_insert_sorted_with_data (GSList *list, + gpointer data, + GCompareDataFunc func, + gpointer user_data) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_insert_before (GSList *slist, + GSList *sibling, + gpointer data) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_concat (GSList *list1, + GSList *list2) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_remove (GSList *list, + gconstpointer data) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_remove_all (GSList *list, + gconstpointer data) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_remove_link (GSList *list, + GSList *link_) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_delete_link (GSList *list, + GSList *link_) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_reverse (GSList *list) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_copy (GSList *list) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_nth (GSList *list, + guint n); +GSList* g_slist_find (GSList *list, + gconstpointer data); +GSList* g_slist_find_custom (GSList *list, + gconstpointer data, + GCompareFunc func); +gint g_slist_position (GSList *list, + GSList *llink); +gint g_slist_index (GSList *list, + gconstpointer data); +GSList* g_slist_last (GSList *list); +guint g_slist_length (GSList *list); +void g_slist_foreach (GSList *list, + GFunc func, + gpointer user_data); +GSList* g_slist_sort (GSList *list, + GCompareFunc compare_func) G_GNUC_WARN_UNUSED_RESULT; +GSList* g_slist_sort_with_data (GSList *list, + GCompareDataFunc compare_func, + gpointer user_data) G_GNUC_WARN_UNUSED_RESULT; +gpointer g_slist_nth_data (GSList *list, + guint n); + +#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL) + +G_END_DECLS + +#endif /* __G_SLIST_H__ */ diff --git a/glib/glib/gspawn-win32-helper.c b/glib/glib/gspawn-win32-helper.c new file mode 100644 index 0000000..40108bb --- /dev/null +++ b/glib/glib/gspawn-win32-helper.c @@ -0,0 +1,333 @@ +/* gspawn-win32-helper.c - Helper program for process launching on Win32. + * + * Copyright 2000 Red Hat, Inc. + * Copyright 2000 Tor Lillqvist + * + * GLib is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, write + * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#undef G_LOG_DOMAIN +#include "glib.h" +#define GSPAWN_HELPER +#include "gspawn-win32.c" /* For shared definitions */ + + +static void +write_err_and_exit (gint fd, + gintptr msg) +{ + gintptr en = errno; + + write (fd, &msg, sizeof(gintptr)); + write (fd, &en, sizeof(gintptr)); + + _exit (1); +} + +#ifdef __GNUC__ +# ifndef _stdcall +# define _stdcall __attribute__((stdcall)) +# endif +#endif + +/* We build gspawn-win32-helper.exe as a Windows GUI application + * to avoid any temporarily flashing console windows in case + * the gspawn function is invoked by a GUI program. Thus, no main() + * but a WinMain(). We do, however, still use argc and argv tucked + * away in the global __argc and __argv by the C runtime startup code. + */ + +/* Info peeked from mingw runtime's source code. __wgetmainargs() is a + * function to get the program's argv in wide char format. + */ + +typedef struct { + int newmode; +} _startupinfo; + +extern void __wgetmainargs(int *argc, + wchar_t ***wargv, + wchar_t ***wenviron, + int expand_wildcards, + _startupinfo *startupinfo); + +/* Copy of protect_argv that handles wchar_t strings */ + +static gint +protect_wargv (wchar_t **wargv, + wchar_t ***new_wargv) +{ + gint i; + gint argc = 0; + + while (wargv[argc]) + ++argc; + *new_wargv = g_new (wchar_t *, argc+1); + + /* Quote each argv element if necessary, so that it will get + * reconstructed correctly in the C runtime startup code. Note that + * the unquoting algorithm in the C runtime is really weird, and + * rather different than what Unix shells do. See stdargv.c in the C + * runtime sources (in the Platform SDK, in src/crt). + * + * Note that an new_wargv[0] constructed by this function should + * *not* be passed as the filename argument to a _wspawn* or _wexec* + * family function. That argument should be the real file name + * without any quoting. + */ + for (i = 0; i < argc; i++) + { + wchar_t *p = wargv[i]; + wchar_t *q; + gint len = 0; + gboolean need_dblquotes = FALSE; + while (*p) + { + if (*p == ' ' || *p == '\t') + need_dblquotes = TRUE; + else if (*p == '"') + len++; + else if (*p == '\\') + { + wchar_t *pp = p; + while (*pp && *pp == '\\') + pp++; + if (*pp == '"') + len++; + } + len++; + p++; + } + + q = (*new_wargv)[i] = g_new (wchar_t, len + need_dblquotes*2 + 1); + p = wargv[i]; + + if (need_dblquotes) + *q++ = '"'; + + while (*p) + { + if (*p == '"') + *q++ = '\\'; + else if (*p == '\\') + { + wchar_t *pp = p; + while (*pp && *pp == '\\') + pp++; + if (*pp == '"') + *q++ = '\\'; + } + *q++ = *p; + p++; + } + + if (need_dblquotes) + *q++ = '"'; + *q++ = '\0'; + } + (*new_wargv)[argc] = NULL; + + return argc; +} + +#ifndef HELPER_CONSOLE +int _stdcall +WinMain (struct HINSTANCE__ *hInstance, + struct HINSTANCE__ *hPrevInstance, + char *lpszCmdLine, + int nCmdShow) +#else +int +main (int ignored_argc, char **ignored_argv) +#endif +{ + int child_err_report_fd = -1; + int helper_sync_fd = -1; + int i; + int fd; + int mode; + gintptr handle; + int saved_errno; + gintptr no_error = CHILD_NO_ERROR; + gint argv_zero_offset = ARG_PROGRAM; + wchar_t **new_wargv; + int argc; + wchar_t **wargv, **wenvp; + _startupinfo si = { 0 }; + char c; + + g_assert (__argc >= ARG_COUNT); + + /* Fetch the wide-char argument vector */ + __wgetmainargs (&argc, &wargv, &wenvp, 0, &si); + + /* We still have the system codepage args in __argv. We can look + * at the first args in which gspawn-win32.c passes us flags and + * fd numbers in __argv, as we know those are just ASCII anyway. + */ + g_assert (argc == __argc); + + /* argv[ARG_CHILD_ERR_REPORT] is the file descriptor number onto + * which write error messages. + */ + child_err_report_fd = atoi (__argv[ARG_CHILD_ERR_REPORT]); + + /* Hack to implement G_SPAWN_FILE_AND_ARGV_ZERO. If + * argv[ARG_CHILD_ERR_REPORT] is suffixed with a '#' it means we get + * the program to run and its argv[0] separately. + */ + if (__argv[ARG_CHILD_ERR_REPORT][strlen (__argv[ARG_CHILD_ERR_REPORT]) - 1] == '#') + argv_zero_offset++; + + /* argv[ARG_HELPER_SYNC] is the file descriptor number we read a + * byte that tells us it is OK to exit. We have to wait until the + * parent allows us to exit, so that the parent has had time to + * duplicate the process handle we sent it. Duplicating a handle + * from another process works only if that other process exists. + */ + helper_sync_fd = atoi (__argv[ARG_HELPER_SYNC]); + + /* argv[ARG_STDIN..ARG_STDERR] are the file descriptor numbers that + * should be dup2'd to 0, 1 and 2. '-' if the corresponding fd + * should be left alone, and 'z' if it should be connected to the + * bit bucket NUL:. + */ + if (__argv[ARG_STDIN][0] == '-') + ; /* Nothing */ + else if (__argv[ARG_STDIN][0] == 'z') + { + fd = open ("NUL:", O_RDONLY); + if (fd != 0) + { + dup2 (fd, 0); + close (fd); + } + } + else + { + fd = atoi (__argv[ARG_STDIN]); + if (fd != 0) + { + dup2 (fd, 0); + close (fd); + } + } + + if (__argv[ARG_STDOUT][0] == '-') + ; /* Nothing */ + else if (__argv[ARG_STDOUT][0] == 'z') + { + fd = open ("NUL:", O_WRONLY); + if (fd != 1) + { + dup2 (fd, 1); + close (fd); + } + } + else + { + fd = atoi (__argv[ARG_STDOUT]); + if (fd != 1) + { + dup2 (fd, 1); + close (fd); + } + } + + if (__argv[ARG_STDERR][0] == '-') + ; /* Nothing */ + else if (__argv[ARG_STDERR][0] == 'z') + { + fd = open ("NUL:", O_WRONLY); + if (fd != 2) + { + dup2 (fd, 2); + close (fd); + } + } + else + { + fd = atoi (__argv[ARG_STDERR]); + if (fd != 2) + { + dup2 (fd, 2); + close (fd); + } + } + + /* __argv[ARG_WORKING_DIRECTORY] is the directory in which to run the + * process. If "-", don't change directory. + */ + if (__argv[ARG_WORKING_DIRECTORY][0] == '-' && + __argv[ARG_WORKING_DIRECTORY][1] == 0) + ; /* Nothing */ + else if (_wchdir (wargv[ARG_WORKING_DIRECTORY]) < 0) + write_err_and_exit (child_err_report_fd, CHILD_CHDIR_FAILED); + + /* __argv[ARG_CLOSE_DESCRIPTORS] is "y" if file descriptors from 3 + * upwards should be closed + */ + if (__argv[ARG_CLOSE_DESCRIPTORS][0] == 'y') + for (i = 3; i < 1000; i++) /* FIXME real limit? */ + if (i != child_err_report_fd && i != helper_sync_fd) + close (i); + + /* We don't want our child to inherit the error report and + * helper sync fds. + */ + child_err_report_fd = dup_noninherited (child_err_report_fd, _O_WRONLY); + helper_sync_fd = dup_noninherited (helper_sync_fd, _O_RDONLY); + + /* __argv[ARG_WAIT] is "w" to wait for the program to exit */ + if (__argv[ARG_WAIT][0] == 'w') + mode = P_WAIT; + else + mode = P_NOWAIT; + + /* __argv[ARG_USE_PATH] is "y" to use PATH, otherwise not */ + + /* __argv[ARG_PROGRAM] is executable file to run, + * __argv[argv_zero_offset]... is its argv. argv_zero_offset equals + * ARG_PROGRAM unless G_SPAWN_FILE_AND_ARGV_ZERO was used, in which + * case we have a separate executable name and argv[0]. + */ + + /* For the program name passed to spawnv(), don't use the quoted + * version. + */ + protect_wargv (wargv + argv_zero_offset, &new_wargv); + + if (__argv[ARG_USE_PATH][0] == 'y') + handle = _wspawnvp (mode, wargv[ARG_PROGRAM], (const wchar_t **) new_wargv); + else + handle = _wspawnv (mode, wargv[ARG_PROGRAM], (const wchar_t **) new_wargv); + + saved_errno = errno; + + if (handle == -1 && saved_errno != 0) + write_err_and_exit (child_err_report_fd, CHILD_SPAWN_FAILED); + + write (child_err_report_fd, &no_error, sizeof (no_error)); + write (child_err_report_fd, &handle, sizeof (handle)); + + read (helper_sync_fd, &c, 1); + + return 0; +} diff --git a/glib/glib/gspawn-win32.c b/glib/glib/gspawn-win32.c new file mode 100644 index 0000000..44ae907 --- /dev/null +++ b/glib/glib/gspawn-win32.c @@ -0,0 +1,1493 @@ +/* gspawn-win32.c - Process launching on Win32 + * + * Copyright 2000 Red Hat, Inc. + * Copyright 2003 Tor Lillqvist + * + * GLib is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, write + * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Implementation details on Win32. + * + * - There is no way to set the no-inherit flag for + * a "file descriptor" in the MS C runtime. The flag is there, + * and the dospawn() function uses it, but unfortunately + * this flag can only be set when opening the file. + * - As there is no fork(), we cannot reliably change directory + * before starting the child process. (There might be several threads + * running, and the current directory is common for all threads.) + * + * Thus, we must in many cases use a helper program to handle closing + * of (inherited) file descriptors and changing of directory. The + * helper process is also needed if the standard input, standard + * output, or standard error of the process to be run are supposed to + * be redirected somewhere. + * + * The structure of the source code in this file is a mess, I know. + */ + +/* Define this to get some logging all the time */ +/* #define G_SPAWN_WIN32_DEBUG */ + +#include "config.h" + +#include "glib.h" +#include "gprintfint.h" +#include "glibintl.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef G_SPAWN_WIN32_DEBUG + static int debug = 1; + #define SETUP_DEBUG() /* empty */ +#else + static int debug = -1; + #define SETUP_DEBUG() \ + G_STMT_START \ + { \ + if (debug == -1) \ + { \ + if (getenv ("G_SPAWN_WIN32_DEBUG") != NULL) \ + debug = 1; \ + else \ + debug = 0; \ + } \ + } \ + G_STMT_END +#endif + +enum +{ + CHILD_NO_ERROR, + CHILD_CHDIR_FAILED, + CHILD_SPAWN_FAILED, +}; + +enum { + ARG_CHILD_ERR_REPORT = 1, + ARG_HELPER_SYNC, + ARG_STDIN, + ARG_STDOUT, + ARG_STDERR, + ARG_WORKING_DIRECTORY, + ARG_CLOSE_DESCRIPTORS, + ARG_USE_PATH, + ARG_WAIT, + ARG_PROGRAM, + ARG_COUNT = ARG_PROGRAM +}; + +static int +dup_noninherited (int fd, + int mode) +{ + HANDLE filehandle; + + DuplicateHandle (GetCurrentProcess (), (LPHANDLE) _get_osfhandle (fd), + GetCurrentProcess (), &filehandle, + 0, FALSE, DUPLICATE_SAME_ACCESS); + close (fd); + return _open_osfhandle ((gintptr) filehandle, mode | _O_NOINHERIT); +} + +#ifndef GSPAWN_HELPER + +#ifdef _WIN64 +#define HELPER_PROCESS "gspawn-win64-helper" +#else +#define HELPER_PROCESS "gspawn-win32-helper" +#endif + +static gchar * +protect_argv_string (const gchar *string) +{ + const gchar *p = string; + gchar *retval, *q; + gint len = 0; + gboolean need_dblquotes = FALSE; + while (*p) + { + if (*p == ' ' || *p == '\t') + need_dblquotes = TRUE; + else if (*p == '"') + len++; + else if (*p == '\\') + { + const gchar *pp = p; + while (*pp && *pp == '\\') + pp++; + if (*pp == '"') + len++; + } + len++; + p++; + } + + q = retval = g_malloc (len + need_dblquotes*2 + 1); + p = string; + + if (need_dblquotes) + *q++ = '"'; + + while (*p) + { + if (*p == '"') + *q++ = '\\'; + else if (*p == '\\') + { + const gchar *pp = p; + while (*pp && *pp == '\\') + pp++; + if (*pp == '"') + *q++ = '\\'; + } + *q++ = *p; + p++; + } + + if (need_dblquotes) + *q++ = '"'; + *q++ = '\0'; + + return retval; +} + +static gint +protect_argv (gchar **argv, + gchar ***new_argv) +{ + gint i; + gint argc = 0; + + while (argv[argc]) + ++argc; + *new_argv = g_new (gchar *, argc+1); + + /* Quote each argv element if necessary, so that it will get + * reconstructed correctly in the C runtime startup code. Note that + * the unquoting algorithm in the C runtime is really weird, and + * rather different than what Unix shells do. See stdargv.c in the C + * runtime sources (in the Platform SDK, in src/crt). + * + * Note that an new_argv[0] constructed by this function should + * *not* be passed as the filename argument to a spawn* or exec* + * family function. That argument should be the real file name + * without any quoting. + */ + for (i = 0; i < argc; i++) + (*new_argv)[i] = protect_argv_string (argv[i]); + + (*new_argv)[argc] = NULL; + + return argc; +} + +GQuark +g_spawn_error_quark (void) +{ + return g_quark_from_static_string ("g-exec-error-quark"); +} + +gboolean +g_spawn_async_utf8 (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_handle, + GError **error) +{ + g_return_val_if_fail (argv != NULL, FALSE); + + return g_spawn_async_with_pipes_utf8 (working_directory, + argv, envp, + flags, + child_setup, + user_data, + child_handle, + NULL, NULL, NULL, + error); +} + +/* Avoids a danger in threaded situations (calling close() + * on a file descriptor twice, and another thread has + * re-opened it since the first close) + */ +static void +close_and_invalidate (gint *fd) +{ + if (*fd < 0) + return; + + close (*fd); + *fd = -1; +} + +typedef enum +{ + READ_FAILED = 0, /* FALSE */ + READ_OK, + READ_EOF +} ReadResult; + +static ReadResult +read_data (GString *str, + GIOChannel *iochannel, + GError **error) +{ + GIOStatus giostatus; + gsize bytes; + gchar buf[4096]; + + again: + + giostatus = g_io_channel_read_chars (iochannel, buf, sizeof (buf), &bytes, NULL); + + if (bytes == 0) + return READ_EOF; + else if (bytes > 0) + { + g_string_append_len (str, buf, bytes); + return READ_OK; + } + else if (giostatus == G_IO_STATUS_AGAIN) + goto again; + else if (giostatus == G_IO_STATUS_ERROR) + { + g_set_error_literal (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ, + _("Failed to read data from child process")); + + return READ_FAILED; + } + else + return READ_OK; +} + +static gboolean +make_pipe (gint p[2], + GError **error) +{ + if (_pipe (p, 4096, _O_BINARY) < 0) + { + int errsv = errno; + + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Failed to create pipe for communicating with child process (%s)"), + g_strerror (errsv)); + return FALSE; + } + else + return TRUE; +} + +/* The helper process writes a status report back to us, through a + * pipe, consisting of two ints. + */ +static gboolean +read_helper_report (int fd, + gintptr report[2], + GError **error) +{ + gint bytes = 0; + + while (bytes < sizeof(gintptr)*2) + { + gint chunk; + + if (debug) + g_print ("%s:read_helper_report: read %" G_GSIZE_FORMAT "...\n", + __FILE__, + sizeof(gintptr)*2 - bytes); + + chunk = read (fd, ((gchar*)report) + bytes, + sizeof(gintptr)*2 - bytes); + + if (debug) + g_print ("...got %d bytes\n", chunk); + + if (chunk < 0) + { + int errsv = errno; + + /* Some weird shit happened, bail out */ + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Failed to read from child pipe (%s)"), + g_strerror (errsv)); + + return FALSE; + } + else if (chunk == 0) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Failed to read from child pipe (%s)"), + "EOF"); + break; /* EOF */ + } + else + bytes += chunk; + } + + if (bytes < sizeof(gintptr)*2) + return FALSE; + + return TRUE; +} + +static void +set_child_error (gintptr report[2], + const gchar *working_directory, + GError **error) +{ + switch (report[0]) + { + case CHILD_CHDIR_FAILED: + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR, + _("Failed to change to directory '%s' (%s)"), + working_directory, + g_strerror (report[1])); + break; + case CHILD_SPAWN_FAILED: + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Failed to execute child process (%s)"), + g_strerror (report[1])); + break; + default: + g_assert_not_reached (); + } +} + +static gboolean +utf8_charv_to_wcharv (char **utf8_charv, + wchar_t ***wcharv, + int *error_index, + GError **error) +{ + wchar_t **retval = NULL; + + *wcharv = NULL; + if (utf8_charv != NULL) + { + int n = 0, i; + + while (utf8_charv[n]) + n++; + retval = g_new (wchar_t *, n + 1); + + for (i = 0; i < n; i++) + { + retval[i] = g_utf8_to_utf16 (utf8_charv[i], -1, NULL, NULL, error); + if (retval[i] == NULL) + { + if (error_index) + *error_index = i; + while (i) + g_free (retval[--i]); + g_free (retval); + return FALSE; + } + } + + retval[n] = NULL; + } + *wcharv = retval; + return TRUE; +} + +static gboolean +do_spawn_directly (gint *exit_status, + gboolean do_return_handle, + GSpawnFlags flags, + gchar **argv, + char **envp, + char **protected_argv, + GPid *child_handle, + GError **error) +{ + const int mode = (exit_status == NULL) ? P_NOWAIT : P_WAIT; + char **new_argv; + gintptr rc = -1; + int saved_errno; + GError *conv_error = NULL; + gint conv_error_index; + wchar_t *wargv0, **wargv, **wenvp; + + new_argv = (flags & G_SPAWN_FILE_AND_ARGV_ZERO) ? protected_argv + 1 : protected_argv; + + wargv0 = g_utf8_to_utf16 (argv[0], -1, NULL, NULL, &conv_error); + if (wargv0 == NULL) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Invalid program name: %s"), + conv_error->message); + g_error_free (conv_error); + + return FALSE; + } + + if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error)) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Invalid string in argument vector at %d: %s"), + conv_error_index, conv_error->message); + g_error_free (conv_error); + g_free (wargv0); + + return FALSE; + } + + if (!utf8_charv_to_wcharv (envp, &wenvp, NULL, &conv_error)) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Invalid string in environment: %s"), + conv_error->message); + g_error_free (conv_error); + g_free (wargv0); + g_strfreev ((gchar **) wargv); + + return FALSE; + } + + if (flags & G_SPAWN_SEARCH_PATH) + if (wenvp != NULL) + rc = _wspawnvpe (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp); + else + rc = _wspawnvp (mode, wargv0, (const wchar_t **) wargv); + else + if (wenvp != NULL) + rc = _wspawnve (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp); + else + rc = _wspawnv (mode, wargv0, (const wchar_t **) wargv); + + g_free (wargv0); + g_strfreev ((gchar **) wargv); + g_strfreev ((gchar **) wenvp); + + saved_errno = errno; + + if (rc == -1 && saved_errno != 0) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Failed to execute child process (%s)"), + g_strerror (saved_errno)); + return FALSE; + } + + if (exit_status == NULL) + { + if (child_handle && do_return_handle) + *child_handle = (GPid) rc; + else + { + CloseHandle ((HANDLE) rc); + if (child_handle) + *child_handle = 0; + } + } + else + *exit_status = rc; + + return TRUE; +} + +static gboolean +do_spawn_with_pipes (gint *exit_status, + gboolean do_return_handle, + const gchar *working_directory, + gchar **argv, + char **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + GPid *child_handle, + gint *standard_input, + gint *standard_output, + gint *standard_error, + gint *err_report, + GError **error) +{ + char **protected_argv; + char args[ARG_COUNT][10]; + char **new_argv; + int i; + gintptr rc = -1; + int saved_errno; + int argc; + int stdin_pipe[2] = { -1, -1 }; + int stdout_pipe[2] = { -1, -1 }; + int stderr_pipe[2] = { -1, -1 }; + int child_err_report_pipe[2] = { -1, -1 }; + int helper_sync_pipe[2] = { -1, -1 }; + gintptr helper_report[2]; + static gboolean warned_about_child_setup = FALSE; + GError *conv_error = NULL; + gint conv_error_index; + gchar *helper_process; + CONSOLE_CURSOR_INFO cursor_info; + wchar_t *whelper, **wargv, **wenvp; + extern gchar *_glib_get_dll_directory (void); + gchar *glib_dll_directory; + + if (child_setup && !warned_about_child_setup) + { + warned_about_child_setup = TRUE; + g_warning ("passing a child setup function to the g_spawn functions is pointless on Windows and it is ignored"); + } + + argc = protect_argv (argv, &protected_argv); + + if (!standard_input && !standard_output && !standard_error && + (flags & G_SPAWN_CHILD_INHERITS_STDIN) && + !(flags & G_SPAWN_STDOUT_TO_DEV_NULL) && + !(flags & G_SPAWN_STDERR_TO_DEV_NULL) && + (working_directory == NULL || !*working_directory) && + (flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN)) + { + /* We can do without the helper process */ + gboolean retval = + do_spawn_directly (exit_status, do_return_handle, flags, + argv, envp, protected_argv, + child_handle, error); + g_strfreev (protected_argv); + return retval; + } + + if (standard_input && !make_pipe (stdin_pipe, error)) + goto cleanup_and_fail; + + if (standard_output && !make_pipe (stdout_pipe, error)) + goto cleanup_and_fail; + + if (standard_error && !make_pipe (stderr_pipe, error)) + goto cleanup_and_fail; + + if (!make_pipe (child_err_report_pipe, error)) + goto cleanup_and_fail; + + if (!make_pipe (helper_sync_pipe, error)) + goto cleanup_and_fail; + + new_argv = g_new (char *, argc + 1 + ARG_COUNT); + if (GetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cursor_info)) + helper_process = HELPER_PROCESS "-console.exe"; + else + helper_process = HELPER_PROCESS ".exe"; + + glib_dll_directory = _glib_get_dll_directory (); + if (glib_dll_directory != NULL) + { + helper_process = g_build_filename (glib_dll_directory, helper_process, NULL); + g_free (glib_dll_directory); + } + else + helper_process = g_strdup (helper_process); + + new_argv[0] = protect_argv_string (helper_process); + + _g_sprintf (args[ARG_CHILD_ERR_REPORT], "%d", child_err_report_pipe[1]); + new_argv[ARG_CHILD_ERR_REPORT] = args[ARG_CHILD_ERR_REPORT]; + + /* Make the read end of the child error report pipe + * noninherited. Otherwise it will needlessly be inherited by the + * helper process, and the started actual user process. As such that + * shouldn't harm, but it is unnecessary. + */ + child_err_report_pipe[0] = dup_noninherited (child_err_report_pipe[0], _O_RDONLY); + + if (flags & G_SPAWN_FILE_AND_ARGV_ZERO) + { + /* Overload ARG_CHILD_ERR_REPORT to also encode the + * G_SPAWN_FILE_AND_ARGV_ZERO functionality. + */ + strcat (args[ARG_CHILD_ERR_REPORT], "#"); + } + + _g_sprintf (args[ARG_HELPER_SYNC], "%d", helper_sync_pipe[0]); + new_argv[ARG_HELPER_SYNC] = args[ARG_HELPER_SYNC]; + + /* Make the write end of the sync pipe noninherited. Otherwise the + * helper process will inherit it, and thus if this process happens + * to crash before writing the sync byte to the pipe, the helper + * process won't read but won't get any EOF either, as it has the + * write end open itself. + */ + helper_sync_pipe[1] = dup_noninherited (helper_sync_pipe[1], _O_WRONLY); + + if (standard_input) + { + _g_sprintf (args[ARG_STDIN], "%d", stdin_pipe[0]); + new_argv[ARG_STDIN] = args[ARG_STDIN]; + } + else if (flags & G_SPAWN_CHILD_INHERITS_STDIN) + { + /* Let stdin be alone */ + new_argv[ARG_STDIN] = "-"; + } + else + { + /* Keep process from blocking on a read of stdin */ + new_argv[ARG_STDIN] = "z"; + } + + if (standard_output) + { + _g_sprintf (args[ARG_STDOUT], "%d", stdout_pipe[1]); + new_argv[ARG_STDOUT] = args[ARG_STDOUT]; + } + else if (flags & G_SPAWN_STDOUT_TO_DEV_NULL) + { + new_argv[ARG_STDOUT] = "z"; + } + else + { + new_argv[ARG_STDOUT] = "-"; + } + + if (standard_error) + { + _g_sprintf (args[ARG_STDERR], "%d", stderr_pipe[1]); + new_argv[ARG_STDERR] = args[ARG_STDERR]; + } + else if (flags & G_SPAWN_STDERR_TO_DEV_NULL) + { + new_argv[ARG_STDERR] = "z"; + } + else + { + new_argv[ARG_STDERR] = "-"; + } + + if (working_directory && *working_directory) + new_argv[ARG_WORKING_DIRECTORY] = protect_argv_string (working_directory); + else + new_argv[ARG_WORKING_DIRECTORY] = g_strdup ("-"); + + if (!(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN)) + new_argv[ARG_CLOSE_DESCRIPTORS] = "y"; + else + new_argv[ARG_CLOSE_DESCRIPTORS] = "-"; + + if (flags & G_SPAWN_SEARCH_PATH) + new_argv[ARG_USE_PATH] = "y"; + else + new_argv[ARG_USE_PATH] = "-"; + + if (exit_status == NULL) + new_argv[ARG_WAIT] = "-"; + else + new_argv[ARG_WAIT] = "w"; + + for (i = 0; i <= argc; i++) + new_argv[ARG_PROGRAM + i] = protected_argv[i]; + + SETUP_DEBUG(); + + if (debug) + { + g_print ("calling %s with argv:\n", helper_process); + for (i = 0; i < argc + 1 + ARG_COUNT; i++) + g_print ("argv[%d]: %s\n", i, (new_argv[i] ? new_argv[i] : "NULL")); + } + + if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error)) + { + if (conv_error_index == ARG_WORKING_DIRECTORY) + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR, + _("Invalid working directory: %s"), + conv_error->message); + else + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Invalid string in argument vector at %d: %s"), + conv_error_index - ARG_PROGRAM, conv_error->message); + g_error_free (conv_error); + g_strfreev (protected_argv); + g_free (new_argv[0]); + g_free (new_argv[ARG_WORKING_DIRECTORY]); + g_free (new_argv); + g_free (helper_process); + + goto cleanup_and_fail; + } + + if (!utf8_charv_to_wcharv (envp, &wenvp, NULL, &conv_error)) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Invalid string in environment: %s"), + conv_error->message); + g_error_free (conv_error); + g_strfreev (protected_argv); + g_free (new_argv[0]); + g_free (new_argv[ARG_WORKING_DIRECTORY]); + g_free (new_argv); + g_free (helper_process); + g_strfreev ((gchar **) wargv); + + goto cleanup_and_fail; + } + + whelper = g_utf8_to_utf16 (helper_process, -1, NULL, NULL, NULL); + g_free (helper_process); + + if (wenvp != NULL) + rc = _wspawnvpe (P_NOWAIT, whelper, (const wchar_t **) wargv, (const wchar_t **) wenvp); + else + rc = _wspawnvp (P_NOWAIT, whelper, (const wchar_t **) wargv); + + saved_errno = errno; + + g_free (whelper); + g_strfreev ((gchar **) wargv); + g_strfreev ((gchar **) wenvp); + + /* Close the other process's ends of the pipes in this process, + * otherwise the reader will never get EOF. + */ + close_and_invalidate (&child_err_report_pipe[1]); + close_and_invalidate (&helper_sync_pipe[0]); + close_and_invalidate (&stdin_pipe[0]); + close_and_invalidate (&stdout_pipe[1]); + close_and_invalidate (&stderr_pipe[1]); + + g_strfreev (protected_argv); + + g_free (new_argv[0]); + g_free (new_argv[ARG_WORKING_DIRECTORY]); + g_free (new_argv); + + /* Check if gspawn-win32-helper couldn't be run */ + if (rc == -1 && saved_errno != 0) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Failed to execute helper program (%s)"), + g_strerror (saved_errno)); + goto cleanup_and_fail; + } + + if (exit_status != NULL) + { + /* Synchronous case. Pass helper's report pipe back to caller, + * which takes care of reading it after the grandchild has + * finished. + */ + g_assert (err_report != NULL); + *err_report = child_err_report_pipe[0]; + write (helper_sync_pipe[1], " ", 1); + close_and_invalidate (&helper_sync_pipe[1]); + } + else + { + /* Asynchronous case. We read the helper's report right away. */ + if (!read_helper_report (child_err_report_pipe[0], helper_report, error)) + goto cleanup_and_fail; + + close_and_invalidate (&child_err_report_pipe[0]); + + switch (helper_report[0]) + { + case CHILD_NO_ERROR: + if (child_handle && do_return_handle) + { + /* rc is our HANDLE for gspawn-win32-helper. It has + * told us the HANDLE of its child. Duplicate that into + * a HANDLE valid in this process. + */ + if (!DuplicateHandle ((HANDLE) rc, (HANDLE) helper_report[1], + GetCurrentProcess (), (LPHANDLE) child_handle, + 0, TRUE, DUPLICATE_SAME_ACCESS)) + { + char *emsg = g_win32_error_message (GetLastError ()); + g_print("%s\n", emsg); + *child_handle = 0; + } + } + else if (child_handle) + *child_handle = 0; + write (helper_sync_pipe[1], " ", 1); + close_and_invalidate (&helper_sync_pipe[1]); + break; + + default: + write (helper_sync_pipe[1], " ", 1); + close_and_invalidate (&helper_sync_pipe[1]); + set_child_error (helper_report, working_directory, error); + goto cleanup_and_fail; + } + } + + /* Success against all odds! return the information */ + + if (standard_input) + *standard_input = stdin_pipe[1]; + if (standard_output) + *standard_output = stdout_pipe[0]; + if (standard_error) + *standard_error = stderr_pipe[0]; + if (rc != -1) + CloseHandle ((HANDLE) rc); + + return TRUE; + + cleanup_and_fail: + + if (rc != -1) + CloseHandle ((HANDLE) rc); + if (child_err_report_pipe[0] != -1) + close (child_err_report_pipe[0]); + if (child_err_report_pipe[1] != -1) + close (child_err_report_pipe[1]); + if (helper_sync_pipe[0] != -1) + close (helper_sync_pipe[0]); + if (helper_sync_pipe[1] != -1) + close (helper_sync_pipe[1]); + if (stdin_pipe[0] != -1) + close (stdin_pipe[0]); + if (stdin_pipe[1] != -1) + close (stdin_pipe[1]); + if (stdout_pipe[0] != -1) + close (stdout_pipe[0]); + if (stdout_pipe[1] != -1) + close (stdout_pipe[1]); + if (stderr_pipe[0] != -1) + close (stderr_pipe[0]); + if (stderr_pipe[1] != -1) + close (stderr_pipe[1]); + + return FALSE; +} + +gboolean +g_spawn_sync_utf8 (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error) +{ + gint outpipe = -1; + gint errpipe = -1; + gint reportpipe = -1; + GIOChannel *outchannel = NULL; + GIOChannel *errchannel = NULL; + GPollFD outfd, errfd; + GPollFD fds[2]; + gint nfds; + gint outindex = -1; + gint errindex = -1; + gint ret; + GString *outstr = NULL; + GString *errstr = NULL; + gboolean failed; + gint status; + + g_return_val_if_fail (argv != NULL, FALSE); + g_return_val_if_fail (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), FALSE); + g_return_val_if_fail (standard_output == NULL || + !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE); + g_return_val_if_fail (standard_error == NULL || + !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE); + + /* Just to ensure segfaults if callers try to use + * these when an error is reported. + */ + if (standard_output) + *standard_output = NULL; + + if (standard_error) + *standard_error = NULL; + + if (!do_spawn_with_pipes (&status, + FALSE, + working_directory, + argv, + envp, + flags, + child_setup, + NULL, + NULL, + standard_output ? &outpipe : NULL, + standard_error ? &errpipe : NULL, + &reportpipe, + error)) + return FALSE; + + /* Read data from child. */ + + failed = FALSE; + + if (outpipe >= 0) + { + outstr = g_string_new (NULL); + outchannel = g_io_channel_win32_new_fd (outpipe); + g_io_channel_set_encoding (outchannel, NULL, NULL); + g_io_channel_set_buffered (outchannel, FALSE); + g_io_channel_win32_make_pollfd (outchannel, + G_IO_IN | G_IO_ERR | G_IO_HUP, + &outfd); + if (debug) + g_print ("outfd=%p\n", (HANDLE) outfd.fd); + } + + if (errpipe >= 0) + { + errstr = g_string_new (NULL); + errchannel = g_io_channel_win32_new_fd (errpipe); + g_io_channel_set_encoding (errchannel, NULL, NULL); + g_io_channel_set_buffered (errchannel, FALSE); + g_io_channel_win32_make_pollfd (errchannel, + G_IO_IN | G_IO_ERR | G_IO_HUP, + &errfd); + if (debug) + g_print ("errfd=%p\n", (HANDLE) errfd.fd); + } + + /* Read data until we get EOF on all pipes. */ + while (!failed && (outpipe >= 0 || errpipe >= 0)) + { + nfds = 0; + if (outpipe >= 0) + { + fds[nfds] = outfd; + outindex = nfds; + nfds++; + } + if (errpipe >= 0) + { + fds[nfds] = errfd; + errindex = nfds; + nfds++; + } + + if (debug) + g_print ("g_spawn_sync: calling g_io_channel_win32_poll, nfds=%d\n", + nfds); + + ret = g_io_channel_win32_poll (fds, nfds, -1); + + if (ret < 0) + { + failed = TRUE; + + g_set_error_literal (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ, + _("Unexpected error in g_io_channel_win32_poll() reading data from a child process")); + + break; + } + + if (outpipe >= 0 && (fds[outindex].revents & G_IO_IN)) + { + switch (read_data (outstr, outchannel, error)) + { + case READ_FAILED: + if (debug) + g_print ("g_spawn_sync: outchannel: READ_FAILED\n"); + failed = TRUE; + break; + case READ_EOF: + if (debug) + g_print ("g_spawn_sync: outchannel: READ_EOF\n"); + g_io_channel_unref (outchannel); + outchannel = NULL; + close_and_invalidate (&outpipe); + break; + default: + if (debug) + g_print ("g_spawn_sync: outchannel: OK\n"); + break; + } + + if (failed) + break; + } + + if (errpipe >= 0 && (fds[errindex].revents & G_IO_IN)) + { + switch (read_data (errstr, errchannel, error)) + { + case READ_FAILED: + if (debug) + g_print ("g_spawn_sync: errchannel: READ_FAILED\n"); + failed = TRUE; + break; + case READ_EOF: + if (debug) + g_print ("g_spawn_sync: errchannel: READ_EOF\n"); + g_io_channel_unref (errchannel); + errchannel = NULL; + close_and_invalidate (&errpipe); + break; + default: + if (debug) + g_print ("g_spawn_sync: errchannel: OK\n"); + break; + } + + if (failed) + break; + } + } + + if (reportpipe == -1) + { + /* No helper process, exit status of actual spawned process + * already available. + */ + if (exit_status) + *exit_status = status; + } + else + { + /* Helper process was involved. Read its report now after the + * grandchild has finished. + */ + gintptr helper_report[2]; + + if (!read_helper_report (reportpipe, helper_report, error)) + failed = TRUE; + else + { + switch (helper_report[0]) + { + case CHILD_NO_ERROR: + if (exit_status) + *exit_status = helper_report[1]; + break; + default: + set_child_error (helper_report, working_directory, error); + failed = TRUE; + break; + } + } + close_and_invalidate (&reportpipe); + } + + + /* These should only be open still if we had an error. */ + + if (outchannel != NULL) + g_io_channel_unref (outchannel); + if (errchannel != NULL) + g_io_channel_unref (errchannel); + if (outpipe >= 0) + close_and_invalidate (&outpipe); + if (errpipe >= 0) + close_and_invalidate (&errpipe); + + if (failed) + { + if (outstr) + g_string_free (outstr, TRUE); + if (errstr) + g_string_free (errstr, TRUE); + + return FALSE; + } + else + { + if (standard_output) + *standard_output = g_string_free (outstr, FALSE); + + if (standard_error) + *standard_error = g_string_free (errstr, FALSE); + + return TRUE; + } +} + +gboolean +g_spawn_async_with_pipes_utf8 (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_handle, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error) +{ + g_return_val_if_fail (argv != NULL, FALSE); + g_return_val_if_fail (standard_output == NULL || + !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE); + g_return_val_if_fail (standard_error == NULL || + !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE); + /* can't inherit stdin if we have an input pipe. */ + g_return_val_if_fail (standard_input == NULL || + !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE); + + return do_spawn_with_pipes (NULL, + (flags & G_SPAWN_DO_NOT_REAP_CHILD), + working_directory, + argv, + envp, + flags, + child_setup, + child_handle, + standard_input, + standard_output, + standard_error, + NULL, + error); +} + +gboolean +g_spawn_command_line_sync_utf8 (const gchar *command_line, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error) +{ + gboolean retval; + gchar **argv = 0; + + g_return_val_if_fail (command_line != NULL, FALSE); + + if (!g_shell_parse_argv (command_line, + NULL, &argv, + error)) + return FALSE; + + retval = g_spawn_sync_utf8 (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + standard_output, + standard_error, + exit_status, + error); + g_strfreev (argv); + + return retval; +} + +gboolean +g_spawn_command_line_async_utf8 (const gchar *command_line, + GError **error) +{ + gboolean retval; + gchar **argv = 0; + + g_return_val_if_fail (command_line != NULL, FALSE); + + if (!g_shell_parse_argv (command_line, + NULL, &argv, + error)) + return FALSE; + + retval = g_spawn_async_utf8 (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + error); + g_strfreev (argv); + + return retval; +} + +void +g_spawn_close_pid (GPid pid) +{ + CloseHandle (pid); +} + +#if !defined (_WIN64) + +/* Binary compatibility versions that take system codepage pathnames, + * argument vectors and environments. These get used only by code + * built against 2.8.1 or earlier. Code built against 2.8.2 or later + * will use the _utf8 versions above (see the #defines in gspawn.h). + */ + +#undef g_spawn_async +#undef g_spawn_async_with_pipes +#undef g_spawn_sync +#undef g_spawn_command_line_sync +#undef g_spawn_command_line_async + +static gboolean +setup_utf8_copies (const gchar *working_directory, + gchar **utf8_working_directory, + gchar **argv, + gchar ***utf8_argv, + gchar **envp, + gchar ***utf8_envp, + GError **error) +{ + gint i, argc, envc; + + if (working_directory == NULL) + *utf8_working_directory = NULL; + else + { + GError *conv_error = NULL; + + *utf8_working_directory = g_locale_to_utf8 (working_directory, -1, NULL, NULL, &conv_error); + if (*utf8_working_directory == NULL) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR, + _("Invalid working directory: %s"), + conv_error->message); + g_error_free (conv_error); + return FALSE; + } + } + + argc = 0; + while (argv[argc]) + ++argc; + *utf8_argv = g_new (gchar *, argc + 1); + for (i = 0; i < argc; i++) + { + GError *conv_error = NULL; + + (*utf8_argv)[i] = g_locale_to_utf8 (argv[i], -1, NULL, NULL, &conv_error); + if ((*utf8_argv)[i] == NULL) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Invalid string in argument vector at %d: %s"), + i, conv_error->message); + g_error_free (conv_error); + + g_strfreev (*utf8_argv); + *utf8_argv = NULL; + + g_free (*utf8_working_directory); + *utf8_working_directory = NULL; + + return FALSE; + } + } + (*utf8_argv)[argc] = NULL; + + if (envp == NULL) + { + *utf8_envp = NULL; + } + else + { + envc = 0; + while (envp[envc]) + ++envc; + *utf8_envp = g_new (gchar *, envc + 1); + for (i = 0; i < envc; i++) + { + GError *conv_error = NULL; + + (*utf8_envp)[i] = g_locale_to_utf8 (envp[i], -1, NULL, NULL, &conv_error); + if ((*utf8_envp)[i] == NULL) + { + g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED, + _("Invalid string in environment: %s"), + conv_error->message); + g_error_free (conv_error); + + g_strfreev (*utf8_envp); + *utf8_envp = NULL; + + g_strfreev (*utf8_argv); + *utf8_argv = NULL; + + g_free (*utf8_working_directory); + *utf8_working_directory = NULL; + + return FALSE; + } + } + (*utf8_envp)[envc] = NULL; + } + return TRUE; +} + +static void +free_utf8_copies (gchar *utf8_working_directory, + gchar **utf8_argv, + gchar **utf8_envp) +{ + g_free (utf8_working_directory); + g_strfreev (utf8_argv); + g_strfreev (utf8_envp); +} + +gboolean +g_spawn_async_with_pipes (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_handle, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error) +{ + gchar *utf8_working_directory; + gchar **utf8_argv; + gchar **utf8_envp; + gboolean retval; + + if (!setup_utf8_copies (working_directory, &utf8_working_directory, + argv, &utf8_argv, + envp, &utf8_envp, + error)) + return FALSE; + + retval = g_spawn_async_with_pipes_utf8 (utf8_working_directory, + utf8_argv, utf8_envp, + flags, child_setup, user_data, + child_handle, + standard_input, standard_output, standard_error, + error); + + free_utf8_copies (utf8_working_directory, utf8_argv, utf8_envp); + + return retval; +} + +gboolean +g_spawn_async (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_handle, + GError **error) +{ + return g_spawn_async_with_pipes (working_directory, + argv, envp, + flags, + child_setup, + user_data, + child_handle, + NULL, NULL, NULL, + error); +} + +gboolean +g_spawn_sync (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error) +{ + gchar *utf8_working_directory; + gchar **utf8_argv; + gchar **utf8_envp; + gboolean retval; + + if (!setup_utf8_copies (working_directory, &utf8_working_directory, + argv, &utf8_argv, + envp, &utf8_envp, + error)) + return FALSE; + + retval = g_spawn_sync_utf8 (utf8_working_directory, + utf8_argv, utf8_envp, + flags, child_setup, user_data, + standard_output, standard_error, exit_status, + error); + + free_utf8_copies (utf8_working_directory, utf8_argv, utf8_envp); + + return retval; +} + +gboolean +g_spawn_command_line_sync (const gchar *command_line, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error) +{ + gboolean retval; + gchar **argv = 0; + + g_return_val_if_fail (command_line != NULL, FALSE); + + if (!g_shell_parse_argv (command_line, + NULL, &argv, + error)) + return FALSE; + + retval = g_spawn_sync (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + standard_output, + standard_error, + exit_status, + error); + g_strfreev (argv); + + return retval; +} + +gboolean +g_spawn_command_line_async (const gchar *command_line, + GError **error) +{ + gboolean retval; + gchar **argv = 0; + + g_return_val_if_fail (command_line != NULL, FALSE); + + if (!g_shell_parse_argv (command_line, + NULL, &argv, + error)) + return FALSE; + + retval = g_spawn_async (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + error); + g_strfreev (argv); + + return retval; +} + +#endif /* !_WIN64 */ + +#endif /* !GSPAWN_HELPER */ diff --git a/glib/glib/gspawn.c b/glib/glib/gspawn.c new file mode 100644 index 0000000..7df271f --- /dev/null +++ b/glib/glib/gspawn.c @@ -0,0 +1,1728 @@ +/* gspawn.c - Process launching + * + * Copyright 2000 Red Hat, Inc. + * g_execvpe implementation based on GNU libc execvp: + * Copyright 1991, 92, 95, 96, 97, 98, 99 Free Software Foundation, Inc. + * + * GLib is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, write + * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include /* for fdwalk */ +#include + +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ + +#ifdef HAVE_SYS_RESOURCE_H +#include +#endif /* HAVE_SYS_RESOURCE_H */ + +#include "gspawn.h" + +#include "genviron.h" +#include "gmem.h" +#include "gshell.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gutils.h" +#include "glibintl.h" + + +/** + * SECTION:spawn + * @Short_description: process launching + * @Title: Spawning Processes + */ + + + +static gint g_execute (const gchar *file, + gchar **argv, + gchar **envp, + gboolean search_path); + +static gboolean make_pipe (gint p[2], + GError **error); +static gboolean fork_exec_with_pipes (gboolean intermediate_child, + const gchar *working_directory, + gchar **argv, + gchar **envp, + gboolean close_descriptors, + gboolean search_path, + gboolean stdout_to_null, + gboolean stderr_to_null, + gboolean child_inherits_stdin, + gboolean file_and_argv_zero, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error); + +GQuark +g_spawn_error_quark (void) +{ + return g_quark_from_static_string ("g-exec-error-quark"); +} + +/** + * g_spawn_async: + * @working_directory: (allow-none): child's current working directory, or %NULL to inherit parent's + * @argv: (array zero-terminated=1): child's argument vector + * @envp: (array zero-terminated=1) (allow-none): child's environment, or %NULL to inherit parent's + * @flags: flags from #GSpawnFlags + * @child_setup: (scope async) (allow-none): function to run in the child just before exec() + * @user_data: (closure): user data for @child_setup + * @child_pid: (out) (allow-none): return location for child process reference, or %NULL + * @error: return location for error + * + * See g_spawn_async_with_pipes() for a full description; this function + * simply calls the g_spawn_async_with_pipes() without any pipes. + * + * You should call g_spawn_close_pid() on the returned child process + * reference when you don't need it any more. + * + * + * If you are writing a GTK+ application, and the program you + * are spawning is a graphical application, too, then you may + * want to use gdk_spawn_on_screen() instead to ensure that + * the spawned program opens its windows on the right screen. + * + * + * Note that the returned @child_pid on Windows is a + * handle to the child process and not its identifier. Process handles + * and process identifiers are different concepts on Windows. + * + * + * Return value: %TRUE on success, %FALSE if error is set + **/ +gboolean +g_spawn_async (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + GError **error) +{ + g_return_val_if_fail (argv != NULL, FALSE); + + return g_spawn_async_with_pipes (working_directory, + argv, envp, + flags, + child_setup, + user_data, + child_pid, + NULL, NULL, NULL, + error); +} + +/* Avoids a danger in threaded situations (calling close() + * on a file descriptor twice, and another thread has + * re-opened it since the first close) + */ +static gint +close_and_invalidate (gint *fd) +{ + gint ret; + + if (*fd < 0) + return -1; + else + { + again: + ret = close (*fd); + if (ret == -1 && errno == EINTR) + goto again; + *fd = -1; + } + + return ret; +} + +/* Some versions of OS X define READ_OK in public headers */ +#undef READ_OK + +typedef enum +{ + READ_FAILED = 0, /* FALSE */ + READ_OK, + READ_EOF +} ReadResult; + +static ReadResult +read_data (GString *str, + gint fd, + GError **error) +{ + gssize bytes; + gchar buf[4096]; + + again: + bytes = read (fd, buf, 4096); + + if (bytes == 0) + return READ_EOF; + else if (bytes > 0) + { + g_string_append_len (str, buf, bytes); + return READ_OK; + } + else if (errno == EINTR) + goto again; + else + { + int errsv = errno; + + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_READ, + _("Failed to read data from child process (%s)"), + g_strerror (errsv)); + + return READ_FAILED; + } +} + +/** + * g_spawn_sync: + * @working_directory: (allow-none): child's current working directory, or %NULL to inherit parent's + * @argv: (array zero-terminated=1): child's argument vector + * @envp: (array zero-terminated=1) (allow-none): child's environment, or %NULL to inherit parent's + * @flags: flags from #GSpawnFlags + * @child_setup: (scope async) (allow-none): function to run in the child just before exec() + * @user_data: (closure): user data for @child_setup + * @standard_output: (out) (array zero-terminated=1) (element-type guint8) (allow-none): return location for child output, or %NULL + * @standard_error: (out) (array zero-terminated=1) (element-type guint8) (allow-none): return location for child error messages, or %NULL + * @exit_status: (out) (allow-none): return location for child exit status, as returned by waitpid(), or %NULL + * @error: return location for error, or %NULL + * + * Executes a child synchronously (waits for the child to exit before returning). + * All output from the child is stored in @standard_output and @standard_error, + * if those parameters are non-%NULL. Note that you must set the + * %G_SPAWN_STDOUT_TO_DEV_NULL and %G_SPAWN_STDERR_TO_DEV_NULL flags when + * passing %NULL for @standard_output and @standard_error. + * If @exit_status is non-%NULL, the exit status of the child is stored + * there as it would be returned by waitpid(); standard UNIX macros such + * as WIFEXITED() and WEXITSTATUS() must be used to evaluate the exit status. + * Note that this function call waitpid() even if @exit_status is %NULL, and + * does not accept the %G_SPAWN_DO_NOT_REAP_CHILD flag. + * If an error occurs, no data is returned in @standard_output, + * @standard_error, or @exit_status. + * + * This function calls g_spawn_async_with_pipes() internally; see that + * function for full details on the other parameters and details on + * how these functions work on Windows. + * + * Return value: %TRUE on success, %FALSE if an error was set. + **/ +gboolean +g_spawn_sync (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error) +{ + gint outpipe = -1; + gint errpipe = -1; + GPid pid; + fd_set fds; + gint ret; + GString *outstr = NULL; + GString *errstr = NULL; + gboolean failed; + gint status; + + g_return_val_if_fail (argv != NULL, FALSE); + g_return_val_if_fail (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), FALSE); + g_return_val_if_fail (standard_output == NULL || + !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE); + g_return_val_if_fail (standard_error == NULL || + !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE); + + /* Just to ensure segfaults if callers try to use + * these when an error is reported. + */ + if (standard_output) + *standard_output = NULL; + + if (standard_error) + *standard_error = NULL; + + if (!fork_exec_with_pipes (FALSE, + working_directory, + argv, + envp, + !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN), + (flags & G_SPAWN_SEARCH_PATH) != 0, + (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0, + (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0, + (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0, + (flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0, + child_setup, + user_data, + &pid, + NULL, + standard_output ? &outpipe : NULL, + standard_error ? &errpipe : NULL, + error)) + return FALSE; + + /* Read data from child. */ + + failed = FALSE; + + if (outpipe >= 0) + { + outstr = g_string_new (NULL); + } + + if (errpipe >= 0) + { + errstr = g_string_new (NULL); + } + + /* Read data until we get EOF on both pipes. */ + while (!failed && + (outpipe >= 0 || + errpipe >= 0)) + { + ret = 0; + + FD_ZERO (&fds); + if (outpipe >= 0) + FD_SET (outpipe, &fds); + if (errpipe >= 0) + FD_SET (errpipe, &fds); + + ret = select (MAX (outpipe, errpipe) + 1, + &fds, + NULL, NULL, + NULL /* no timeout */); + + if (ret < 0) + { + int errsv = errno; + + if (errno == EINTR) + continue; + + failed = TRUE; + + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_READ, + _("Unexpected error in select() reading data from a child process (%s)"), + g_strerror (errsv)); + + break; + } + + if (outpipe >= 0 && FD_ISSET (outpipe, &fds)) + { + switch (read_data (outstr, outpipe, error)) + { + case READ_FAILED: + failed = TRUE; + break; + case READ_EOF: + close_and_invalidate (&outpipe); + outpipe = -1; + break; + default: + break; + } + + if (failed) + break; + } + + if (errpipe >= 0 && FD_ISSET (errpipe, &fds)) + { + switch (read_data (errstr, errpipe, error)) + { + case READ_FAILED: + failed = TRUE; + break; + case READ_EOF: + close_and_invalidate (&errpipe); + errpipe = -1; + break; + default: + break; + } + + if (failed) + break; + } + } + + /* These should only be open still if we had an error. */ + + if (outpipe >= 0) + close_and_invalidate (&outpipe); + if (errpipe >= 0) + close_and_invalidate (&errpipe); + + /* Wait for child to exit, even if we have + * an error pending. + */ + again: + + ret = waitpid (pid, &status, 0); + + if (ret < 0) + { + if (errno == EINTR) + goto again; + else if (errno == ECHILD) + { + if (exit_status) + { + g_warning ("In call to g_spawn_sync(), exit status of a child process was requested but SIGCHLD action was set to SIG_IGN and ECHILD was received by waitpid(), so exit status can't be returned. This is a bug in the program calling g_spawn_sync(); either don't request the exit status, or don't set the SIGCHLD action."); + } + else + { + /* We don't need the exit status. */ + } + } + else + { + if (!failed) /* avoid error pileups */ + { + int errsv = errno; + + failed = TRUE; + + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_READ, + _("Unexpected error in waitpid() (%s)"), + g_strerror (errsv)); + } + } + } + + if (failed) + { + if (outstr) + g_string_free (outstr, TRUE); + if (errstr) + g_string_free (errstr, TRUE); + + return FALSE; + } + else + { + if (exit_status) + *exit_status = status; + + if (standard_output) + *standard_output = g_string_free (outstr, FALSE); + + if (standard_error) + *standard_error = g_string_free (errstr, FALSE); + + return TRUE; + } +} + +/** + * g_spawn_async_with_pipes: + * @working_directory: (allow-none): child's current working directory, or %NULL to inherit parent's, in the GLib file name encoding + * @argv: (array zero-terminated=1): child's argument vector, in the GLib file name encoding + * @envp: (array zero-terminated=1) (allow-none): child's environment, or %NULL to inherit parent's, in the GLib file name encoding + * @flags: flags from #GSpawnFlags + * @child_setup: (scope async) (allow-none): function to run in the child just before exec() + * @user_data: (closure): user data for @child_setup + * @child_pid: (out) (allow-none): return location for child process ID, or %NULL + * @standard_input: (out) (allow-none): return location for file descriptor to write to child's stdin, or %NULL + * @standard_output: (out) (allow-none): return location for file descriptor to read child's stdout, or %NULL + * @standard_error: (out) (allow-none): return location for file descriptor to read child's stderr, or %NULL + * @error: return location for error + * + * Executes a child program asynchronously (your program will not + * block waiting for the child to exit). The child program is + * specified by the only argument that must be provided, @argv. @argv + * should be a %NULL-terminated array of strings, to be passed as the + * argument vector for the child. The first string in @argv is of + * course the name of the program to execute. By default, the name of + * the program must be a full path; the PATH shell variable + * will only be searched if you pass the %G_SPAWN_SEARCH_PATH flag. + * If the program name is not a full path and %G_SPAWN_SEARCH_PATH flag is not + * used, then the program will be run from the current directory (or + * @working_directory, if specified); this might be unexpected or even + * dangerous in some cases when the current directory is world-writable. + * + * On Windows, note that all the string or string vector arguments to + * this function and the other g_spawn*() functions are in UTF-8, the + * GLib file name encoding. Unicode characters that are not part of + * the system codepage passed in these arguments will be correctly + * available in the spawned program only if it uses wide character API + * to retrieve its command line. For C programs built with Microsoft's + * tools it is enough to make the program have a wmain() instead of + * main(). wmain() has a wide character argument vector as parameter. + * + * At least currently, mingw doesn't support wmain(), so if you use + * mingw to develop the spawned program, it will have to call the + * undocumented function __wgetmainargs() to get the wide character + * argument vector and environment. See gspawn-win32-helper.c in the + * GLib sources or init.c in the mingw runtime sources for a prototype + * for that function. Alternatively, you can retrieve the Win32 system + * level wide character command line passed to the spawned program + * using the GetCommandLineW() function. + * + * On Windows the low-level child process creation API + * CreateProcess() doesn't use argument vectors, + * but a command line. The C runtime library's + * spawn*() family of functions (which + * g_spawn_async_with_pipes() eventually calls) paste the argument + * vector elements together into a command line, and the C runtime startup code + * does a corresponding reconstruction of an argument vector from the + * command line, to be passed to main(). Complications arise when you have + * argument vector elements that contain spaces of double quotes. The + * spawn*() functions don't do any quoting or + * escaping, but on the other hand the startup code does do unquoting + * and unescaping in order to enable receiving arguments with embedded + * spaces or double quotes. To work around this asymmetry, + * g_spawn_async_with_pipes() will do quoting and escaping on argument + * vector elements that need it before calling the C runtime + * spawn() function. + * + * The returned @child_pid on Windows is a handle to the child + * process, not its identifier. Process handles and process + * identifiers are different concepts on Windows. + * + * @envp is a %NULL-terminated array of strings, where each string + * has the form KEY=VALUE. This will become + * the child's environment. If @envp is %NULL, the child inherits its + * parent's environment. + * + * @flags should be the bitwise OR of any flags you want to affect the + * function's behaviour. The %G_SPAWN_DO_NOT_REAP_CHILD means that the + * child will not automatically be reaped; you must use a child watch to + * be notified about the death of the child process. Eventually you must + * call g_spawn_close_pid() on the @child_pid, in order to free + * resources which may be associated with the child process. (On Unix, + * using a child watch is equivalent to calling waitpid() or handling + * the SIGCHLD signal manually. On Windows, calling g_spawn_close_pid() + * is equivalent to calling CloseHandle() on the process handle returned + * in @child_pid). See g_child_watch_add(). + * + * %G_SPAWN_LEAVE_DESCRIPTORS_OPEN means that the parent's open file + * descriptors will be inherited by the child; otherwise all + * descriptors except stdin/stdout/stderr will be closed before + * calling exec() in the child. %G_SPAWN_SEARCH_PATH + * means that argv[0] need not be an absolute path, it + * will be looked for in the user's PATH. + * %G_SPAWN_STDOUT_TO_DEV_NULL means that the child's standard output will + * be discarded, instead of going to the same location as the parent's + * standard output. If you use this flag, @standard_output must be %NULL. + * %G_SPAWN_STDERR_TO_DEV_NULL means that the child's standard error + * will be discarded, instead of going to the same location as the parent's + * standard error. If you use this flag, @standard_error must be %NULL. + * %G_SPAWN_CHILD_INHERITS_STDIN means that the child will inherit the parent's + * standard input (by default, the child's standard input is attached to + * /dev/null). If you use this flag, @standard_input must be %NULL. + * %G_SPAWN_FILE_AND_ARGV_ZERO means that the first element of @argv is + * the file to execute, while the remaining elements are the + * actual argument vector to pass to the file. Normally + * g_spawn_async_with_pipes() uses @argv[0] as the file to execute, and + * passes all of @argv to the child. + * + * @child_setup and @user_data are a function and user data. On POSIX + * platforms, the function is called in the child after GLib has + * performed all the setup it plans to perform (including creating + * pipes, closing file descriptors, etc.) but before calling + * exec(). That is, @child_setup is called just + * before calling exec() in the child. Obviously + * actions taken in this function will only affect the child, not the + * parent. + * + * On Windows, there is no separate fork() and exec() + * functionality. Child processes are created and run with a single + * API call, CreateProcess(). There is no sensible thing @child_setup + * could be used for on Windows so it is ignored and not called. + * + * If non-%NULL, @child_pid will on Unix be filled with the child's + * process ID. You can use the process ID to send signals to the + * child, or to use g_child_watch_add() (or waitpid()) if you specified the + * %G_SPAWN_DO_NOT_REAP_CHILD flag. On Windows, @child_pid will be + * filled with a handle to the child process only if you specified the + * %G_SPAWN_DO_NOT_REAP_CHILD flag. You can then access the child + * process using the Win32 API, for example wait for its termination + * with the WaitFor*() functions, or examine its + * exit code with GetExitCodeProcess(). You should close the handle + * with CloseHandle() or g_spawn_close_pid() when you no longer need it. + * + * If non-%NULL, the @standard_input, @standard_output, @standard_error + * locations will be filled with file descriptors for writing to the child's + * standard input or reading from its standard output or standard error. + * The caller of g_spawn_async_with_pipes() must close these file descriptors + * when they are no longer in use. If these parameters are %NULL, the corresponding + * pipe won't be created. + * + * If @standard_input is NULL, the child's standard input is attached to + * /dev/null unless %G_SPAWN_CHILD_INHERITS_STDIN is set. + * + * If @standard_error is NULL, the child's standard error goes to the same + * location as the parent's standard error unless %G_SPAWN_STDERR_TO_DEV_NULL + * is set. + * + * If @standard_output is NULL, the child's standard output goes to the same + * location as the parent's standard output unless %G_SPAWN_STDOUT_TO_DEV_NULL + * is set. + * + * @error can be %NULL to ignore errors, or non-%NULL to report errors. + * If an error is set, the function returns %FALSE. Errors + * are reported even if they occur in the child (for example if the + * executable in argv[0] is not found). Typically + * the message field of returned errors should be displayed + * to users. Possible errors are those from the #G_SPAWN_ERROR domain. + * + * If an error occurs, @child_pid, @standard_input, @standard_output, + * and @standard_error will not be filled with valid values. + * + * If @child_pid is not %NULL and an error does not occur then the returned + * process reference must be closed using g_spawn_close_pid(). + * + * + * If you are writing a GTK+ application, and the program you + * are spawning is a graphical application, too, then you may + * want to use gdk_spawn_on_screen_with_pipes() instead to ensure that + * the spawned program opens its windows on the right screen. + * + * + * Return value: %TRUE on success, %FALSE if an error was set + **/ +gboolean +g_spawn_async_with_pipes (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error) +{ + g_return_val_if_fail (argv != NULL, FALSE); + g_return_val_if_fail (standard_output == NULL || + !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE); + g_return_val_if_fail (standard_error == NULL || + !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE); + /* can't inherit stdin if we have an input pipe. */ + g_return_val_if_fail (standard_input == NULL || + !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE); + + return fork_exec_with_pipes (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), + working_directory, + argv, + envp, + !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN), + (flags & G_SPAWN_SEARCH_PATH) != 0, + (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0, + (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0, + (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0, + (flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0, + child_setup, + user_data, + child_pid, + standard_input, + standard_output, + standard_error, + error); +} + +/** + * g_spawn_command_line_sync: + * @command_line: a command line + * @standard_output: (out) (array zero-terminated=1) (element-type guint8) (allow-none): return location for child output + * @standard_error: (out) (array zero-terminated=1) (element-type guint8) (allow-none): return location for child errors + * @exit_status: (out) (allow-none): return location for child exit status, as returned by waitpid() + * @error: return location for errors + * + * A simple version of g_spawn_sync() with little-used parameters + * removed, taking a command line instead of an argument vector. See + * g_spawn_sync() for full details. @command_line will be parsed by + * g_shell_parse_argv(). Unlike g_spawn_sync(), the %G_SPAWN_SEARCH_PATH flag + * is enabled. Note that %G_SPAWN_SEARCH_PATH can have security + * implications, so consider using g_spawn_sync() directly if + * appropriate. Possible errors are those from g_spawn_sync() and those + * from g_shell_parse_argv(). + * + * If @exit_status is non-%NULL, the exit status of the child is stored there as + * it would be returned by waitpid(); standard UNIX macros such as WIFEXITED() + * and WEXITSTATUS() must be used to evaluate the exit status. + * + * On Windows, please note the implications of g_shell_parse_argv() + * parsing @command_line. Parsing is done according to Unix shell rules, not + * Windows command interpreter rules. + * Space is a separator, and backslashes are + * special. Thus you cannot simply pass a @command_line containing + * canonical Windows paths, like "c:\\program files\\app\\app.exe", as + * the backslashes will be eaten, and the space will act as a + * separator. You need to enclose such paths with single quotes, like + * "'c:\\program files\\app\\app.exe' 'e:\\folder\\argument.txt'". + * + * Return value: %TRUE on success, %FALSE if an error was set + **/ +gboolean +g_spawn_command_line_sync (const gchar *command_line, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error) +{ + gboolean retval; + gchar **argv = NULL; + + g_return_val_if_fail (command_line != NULL, FALSE); + + if (!g_shell_parse_argv (command_line, + NULL, &argv, + error)) + return FALSE; + + retval = g_spawn_sync (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + standard_output, + standard_error, + exit_status, + error); + g_strfreev (argv); + + return retval; +} + +/** + * g_spawn_command_line_async: + * @command_line: a command line + * @error: return location for errors + * + * A simple version of g_spawn_async() that parses a command line with + * g_shell_parse_argv() and passes it to g_spawn_async(). Runs a + * command line in the background. Unlike g_spawn_async(), the + * %G_SPAWN_SEARCH_PATH flag is enabled, other flags are not. Note + * that %G_SPAWN_SEARCH_PATH can have security implications, so + * consider using g_spawn_async() directly if appropriate. Possible + * errors are those from g_shell_parse_argv() and g_spawn_async(). + * + * The same concerns on Windows apply as for g_spawn_command_line_sync(). + * + * Return value: %TRUE on success, %FALSE if error is set. + **/ +gboolean +g_spawn_command_line_async (const gchar *command_line, + GError **error) +{ + gboolean retval; + gchar **argv = NULL; + + g_return_val_if_fail (command_line != NULL, FALSE); + + if (!g_shell_parse_argv (command_line, + NULL, &argv, + error)) + return FALSE; + + retval = g_spawn_async (NULL, + argv, + NULL, + G_SPAWN_SEARCH_PATH, + NULL, + NULL, + NULL, + error); + g_strfreev (argv); + + return retval; +} + +static gint +exec_err_to_g_error (gint en) +{ + switch (en) + { +#ifdef EACCES + case EACCES: + return G_SPAWN_ERROR_ACCES; + break; +#endif + +#ifdef EPERM + case EPERM: + return G_SPAWN_ERROR_PERM; + break; +#endif + +#ifdef E2BIG + case E2BIG: + return G_SPAWN_ERROR_TOO_BIG; + break; +#endif + +#ifdef ENOEXEC + case ENOEXEC: + return G_SPAWN_ERROR_NOEXEC; + break; +#endif + +#ifdef ENAMETOOLONG + case ENAMETOOLONG: + return G_SPAWN_ERROR_NAMETOOLONG; + break; +#endif + +#ifdef ENOENT + case ENOENT: + return G_SPAWN_ERROR_NOENT; + break; +#endif + +#ifdef ENOMEM + case ENOMEM: + return G_SPAWN_ERROR_NOMEM; + break; +#endif + +#ifdef ENOTDIR + case ENOTDIR: + return G_SPAWN_ERROR_NOTDIR; + break; +#endif + +#ifdef ELOOP + case ELOOP: + return G_SPAWN_ERROR_LOOP; + break; +#endif + +#ifdef ETXTBUSY + case ETXTBUSY: + return G_SPAWN_ERROR_TXTBUSY; + break; +#endif + +#ifdef EIO + case EIO: + return G_SPAWN_ERROR_IO; + break; +#endif + +#ifdef ENFILE + case ENFILE: + return G_SPAWN_ERROR_NFILE; + break; +#endif + +#ifdef EMFILE + case EMFILE: + return G_SPAWN_ERROR_MFILE; + break; +#endif + +#ifdef EINVAL + case EINVAL: + return G_SPAWN_ERROR_INVAL; + break; +#endif + +#ifdef EISDIR + case EISDIR: + return G_SPAWN_ERROR_ISDIR; + break; +#endif + +#ifdef ELIBBAD + case ELIBBAD: + return G_SPAWN_ERROR_LIBBAD; + break; +#endif + + default: + return G_SPAWN_ERROR_FAILED; + break; + } +} + +static gssize +write_all (gint fd, gconstpointer vbuf, gsize to_write) +{ + gchar *buf = (gchar *) vbuf; + + while (to_write > 0) + { + gssize count = write (fd, buf, to_write); + if (count < 0) + { + if (errno != EINTR) + return FALSE; + } + else + { + to_write -= count; + buf += count; + } + } + + return TRUE; +} + +G_GNUC_NORETURN +static void +write_err_and_exit (gint fd, gint msg) +{ + gint en = errno; + + write_all (fd, &msg, sizeof(msg)); + write_all (fd, &en, sizeof(en)); + + _exit (1); +} + +static int +set_cloexec (void *data, gint fd) +{ + if (fd >= GPOINTER_TO_INT (data)) + fcntl (fd, F_SETFD, FD_CLOEXEC); + + return 0; +} + +#ifndef HAVE_FDWALK +static int +fdwalk (int (*cb)(void *data, int fd), void *data) +{ + gint open_max; + gint fd; + gint res = 0; + +#ifdef HAVE_SYS_RESOURCE_H + struct rlimit rl; +#endif + +#ifdef __linux__ + DIR *d; + + if ((d = opendir("/proc/self/fd"))) { + struct dirent *de; + + while ((de = readdir(d))) { + glong l; + gchar *e = NULL; + + if (de->d_name[0] == '.') + continue; + + errno = 0; + l = strtol(de->d_name, &e, 10); + if (errno != 0 || !e || *e) + continue; + + fd = (gint) l; + + if ((glong) fd != l) + continue; + + if (fd == dirfd(d)) + continue; + + if ((res = cb (data, fd)) != 0) + break; + } + + closedir(d); + return res; + } + + /* If /proc is not mounted or not accessible we fall back to the old + * rlimit trick */ + +#endif + +#ifdef HAVE_SYS_RESOURCE_H + + if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY) + open_max = rl.rlim_max; + else +#endif + open_max = sysconf (_SC_OPEN_MAX); + + for (fd = 0; fd < open_max; fd++) + if ((res = cb (data, fd)) != 0) + break; + + return res; +} +#endif + +static gint +sane_dup2 (gint fd1, gint fd2) +{ + gint ret; + + retry: + ret = dup2 (fd1, fd2); + if (ret < 0 && errno == EINTR) + goto retry; + + return ret; +} + +static gint +sane_open (const char *path, gint mode) +{ + gint ret; + + retry: + ret = open (path, mode); + if (ret < 0 && errno == EINTR) + goto retry; + + return ret; +} + +enum +{ + CHILD_CHDIR_FAILED, + CHILD_EXEC_FAILED, + CHILD_DUP2_FAILED, + CHILD_FORK_FAILED +}; + +static void +do_exec (gint child_err_report_fd, + gint stdin_fd, + gint stdout_fd, + gint stderr_fd, + const gchar *working_directory, + gchar **argv, + gchar **envp, + gboolean close_descriptors, + gboolean search_path, + gboolean stdout_to_null, + gboolean stderr_to_null, + gboolean child_inherits_stdin, + gboolean file_and_argv_zero, + GSpawnChildSetupFunc child_setup, + gpointer user_data) +{ + if (working_directory && chdir (working_directory) < 0) + write_err_and_exit (child_err_report_fd, + CHILD_CHDIR_FAILED); + + /* Close all file descriptors but stdin stdout and stderr as + * soon as we exec. Note that this includes + * child_err_report_fd, which keeps the parent from blocking + * forever on the other end of that pipe. + */ + if (close_descriptors) + { + fdwalk (set_cloexec, GINT_TO_POINTER(3)); + } + else + { + /* We need to do child_err_report_fd anyway */ + set_cloexec (GINT_TO_POINTER(0), child_err_report_fd); + } + + /* Redirect pipes as required */ + + if (stdin_fd >= 0) + { + /* dup2 can't actually fail here I don't think */ + + if (sane_dup2 (stdin_fd, 0) < 0) + write_err_and_exit (child_err_report_fd, + CHILD_DUP2_FAILED); + + /* ignore this if it doesn't work */ + close_and_invalidate (&stdin_fd); + } + else if (!child_inherits_stdin) + { + /* Keep process from blocking on a read of stdin */ + gint read_null = open ("/dev/null", O_RDONLY); + sane_dup2 (read_null, 0); + close_and_invalidate (&read_null); + } + + if (stdout_fd >= 0) + { + /* dup2 can't actually fail here I don't think */ + + if (sane_dup2 (stdout_fd, 1) < 0) + write_err_and_exit (child_err_report_fd, + CHILD_DUP2_FAILED); + + /* ignore this if it doesn't work */ + close_and_invalidate (&stdout_fd); + } + else if (stdout_to_null) + { + gint write_null = sane_open ("/dev/null", O_WRONLY); + sane_dup2 (write_null, 1); + close_and_invalidate (&write_null); + } + + if (stderr_fd >= 0) + { + /* dup2 can't actually fail here I don't think */ + + if (sane_dup2 (stderr_fd, 2) < 0) + write_err_and_exit (child_err_report_fd, + CHILD_DUP2_FAILED); + + /* ignore this if it doesn't work */ + close_and_invalidate (&stderr_fd); + } + else if (stderr_to_null) + { + gint write_null = sane_open ("/dev/null", O_WRONLY); + sane_dup2 (write_null, 2); + close_and_invalidate (&write_null); + } + + /* Call user function just before we exec */ + if (child_setup) + { + (* child_setup) (user_data); + } + + g_execute (argv[0], + file_and_argv_zero ? argv + 1 : argv, + envp, search_path); + + /* Exec failed */ + write_err_and_exit (child_err_report_fd, + CHILD_EXEC_FAILED); +} + +static gboolean +read_ints (int fd, + gint* buf, + gint n_ints_in_buf, + gint *n_ints_read, + GError **error) +{ + gsize bytes = 0; + + while (TRUE) + { + gssize chunk; + + if (bytes >= sizeof(gint)*2) + break; /* give up, who knows what happened, should not be + * possible. + */ + + again: + chunk = read (fd, + ((gchar*)buf) + bytes, + sizeof(gint) * n_ints_in_buf - bytes); + if (chunk < 0 && errno == EINTR) + goto again; + + if (chunk < 0) + { + int errsv = errno; + + /* Some weird shit happened, bail out */ + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FAILED, + _("Failed to read from child pipe (%s)"), + g_strerror (errsv)); + + return FALSE; + } + else if (chunk == 0) + break; /* EOF */ + else /* chunk > 0 */ + bytes += chunk; + } + + *n_ints_read = (gint)(bytes / sizeof(gint)); + + return TRUE; +} + +static gboolean +fork_exec_with_pipes (gboolean intermediate_child, + const gchar *working_directory, + gchar **argv, + gchar **envp, + gboolean close_descriptors, + gboolean search_path, + gboolean stdout_to_null, + gboolean stderr_to_null, + gboolean child_inherits_stdin, + gboolean file_and_argv_zero, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error) +{ + GPid pid = -1; + gint stdin_pipe[2] = { -1, -1 }; + gint stdout_pipe[2] = { -1, -1 }; + gint stderr_pipe[2] = { -1, -1 }; + gint child_err_report_pipe[2] = { -1, -1 }; + gint child_pid_report_pipe[2] = { -1, -1 }; + gint status; + + if (!make_pipe (child_err_report_pipe, error)) + return FALSE; + + if (intermediate_child && !make_pipe (child_pid_report_pipe, error)) + goto cleanup_and_fail; + + if (standard_input && !make_pipe (stdin_pipe, error)) + goto cleanup_and_fail; + + if (standard_output && !make_pipe (stdout_pipe, error)) + goto cleanup_and_fail; + + if (standard_error && !make_pipe (stderr_pipe, error)) + goto cleanup_and_fail; + + pid = fork (); + + if (pid < 0) + { + int errsv = errno; + + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FORK, + _("Failed to fork (%s)"), + g_strerror (errsv)); + + goto cleanup_and_fail; + } + else if (pid == 0) + { + /* Immediate child. This may or may not be the child that + * actually execs the new process. + */ + + /* Reset some signal handlers that we may use */ + signal (SIGCHLD, SIG_DFL); + signal (SIGINT, SIG_DFL); + signal (SIGTERM, SIG_DFL); + signal (SIGHUP, SIG_DFL); + + /* Be sure we crash if the parent exits + * and we write to the err_report_pipe + */ + signal (SIGPIPE, SIG_DFL); + + /* Close the parent's end of the pipes; + * not needed in the close_descriptors case, + * though + */ + close_and_invalidate (&child_err_report_pipe[0]); + close_and_invalidate (&child_pid_report_pipe[0]); + close_and_invalidate (&stdin_pipe[1]); + close_and_invalidate (&stdout_pipe[0]); + close_and_invalidate (&stderr_pipe[0]); + + if (intermediate_child) + { + /* We need to fork an intermediate child that launches the + * final child. The purpose of the intermediate child + * is to exit, so we can waitpid() it immediately. + * Then the grandchild will not become a zombie. + */ + GPid grandchild_pid; + + grandchild_pid = fork (); + + if (grandchild_pid < 0) + { + /* report -1 as child PID */ + write_all (child_pid_report_pipe[1], &grandchild_pid, + sizeof(grandchild_pid)); + + write_err_and_exit (child_err_report_pipe[1], + CHILD_FORK_FAILED); + } + else if (grandchild_pid == 0) + { + do_exec (child_err_report_pipe[1], + stdin_pipe[0], + stdout_pipe[1], + stderr_pipe[1], + working_directory, + argv, + envp, + close_descriptors, + search_path, + stdout_to_null, + stderr_to_null, + child_inherits_stdin, + file_and_argv_zero, + child_setup, + user_data); + } + else + { + write_all (child_pid_report_pipe[1], &grandchild_pid, sizeof(grandchild_pid)); + close_and_invalidate (&child_pid_report_pipe[1]); + + _exit (0); + } + } + else + { + /* Just run the child. + */ + + do_exec (child_err_report_pipe[1], + stdin_pipe[0], + stdout_pipe[1], + stderr_pipe[1], + working_directory, + argv, + envp, + close_descriptors, + search_path, + stdout_to_null, + stderr_to_null, + child_inherits_stdin, + file_and_argv_zero, + child_setup, + user_data); + } + } + else + { + /* Parent */ + + gint buf[2]; + gint n_ints = 0; + + /* Close the uncared-about ends of the pipes */ + close_and_invalidate (&child_err_report_pipe[1]); + close_and_invalidate (&child_pid_report_pipe[1]); + close_and_invalidate (&stdin_pipe[0]); + close_and_invalidate (&stdout_pipe[1]); + close_and_invalidate (&stderr_pipe[1]); + + /* If we had an intermediate child, reap it */ + if (intermediate_child) + { + wait_again: + if (waitpid (pid, &status, 0) < 0) + { + if (errno == EINTR) + goto wait_again; + else if (errno == ECHILD) + ; /* do nothing, child already reaped */ + else + g_warning ("waitpid() should not fail in " + "'fork_exec_with_pipes'"); + } + } + + + if (!read_ints (child_err_report_pipe[0], + buf, 2, &n_ints, + error)) + goto cleanup_and_fail; + + if (n_ints >= 2) + { + /* Error from the child. */ + + switch (buf[0]) + { + case CHILD_CHDIR_FAILED: + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_CHDIR, + _("Failed to change to directory '%s' (%s)"), + working_directory, + g_strerror (buf[1])); + + break; + + case CHILD_EXEC_FAILED: + g_set_error (error, + G_SPAWN_ERROR, + exec_err_to_g_error (buf[1]), + _("Failed to execute child process \"%s\" (%s)"), + argv[0], + g_strerror (buf[1])); + + break; + + case CHILD_DUP2_FAILED: + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FAILED, + _("Failed to redirect output or input of child process (%s)"), + g_strerror (buf[1])); + + break; + + case CHILD_FORK_FAILED: + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FORK, + _("Failed to fork child process (%s)"), + g_strerror (buf[1])); + break; + + default: + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FAILED, + _("Unknown error executing child process \"%s\""), + argv[0]); + break; + } + + goto cleanup_and_fail; + } + + /* Get child pid from intermediate child pipe. */ + if (intermediate_child) + { + n_ints = 0; + + if (!read_ints (child_pid_report_pipe[0], + buf, 1, &n_ints, error)) + goto cleanup_and_fail; + + if (n_ints < 1) + { + int errsv = errno; + + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FAILED, + _("Failed to read enough data from child pid pipe (%s)"), + g_strerror (errsv)); + goto cleanup_and_fail; + } + else + { + /* we have the child pid */ + pid = buf[0]; + } + } + + /* Success against all odds! return the information */ + close_and_invalidate (&child_err_report_pipe[0]); + close_and_invalidate (&child_pid_report_pipe[0]); + + if (child_pid) + *child_pid = pid; + + if (standard_input) + *standard_input = stdin_pipe[1]; + if (standard_output) + *standard_output = stdout_pipe[0]; + if (standard_error) + *standard_error = stderr_pipe[0]; + + return TRUE; + } + + cleanup_and_fail: + + /* There was an error from the Child, reap the child to avoid it being + a zombie. + */ + + if (pid > 0) + { + wait_failed: + if (waitpid (pid, NULL, 0) < 0) + { + if (errno == EINTR) + goto wait_failed; + else if (errno == ECHILD) + ; /* do nothing, child already reaped */ + else + g_warning ("waitpid() should not fail in " + "'fork_exec_with_pipes'"); + } + } + + close_and_invalidate (&child_err_report_pipe[0]); + close_and_invalidate (&child_err_report_pipe[1]); + close_and_invalidate (&child_pid_report_pipe[0]); + close_and_invalidate (&child_pid_report_pipe[1]); + close_and_invalidate (&stdin_pipe[0]); + close_and_invalidate (&stdin_pipe[1]); + close_and_invalidate (&stdout_pipe[0]); + close_and_invalidate (&stdout_pipe[1]); + close_and_invalidate (&stderr_pipe[0]); + close_and_invalidate (&stderr_pipe[1]); + + return FALSE; +} + +static gboolean +make_pipe (gint p[2], + GError **error) +{ + if (pipe (p) < 0) + { + gint errsv = errno; + g_set_error (error, + G_SPAWN_ERROR, + G_SPAWN_ERROR_FAILED, + _("Failed to create pipe for communicating with child process (%s)"), + g_strerror (errsv)); + return FALSE; + } + else + return TRUE; +} + +/* Based on execvp from GNU C Library */ + +static void +script_execute (const gchar *file, + gchar **argv, + gchar **envp, + gboolean search_path) +{ + /* Count the arguments. */ + int argc = 0; + while (argv[argc]) + ++argc; + + /* Construct an argument list for the shell. */ + { + gchar **new_argv; + + new_argv = g_new0 (gchar*, argc + 2); /* /bin/sh and NULL */ + + new_argv[0] = (char *) "/bin/sh"; + new_argv[1] = (char *) file; + while (argc > 0) + { + new_argv[argc + 1] = argv[argc]; + --argc; + } + + /* Execute the shell. */ + if (envp) + execve (new_argv[0], new_argv, envp); + else + execv (new_argv[0], new_argv); + + g_free (new_argv); + } +} + +static gchar* +my_strchrnul (const gchar *str, gchar c) +{ + gchar *p = (gchar*) str; + while (*p && (*p != c)) + ++p; + + return p; +} + +static gint +g_execute (const gchar *file, + gchar **argv, + gchar **envp, + gboolean search_path) +{ + if (*file == '\0') + { + /* We check the simple case first. */ + errno = ENOENT; + return -1; + } + + if (!search_path || strchr (file, '/') != NULL) + { + /* Don't search when it contains a slash. */ + if (envp) + execve (file, argv, envp); + else + execv (file, argv); + + if (errno == ENOEXEC) + script_execute (file, argv, envp, FALSE); + } + else + { + gboolean got_eacces = 0; + const gchar *path, *p; + gchar *name, *freeme; + gsize len; + gsize pathlen; + + path = g_getenv ("PATH"); + if (path == NULL) + { + /* There is no `PATH' in the environment. The default + * search path in libc is the current directory followed by + * the path `confstr' returns for `_CS_PATH'. + */ + + /* In GLib we put . last, for security, and don't use the + * unportable confstr(); UNIX98 does not actually specify + * what to search if PATH is unset. POSIX may, dunno. + */ + + path = "/bin:/usr/bin:."; + } + + len = strlen (file) + 1; + pathlen = strlen (path); + freeme = name = g_malloc (pathlen + len + 1); + + /* Copy the file name at the top, including '\0' */ + memcpy (name + pathlen + 1, file, len); + name = name + pathlen; + /* And add the slash before the filename */ + *name = '/'; + + p = path; + do + { + char *startp; + + path = p; + p = my_strchrnul (path, ':'); + + if (p == path) + /* Two adjacent colons, or a colon at the beginning or the end + * of `PATH' means to search the current directory. + */ + startp = name + 1; + else + startp = memcpy (name - (p - path), path, p - path); + + /* Try to execute this name. If it works, execv will not return. */ + if (envp) + execve (startp, argv, envp); + else + execv (startp, argv); + + if (errno == ENOEXEC) + script_execute (startp, argv, envp, search_path); + + switch (errno) + { + case EACCES: + /* Record the we got a `Permission denied' error. If we end + * up finding no executable we can use, we want to diagnose + * that we did find one but were denied access. + */ + got_eacces = TRUE; + + /* FALL THRU */ + + case ENOENT: +#ifdef ESTALE + case ESTALE: +#endif +#ifdef ENOTDIR + case ENOTDIR: +#endif + /* Those errors indicate the file is missing or not executable + * by us, in which case we want to just try the next path + * directory. + */ + break; + + case ENODEV: + case ETIMEDOUT: + /* Some strange filesystems like AFS return even + * stranger error numbers. They cannot reasonably mean anything + * else so ignore those, too. + */ + break; + + default: + /* Some other error means we found an executable file, but + * something went wrong executing it; return the error to our + * caller. + */ + g_free (freeme); + return -1; + } + } + while (*p++ != '\0'); + + /* We tried every element and none of them worked. */ + if (got_eacces) + /* At least one failure was due to permissions, so report that + * error. + */ + errno = EACCES; + + g_free (freeme); + } + + /* Return the error from the last attempt (probably ENOENT). */ + return -1; +} + +/** + * g_spawn_close_pid: + * @pid: The process reference to close + * + * On some platforms, notably Windows, the #GPid type represents a resource + * which must be closed to prevent resource leaking. g_spawn_close_pid() + * is provided for this purpose. It should be used on all platforms, even + * though it doesn't do anything under UNIX. + **/ +void +g_spawn_close_pid (GPid pid) +{ +} diff --git a/glib/glib/gspawn.h b/glib/glib/gspawn.h new file mode 100644 index 0000000..bdac189 --- /dev/null +++ b/glib/glib/gspawn.h @@ -0,0 +1,239 @@ +/* gspawn.h - Process launching + * + * Copyright 2000 Red Hat, Inc. + * + * GLib is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, write + * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_SPAWN_H__ +#define __G_SPAWN_H__ + +#include + +G_BEGIN_DECLS + + +/* I'm not sure I remember our proposed naming convention here. */ +/** + * G_SPAWN_ERROR: + * + * Error domain for spawning processes. Errors in this domain will + * be from the #GSpawnError enumeration. See #GError for information on + * error domains. + */ +#define G_SPAWN_ERROR g_spawn_error_quark () + +/** + * GSpawnError: + * @G_SPAWN_ERROR_FORK: Fork failed due to lack of memory. + * @G_SPAWN_ERROR_READ: Read or select on pipes failed. + * @G_SPAWN_ERROR_CHDIR: Changing to working directory failed. + * @G_SPAWN_ERROR_ACCES: execv() returned EACCES + * @G_SPAWN_ERROR_PERM: execv() returned EPERM + * @G_SPAWN_ERROR_TOO_BIG: execv() returned E2BIG + * @G_SPAWN_ERROR_2BIG: deprecated alias for %G_SPAWN_ERROR_TOO_BIG + * @G_SPAWN_ERROR_NOEXEC: execv() returned ENOEXEC + * @G_SPAWN_ERROR_NAMETOOLONG: execv() returned ENAMETOOLONG + * @G_SPAWN_ERROR_NOENT: execv() returned ENOENT + * @G_SPAWN_ERROR_NOMEM: execv() returned ENOMEM + * @G_SPAWN_ERROR_NOTDIR: execv() returned ENOTDIR + * @G_SPAWN_ERROR_LOOP: execv() returned ELOOP + * @G_SPAWN_ERROR_TXTBUSY: execv() returned ETXTBUSY + * @G_SPAWN_ERROR_IO: execv() returned EIO + * @G_SPAWN_ERROR_NFILE: execv() returned ENFILE + * @G_SPAWN_ERROR_MFILE: execv() returned EMFILE + * @G_SPAWN_ERROR_INVAL: execv() returned EINVAL + * @G_SPAWN_ERROR_ISDIR: execv() returned EISDIR + * @G_SPAWN_ERROR_LIBBAD: execv() returned ELIBBAD + * @G_SPAWN_ERROR_FAILED: Some other fatal failure, + * error->message should explain. + * + * Error codes returned by spawning processes. + */ +typedef enum +{ + G_SPAWN_ERROR_FORK, /* fork failed due to lack of memory */ + G_SPAWN_ERROR_READ, /* read or select on pipes failed */ + G_SPAWN_ERROR_CHDIR, /* changing to working dir failed */ + G_SPAWN_ERROR_ACCES, /* execv() returned EACCES */ + G_SPAWN_ERROR_PERM, /* execv() returned EPERM */ + G_SPAWN_ERROR_TOO_BIG,/* execv() returned E2BIG */ +#ifndef G_DISABLE_DEPRECATED + G_SPAWN_ERROR_2BIG = G_SPAWN_ERROR_TOO_BIG, +#endif + G_SPAWN_ERROR_NOEXEC, /* execv() returned ENOEXEC */ + G_SPAWN_ERROR_NAMETOOLONG, /* "" "" ENAMETOOLONG */ + G_SPAWN_ERROR_NOENT, /* "" "" ENOENT */ + G_SPAWN_ERROR_NOMEM, /* "" "" ENOMEM */ + G_SPAWN_ERROR_NOTDIR, /* "" "" ENOTDIR */ + G_SPAWN_ERROR_LOOP, /* "" "" ELOOP */ + G_SPAWN_ERROR_TXTBUSY, /* "" "" ETXTBUSY */ + G_SPAWN_ERROR_IO, /* "" "" EIO */ + G_SPAWN_ERROR_NFILE, /* "" "" ENFILE */ + G_SPAWN_ERROR_MFILE, /* "" "" EMFLE */ + G_SPAWN_ERROR_INVAL, /* "" "" EINVAL */ + G_SPAWN_ERROR_ISDIR, /* "" "" EISDIR */ + G_SPAWN_ERROR_LIBBAD, /* "" "" ELIBBAD */ + G_SPAWN_ERROR_FAILED /* other fatal failure, error->message + * should explain + */ +} GSpawnError; + +/** + * GSpawnChildSetupFunc: + * @user_data: user data to pass to the function. + * + * Specifies the type of the setup function passed to g_spawn_async(), + * g_spawn_sync() and g_spawn_async_with_pipes(), which can, in very + * limited ways, be used to affect the child's execution. + * + * On POSIX platforms, the function is called in the child after GLib + * has performed all the setup it plans to perform, but before calling + * exec(). Actions taken in this function will only affect the child, + * not the parent. + * + * On Windows, the function is called in the parent. Its usefulness on + * Windows is thus questionable. In many cases executing the child setup + * function in the parent can have ill effects, and you should be very + * careful when porting software to Windows that uses child setup + * functions. + * + * However, even on POSIX, you are extremely limited in what you can + * safely do from a #GSpawnChildSetupFunc, because any mutexes that + * were held by other threads in the parent process at the time of the + * fork() will still be locked in the child process, and they will + * never be unlocked (since the threads that held them don't exist in + * the child). POSIX allows only async-signal-safe functions (see + * signal7) + * to be called in the child between fork() and exec(), which + * drastically limits the usefulness of child setup functions. + * + * In particular, it is not safe to call any function which may + * call malloc(), which includes POSIX functions such as setenv(). + * If you need to set up the child environment differently from + * the parent, you should use g_get_environ(), g_environ_setenv(), + * and g_environ_unsetenv(), and then pass the complete environment + * list to the g_spawn... function. + */ +typedef void (* GSpawnChildSetupFunc) (gpointer user_data); + +/** + * GSpawnFlags: + * @G_SPAWN_LEAVE_DESCRIPTORS_OPEN: the parent's open file descriptors will be + * inherited by the child; otherwise all descriptors except stdin/stdout/stderr + * will be closed before calling exec() in the child. + * @G_SPAWN_DO_NOT_REAP_CHILD: the child will not be automatically reaped; you + * must use g_child_watch_add() yourself (or call waitpid() + * or handle SIGCHLD yourself), or the child will become a zombie. + * @G_SPAWN_SEARCH_PATH: argv[0] need not be an absolute path, + * it will be looked for in the user's PATH. + * @G_SPAWN_STDOUT_TO_DEV_NULL: the child's standard output will be discarded, + * instead of going to the same location as the parent's standard output. + * @G_SPAWN_STDERR_TO_DEV_NULL: the child's standard error will be discarded. + * @G_SPAWN_CHILD_INHERITS_STDIN: the child will inherit the parent's standard + * input (by default, the child's standard input is attached to + * /dev/null). + * @G_SPAWN_FILE_AND_ARGV_ZERO: the first element of argv is + * the file to execute, while the remaining elements are the actual argument + * vector to pass to the file. Normally g_spawn_async_with_pipes() uses + * argv[0] as the file to execute, and passes all of + * argv to the child. + * + * Flags passed to g_spawn_sync(), g_spawn_async() and g_spawn_async_with_pipes(). + */ +typedef enum +{ + G_SPAWN_LEAVE_DESCRIPTORS_OPEN = 1 << 0, + G_SPAWN_DO_NOT_REAP_CHILD = 1 << 1, + /* look for argv[0] in the path i.e. use execvp() */ + G_SPAWN_SEARCH_PATH = 1 << 2, + /* Dump output to /dev/null */ + G_SPAWN_STDOUT_TO_DEV_NULL = 1 << 3, + G_SPAWN_STDERR_TO_DEV_NULL = 1 << 4, + G_SPAWN_CHILD_INHERITS_STDIN = 1 << 5, + G_SPAWN_FILE_AND_ARGV_ZERO = 1 << 6 +} GSpawnFlags; + +GQuark g_spawn_error_quark (void); + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +#define g_spawn_async g_spawn_async_utf8 +#define g_spawn_async_with_pipes g_spawn_async_with_pipes_utf8 +#define g_spawn_sync g_spawn_sync_utf8 +#define g_spawn_command_line_sync g_spawn_command_line_sync_utf8 +#define g_spawn_command_line_async g_spawn_command_line_async_utf8 +#endif +#endif + +gboolean g_spawn_async (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + GError **error); + + +/* Opens pipes for non-NULL standard_output, standard_input, standard_error, + * and returns the parent's end of the pipes. + */ +gboolean g_spawn_async_with_pipes (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + GPid *child_pid, + gint *standard_input, + gint *standard_output, + gint *standard_error, + GError **error); + + +/* If standard_output or standard_error are non-NULL, the full + * standard output or error of the command will be placed there. + */ + +gboolean g_spawn_sync (const gchar *working_directory, + gchar **argv, + gchar **envp, + GSpawnFlags flags, + GSpawnChildSetupFunc child_setup, + gpointer user_data, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error); + +gboolean g_spawn_command_line_sync (const gchar *command_line, + gchar **standard_output, + gchar **standard_error, + gint *exit_status, + GError **error); +gboolean g_spawn_command_line_async (const gchar *command_line, + GError **error); + +void g_spawn_close_pid (GPid pid); + +G_END_DECLS + +#endif /* __G_SPAWN_H__ */ diff --git a/glib/glib/gstdio.c b/glib/glib/gstdio.c new file mode 100644 index 0000000..1908918 --- /dev/null +++ b/glib/glib/gstdio.c @@ -0,0 +1,832 @@ +/* gstdio.c - wrappers for C library functions + * + * Copyright 2004 Tor Lillqvist + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include "glibconfig.h" + +#define G_STDIO_NO_WRAP_ON_UNIX + +#include +#include +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifdef G_OS_WIN32 +#include +#include +#include +#include +#include +#include +#else +#include +#endif + +#include "gstdio.h" + + +#if !defined (G_OS_UNIX) && !defined (G_OS_WIN32) && !defined (G_OS_BEOS) +#error Please port this to your operating system +#endif + +#if defined (_MSC_VER) && !defined(_WIN64) +#undef _wstat +#define _wstat _wstat32 +#endif + +/** + * g_access: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @mode: as in access() + * + * A wrapper for the POSIX access() function. This function is used to + * test a pathname for one or several of read, write or execute + * permissions, or just existence. + * + * On Windows, the file protection mechanism is not at all POSIX-like, + * and the underlying function in the C library only checks the + * FAT-style READONLY attribute, and does not look at the ACL of a + * file at all. This function is this in practise almost useless on + * Windows. Software that needs to handle file permissions on Windows + * more exactly should use the Win32 API. + * + * See your C library manual for more details about access(). + * + * Returns: zero if the pathname refers to an existing file system + * object that has all the tested permissions, or -1 otherwise or on + * error. + * + * Since: 2.8 + */ +int +g_access (const gchar *filename, + int mode) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + +#ifndef X_OK +#define X_OK 1 +#endif + + retval = _waccess (wfilename, mode & ~X_OK); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return access (filename, mode); +#endif +} + +/** + * g_chmod: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @mode: as in chmod() + * + * A wrapper for the POSIX chmod() function. The chmod() function is + * used to set the permissions of a file system object. + * + * On Windows the file protection mechanism is not at all POSIX-like, + * and the underlying chmod() function in the C library just sets or + * clears the FAT-style READONLY attribute. It does not touch any + * ACL. Software that needs to manage file permissions on Windows + * exactly should use the Win32 API. + * + * See your C library manual for more details about chmod(). + * + * Returns: zero if the operation succeeded, -1 on error. + * + * Since: 2.8 + */ +int +g_chmod (const gchar *filename, + int mode) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wchmod (wfilename, mode); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return chmod (filename, mode); +#endif +} +/** + * g_open: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @flags: as in open() + * @mode: as in open() + * + * A wrapper for the POSIX open() function. The open() function is + * used to convert a pathname into a file descriptor. + * + * On POSIX systems file descriptors are implemented by the operating + * system. On Windows, it's the C library that implements open() and + * file descriptors. The actual Win32 API for opening files is quite + * different, see MSDN documentation for CreateFile(). The Win32 API + * uses file handles, which are more randomish integers, not small + * integers like file descriptors. + * + * Because file descriptors are specific to the C library on Windows, + * the file descriptor returned by this function makes sense only to + * functions in the same C library. Thus if the GLib-using code uses a + * different C library than GLib does, the file descriptor returned by + * this function cannot be passed to C library functions like write() + * or read(). + * + * See your C library manual for more details about open(). + * + * Returns: a new file descriptor, or -1 if an error occurred. The + * return value can be used exactly like the return value from open(). + * + * Since: 2.6 + */ +int +g_open (const gchar *filename, + int flags, + int mode) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wopen (wfilename, flags, mode); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return open (filename, flags, mode); +#endif +} + +/** + * g_creat: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @mode: as in creat() + * + * A wrapper for the POSIX creat() function. The creat() function is + * used to convert a pathname into a file descriptor, creating a file + * if necessary. + + * On POSIX systems file descriptors are implemented by the operating + * system. On Windows, it's the C library that implements creat() and + * file descriptors. The actual Windows API for opening files is + * different, see MSDN documentation for CreateFile(). The Win32 API + * uses file handles, which are more randomish integers, not small + * integers like file descriptors. + * + * Because file descriptors are specific to the C library on Windows, + * the file descriptor returned by this function makes sense only to + * functions in the same C library. Thus if the GLib-using code uses a + * different C library than GLib does, the file descriptor returned by + * this function cannot be passed to C library functions like write() + * or read(). + * + * See your C library manual for more details about creat(). + * + * Returns: a new file descriptor, or -1 if an error occurred. The + * return value can be used exactly like the return value from creat(). + * + * Since: 2.8 + */ +int +g_creat (const gchar *filename, + int mode) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wcreat (wfilename, mode); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return creat (filename, mode); +#endif +} + +/** + * g_rename: + * @oldfilename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @newfilename: a pathname in the GLib file name encoding + * + * A wrapper for the POSIX rename() function. The rename() function + * renames a file, moving it between directories if required. + * + * See your C library manual for more details about how rename() works + * on your system. It is not possible in general on Windows to rename + * a file that is open to some process. + * + * Returns: 0 if the renaming succeeded, -1 if an error occurred + * + * Since: 2.6 + */ +int +g_rename (const gchar *oldfilename, + const gchar *newfilename) +{ +#ifdef G_OS_WIN32 + wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL); + wchar_t *wnewfilename; + int retval; + int save_errno = 0; + + if (woldfilename == NULL) + { + errno = EINVAL; + return -1; + } + + wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL); + + if (wnewfilename == NULL) + { + g_free (woldfilename); + errno = EINVAL; + return -1; + } + + if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING)) + retval = 0; + else + { + retval = -1; + switch (GetLastError ()) + { +#define CASE(a,b) case ERROR_##a: save_errno = b; break + CASE (FILE_NOT_FOUND, ENOENT); + CASE (PATH_NOT_FOUND, ENOENT); + CASE (ACCESS_DENIED, EACCES); + CASE (NOT_SAME_DEVICE, EXDEV); + CASE (LOCK_VIOLATION, EACCES); + CASE (SHARING_VIOLATION, EACCES); + CASE (FILE_EXISTS, EEXIST); + CASE (ALREADY_EXISTS, EEXIST); +#undef CASE + default: save_errno = EIO; + } + } + + g_free (woldfilename); + g_free (wnewfilename); + + errno = save_errno; + return retval; +#else + return rename (oldfilename, newfilename); +#endif +} + +/** + * g_mkdir: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @mode: permissions to use for the newly created directory + * + * A wrapper for the POSIX mkdir() function. The mkdir() function + * attempts to create a directory with the given name and permissions. + * The mode argument is ignored on Windows. + * + * See your C library manual for more details about mkdir(). + * + * Returns: 0 if the directory was successfully created, -1 if an error + * occurred + * + * Since: 2.6 + */ +int +g_mkdir (const gchar *filename, + int mode) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wmkdir (wfilename); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return mkdir (filename, mode); +#endif +} + +/** + * g_chdir: + * @path: a pathname in the GLib file name encoding (UTF-8 on Windows) + * + * A wrapper for the POSIX chdir() function. The function changes the + * current directory of the process to @path. + * + * See your C library manual for more details about chdir(). + * + * Returns: 0 on success, -1 if an error occurred. + * + * Since: 2.8 + */ +int +g_chdir (const gchar *path) +{ +#ifdef G_OS_WIN32 + wchar_t *wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wpath == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wchdir (wpath); + save_errno = errno; + + g_free (wpath); + + errno = save_errno; + return retval; +#else + return chdir (path); +#endif +} + +/** + * GStatBuf: + * + * A type corresponding to the appropriate struct type for the stat + * system call, depending on the platform and/or compiler being used. + * + * See g_stat() for more information. + **/ +/** + * g_stat: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @buf: a pointer to a stat struct, which + * will be filled with the file information + * + * A wrapper for the POSIX stat() function. The stat() function + * returns information about a file. On Windows the stat() function in + * the C library checks only the FAT-style READONLY attribute and does + * not look at the ACL at all. Thus on Windows the protection bits in + * the st_mode field are a fabrication of little use. + * + * On Windows the Microsoft C libraries have several variants of the + * stat struct and stat() function with names + * like "_stat", "_stat32", "_stat32i64" and "_stat64i32". The one + * used here is for 32-bit code the one with 32-bit size and time + * fields, specifically called "_stat32". + * + * In Microsoft's compiler, by default "struct stat" means one with + * 64-bit time fields while in MinGW "struct stat" is the legacy one + * with 32-bit fields. To hopefully clear up this messs, the gstdio.h + * header defines a type GStatBuf which is the appropriate struct type + * depending on the platform and/or compiler being used. On POSIX it + * is just "struct stat", but note that even on POSIX platforms, + * "stat" might be a macro. + * + * See your C library manual for more details about stat(). + * + * Returns: 0 if the information was successfully retrieved, -1 if an error + * occurred + * + * Since: 2.6 + */ +int +g_stat (const gchar *filename, + GStatBuf *buf) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + int len; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + len = wcslen (wfilename); + while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1])) + len--; + if (len > 0 && + (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename)) + wfilename[len] = '\0'; + + retval = _wstat (wfilename, buf); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return stat (filename, buf); +#endif +} + +/** + * g_lstat: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @buf: a pointer to a stat struct, which + * will be filled with the file information + * + * A wrapper for the POSIX lstat() function. The lstat() function is + * like stat() except that in the case of symbolic links, it returns + * information about the symbolic link itself and not the file that it + * refers to. If the system does not support symbolic links g_lstat() + * is identical to g_stat(). + * + * See your C library manual for more details about lstat(). + * + * Returns: 0 if the information was successfully retrieved, -1 if an error + * occurred + * + * Since: 2.6 + */ +int +g_lstat (const gchar *filename, + GStatBuf *buf) +{ +#ifdef HAVE_LSTAT + /* This can't be Win32, so don't do the widechar dance. */ + return lstat (filename, buf); +#else + return g_stat (filename, buf); +#endif +} + +/** + * g_unlink: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * + * A wrapper for the POSIX unlink() function. The unlink() function + * deletes a name from the filesystem. If this was the last link to the + * file and no processes have it opened, the diskspace occupied by the + * file is freed. + * + * See your C library manual for more details about unlink(). Note + * that on Windows, it is in general not possible to delete files that + * are open to some process, or mapped into memory. + * + * Returns: 0 if the name was successfully deleted, -1 if an error + * occurred + * + * Since: 2.6 + */ +int +g_unlink (const gchar *filename) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wunlink (wfilename); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return unlink (filename); +#endif +} + +/** + * g_remove: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * + * A wrapper for the POSIX remove() function. The remove() function + * deletes a name from the filesystem. + * + * See your C library manual for more details about how remove() works + * on your system. On Unix, remove() removes also directories, as it + * calls unlink() for files and rmdir() for directories. On Windows, + * although remove() in the C library only works for files, this + * function tries first remove() and then if that fails rmdir(), and + * thus works for both files and directories. Note however, that on + * Windows, it is in general not possible to remove a file that is + * open to some process, or mapped into memory. + * + * If this function fails on Windows you can't infer too much from the + * errno value. rmdir() is tried regardless of what caused remove() to + * fail. Any errno value set by remove() will be overwritten by that + * set by rmdir(). + * + * Returns: 0 if the file was successfully removed, -1 if an error + * occurred + * + * Since: 2.6 + */ +int +g_remove (const gchar *filename) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wremove (wfilename); + if (retval == -1) + retval = _wrmdir (wfilename); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return remove (filename); +#endif +} + +/** + * g_rmdir: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * + * A wrapper for the POSIX rmdir() function. The rmdir() function + * deletes a directory from the filesystem. + * + * See your C library manual for more details about how rmdir() works + * on your system. + * + * Returns: 0 if the directory was successfully removed, -1 if an error + * occurred + * + * Since: 2.6 + */ +int +g_rmdir (const gchar *filename) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wrmdir (wfilename); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return rmdir (filename); +#endif +} + +/** + * g_fopen: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @mode: a string describing the mode in which the file should be + * opened + * + * A wrapper for the stdio fopen() function. The fopen() function + * opens a file and associates a new stream with it. + * + * Because file descriptors are specific to the C library on Windows, + * and a file descriptor is partof the FILE struct, the + * FILE pointer returned by this function makes sense + * only to functions in the same C library. Thus if the GLib-using + * code uses a different C library than GLib does, the + * FILE pointer returned by this function cannot be + * passed to C library functions like fprintf() or fread(). + * + * See your C library manual for more details about fopen(). + * + * Returns: A FILE pointer if the file was successfully + * opened, or %NULL if an error occurred + * + * Since: 2.6 + */ +FILE * +g_fopen (const gchar *filename, + const gchar *mode) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + wchar_t *wmode; + FILE *retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return NULL; + } + + wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); + + if (wmode == NULL) + { + g_free (wfilename); + errno = EINVAL; + return NULL; + } + + retval = _wfopen (wfilename, wmode); + save_errno = errno; + + g_free (wfilename); + g_free (wmode); + + errno = save_errno; + return retval; +#else + return fopen (filename, mode); +#endif +} + +/** + * g_freopen: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @mode: a string describing the mode in which the file should be + * opened + * @stream: an existing stream which will be reused, or %NULL + * + * A wrapper for the POSIX freopen() function. The freopen() function + * opens a file and associates it with an existing stream. + * + * See your C library manual for more details about freopen(). + * + * Returns: A FILE pointer if the file was successfully + * opened, or %NULL if an error occurred. + * + * Since: 2.6 + */ +FILE * +g_freopen (const gchar *filename, + const gchar *mode, + FILE *stream) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + wchar_t *wmode; + FILE *retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return NULL; + } + + wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL); + + if (wmode == NULL) + { + g_free (wfilename); + errno = EINVAL; + return NULL; + } + + retval = _wfreopen (wfilename, wmode, stream); + save_errno = errno; + + g_free (wfilename); + g_free (wmode); + + errno = save_errno; + return retval; +#else + return freopen (filename, mode, stream); +#endif +} + +/** + * g_utime: + * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows) + * @utb: a pointer to a struct utimbuf. + * + * A wrapper for the POSIX utime() function. The utime() function + * sets the access and modification timestamps of a file. + * + * See your C library manual for more details about how utime() works + * on your system. + * + * Returns: 0 if the operation was successful, -1 if an error + * occurred + * + * Since: 2.18 + */ +int +g_utime (const gchar *filename, + struct utimbuf *utb) +{ +#ifdef G_OS_WIN32 + wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL); + int retval; + int save_errno; + + if (wfilename == NULL) + { + errno = EINVAL; + return -1; + } + + retval = _wutime (wfilename, (struct _utimbuf*) utb); + save_errno = errno; + + g_free (wfilename); + + errno = save_errno; + return retval; +#else + return utime (filename, utb); +#endif +} diff --git a/glib/glib/gstdio.h b/glib/glib/gstdio.h new file mode 100644 index 0000000..08aea7d --- /dev/null +++ b/glib/glib/gstdio.h @@ -0,0 +1,149 @@ +/* gstdio.h - GFilename wrappers for C library functions + * + * Copyright 2004 Tor Lillqvist + * + * GLib is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * GLib 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with GLib; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_STDIO_H__ +#define __G_STDIO_H__ + +#include + +#include + +G_BEGIN_DECLS + +#if defined (_MSC_VER) && !defined(_WIN64) + +/* Make it clear that we mean the struct with 32-bit st_size and + * 32-bit st_*time fields as that is how the 32-bit GLib DLL normally + * has been compiled. If you get a compiler warning when calling + * g_stat(), do take it seriously and make sure that the type of + * struct stat the code in GLib fills in matches the struct the type + * of struct stat you pass to g_stat(). To avoid hassle, to get file + * attributes just use the GIO API instead which doesn't use struct + * stat. + * + * Sure, it would be nicer to use a struct with 64-bit st_size and + * 64-bit st_*time fields, but changing that now would break ABI. And + * in MinGW, a plain "struct stat" is the one with 32-bit st_size and + * st_*time fields. + */ + +typedef struct _stat32 GStatBuf; + +#else + +typedef struct stat GStatBuf; + +#endif + +#if defined(G_OS_UNIX) && !defined(G_STDIO_NO_WRAP_ON_UNIX) + +/* Just pass on to the system functions, so there's no potential for data + * format mismatches, especially with large file interfaces. + * A few functions can't be handled in this way, since they are not defined + * in a portable system header that we could include here. + */ + +#ifndef __GTK_DOC_IGNORE__ +#define g_chmod chmod +#define g_open open +#define g_creat creat +#define g_rename rename +#define g_mkdir mkdir +#define g_stat stat +#define g_lstat lstat +#define g_remove remove +#define g_fopen fopen +#define g_freopen freopen +#define g_utime utime +#endif + +int g_access (const gchar *filename, + int mode); + +int g_chdir (const gchar *path); + +int g_unlink (const gchar *filename); + +int g_rmdir (const gchar *filename); + +#else /* ! G_OS_UNIX */ + +/* Wrappers for C library functions that take pathname arguments. On + * Unix, the pathname is a file name as it literally is in the file + * system. On well-maintained systems with consistent users who know + * what they are doing and no exchange of files with others this would + * be a well-defined encoding, preferably UTF-8. On Windows, the + * pathname is always in UTF-8, even if that is not the on-disk + * encoding, and not the encoding accepted by the C library or Win32 + * API. + */ + +int g_access (const gchar *filename, + int mode); + +int g_chmod (const gchar *filename, + int mode); + +int g_open (const gchar *filename, + int flags, + int mode); + +int g_creat (const gchar *filename, + int mode); + +int g_rename (const gchar *oldfilename, + const gchar *newfilename); + +int g_mkdir (const gchar *filename, + int mode); + +int g_chdir (const gchar *path); + +int g_stat (const gchar *filename, + GStatBuf *buf); + +int g_lstat (const gchar *filename, + GStatBuf *buf); + +int g_unlink (const gchar *filename); + +int g_remove (const gchar *filename); + +int g_rmdir (const gchar *filename); + +FILE *g_fopen (const gchar *filename, + const gchar *mode); + +FILE *g_freopen (const gchar *filename, + const gchar *mode, + FILE *stream); + +struct utimbuf; /* Don't need the real definition of struct utimbuf when just + * including this header. + */ + +int g_utime (const gchar *filename, + struct utimbuf *utb); + +#endif /* G_OS_UNIX */ + +G_END_DECLS + +#endif /* __G_STDIO_H__ */ diff --git a/glib/glib/gstrfuncs.c b/glib/glib/gstrfuncs.c new file mode 100644 index 0000000..19365b2 --- /dev/null +++ b/glib/glib/gstrfuncs.c @@ -0,0 +1,2805 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include +#include +#include +#include +#include +#include +#include +#include /* For tolower() */ + +#ifdef HAVE_XLOCALE_H +/* Needed on BSD/OS X for e.g. strtod_l */ +#include +#endif + +#ifdef G_OS_WIN32 +#include +#endif + +/* do not include here, it may interfere with g_strsignal() */ + +#include "gstrfuncs.h" + +#include "gprintf.h" +#include "gprintfint.h" +#include "glibintl.h" + + +/** + * SECTION:string_utils + * @title: String Utility Functions + * @short_description: various string-related functions + * + * This section describes a number of utility functions for creating, + * duplicating, and manipulating strings. + * + * Note that the functions g_printf(), g_fprintf(), g_sprintf(), + * g_snprintf(), g_vprintf(), g_vfprintf(), g_vsprintf() and g_vsnprintf() + * are declared in the header gprintf.h which is + * not included in glib.h + * (otherwise using glib.h would drag in + * stdio.h), so you'll have to explicitly include + * <glib/gprintf.h> in order to use the GLib + * printf() functions. + * + * While you may use the printf() functions + * to format UTF-8 strings, notice that the precision of a + * %Ns parameter is interpreted as the + * number of bytes, not characters + * to print. On top of that, the GNU libc implementation of the printf() + * functions has the "feature" that it checks that the string given for + * the %Ns parameter consists of a whole number + * of characters in the current encoding. So, unless you are sure you are + * always going to be in an UTF-8 locale or your know your text is restricted + * to ASCII, avoid using %Ns. If your intention is + * to format strings for a certain number of columns, then + * %Ns is not a correct solution anyway, since it + * fails to take wide characters (see g_unichar_iswide()) into account. + * + */ + +/** + * g_ascii_isalnum: + * @c: any character + * + * Determines whether a character is alphanumeric. + * + * Unlike the standard C library isalnum() function, this only + * recognizes standard ASCII letters and ignores the locale, + * returning %FALSE for all non-ASCII characters. Also, unlike + * the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need to + * cast to #guchar before passing a possibly non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII alphanumeric character + */ + +/** + * g_ascii_isalpha: + * @c: any character + * + * Determines whether a character is alphabetic (i.e. a letter). + * + * Unlike the standard C library isalpha() function, this only + * recognizes standard ASCII letters and ignores the locale, + * returning %FALSE for all non-ASCII characters. Also, unlike + * the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need to + * cast to #guchar before passing a possibly non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII alphabetic character + */ + +/** + * g_ascii_iscntrl: + * @c: any character + * + * Determines whether a character is a control character. + * + * Unlike the standard C library iscntrl() function, this only + * recognizes standard ASCII control characters and ignores the + * locale, returning %FALSE for all non-ASCII characters. Also, + * unlike the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need to + * cast to #guchar before passing a possibly non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII control character. + */ + +/** + * g_ascii_isdigit: + * @c: any character + * + * Determines whether a character is digit (0-9). + * + * Unlike the standard C library isdigit() function, this takes + * a char, not an int, so don't call it + * on EOF, but no need to cast to #guchar before passing a possibly + * non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII digit. + */ + +/** + * g_ascii_isgraph: + * @c: any character + * + * Determines whether a character is a printing character and not a space. + * + * Unlike the standard C library isgraph() function, this only + * recognizes standard ASCII characters and ignores the locale, + * returning %FALSE for all non-ASCII characters. Also, unlike + * the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need + * to cast to #guchar before passing a possibly non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII printing character other than space. + */ + +/** + * g_ascii_islower: + * @c: any character + * + * Determines whether a character is an ASCII lower case letter. + * + * Unlike the standard C library islower() function, this only + * recognizes standard ASCII letters and ignores the locale, + * returning %FALSE for all non-ASCII characters. Also, unlike + * the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need + * to worry about casting to #guchar before passing a possibly + * non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII lower case letter + */ + +/** + * g_ascii_isprint: + * @c: any character + * + * Determines whether a character is a printing character. + * + * Unlike the standard C library isprint() function, this only + * recognizes standard ASCII characters and ignores the locale, + * returning %FALSE for all non-ASCII characters. Also, unlike + * the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need + * to cast to #guchar before passing a possibly non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII printing character. + */ + +/** + * g_ascii_ispunct: + * @c: any character + * + * Determines whether a character is a punctuation character. + * + * Unlike the standard C library ispunct() function, this only + * recognizes standard ASCII letters and ignores the locale, + * returning %FALSE for all non-ASCII characters. Also, unlike + * the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need to + * cast to #guchar before passing a possibly non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII punctuation character. + */ + +/** + * g_ascii_isspace: + * @c: any character + * + * Determines whether a character is a white-space character. + * + * Unlike the standard C library isspace() function, this only + * recognizes standard ASCII white-space and ignores the locale, + * returning %FALSE for all non-ASCII characters. Also, unlike + * the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need to + * cast to #guchar before passing a possibly non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII white-space character + */ + +/** + * g_ascii_isupper: + * @c: any character + * + * Determines whether a character is an ASCII upper case letter. + * + * Unlike the standard C library isupper() function, this only + * recognizes standard ASCII letters and ignores the locale, + * returning %FALSE for all non-ASCII characters. Also, unlike + * the standard library function, this takes a char, + * not an int, so don't call it on EOF, but no need to + * worry about casting to #guchar before passing a possibly non-ASCII + * character in. + * + * Returns: %TRUE if @c is an ASCII upper case letter + */ + +/** + * g_ascii_isxdigit: + * @c: any character + * + * Determines whether a character is a hexadecimal-digit character. + * + * Unlike the standard C library isxdigit() function, this takes + * a char, not an int, so don't call it + * on EOF, but no need to cast to #guchar before passing a + * possibly non-ASCII character in. + * + * Returns: %TRUE if @c is an ASCII hexadecimal-digit character. + */ + +/** + * G_ASCII_DTOSTR_BUF_SIZE: + * + * A good size for a buffer to be passed into g_ascii_dtostr(). + * It is guaranteed to be enough for all output of that function + * on systems with 64bit IEEE-compatible doubles. + * + * The typical usage would be something like: + * |[ + * char buf[G_ASCII_DTOSTR_BUF_SIZE]; + * + * fprintf (out, "value=%s\n", g_ascii_dtostr (buf, sizeof (buf), value)); + * ]| + */ + +/** + * g_strstrip: + * @string: a string to remove the leading and trailing whitespace from + * + * Removes leading and trailing whitespace from a string. + * See g_strchomp() and g_strchug(). + * + * Returns: @string + */ + +/** + * G_STR_DELIMITERS: + * + * The standard delimiters, used in g_strdelimit(). + */ + +static const guint16 ascii_table_data[256] = { + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, + 0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, + 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, + 0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, + 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, + 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, + 0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, + 0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253, + 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, + 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, + 0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, + 0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073, + 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, + 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, + 0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004 + /* the upper 128 are all zeroes */ +}; + +const guint16 * const g_ascii_table = ascii_table_data; + +#ifdef HAVE_NEWLOCALE +static locale_t +get_C_locale (void) +{ + static gsize initialized = FALSE; + static locale_t C_locale = NULL; + + if (g_once_init_enter (&initialized)) + { + C_locale = newlocale (LC_ALL_MASK, "C", NULL); + g_once_init_leave (&initialized, TRUE); + } + + return C_locale; +} +#endif + +/** + * g_strdup: + * @str: the string to duplicate + * + * Duplicates a string. If @str is %NULL it returns %NULL. + * The returned string should be freed with g_free() + * when no longer needed. + * + * Returns: a newly-allocated copy of @str + */ +gchar* +g_strdup (const gchar *str) +{ + gchar *new_str; + gsize length; + + if (str) + { + length = strlen (str) + 1; + new_str = g_new (char, length); + memcpy (new_str, str, length); + } + else + new_str = NULL; + + return new_str; +} + +/** + * g_memdup: + * @mem: the memory to copy. + * @byte_size: the number of bytes to copy. + * + * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it + * from @mem. If @mem is %NULL it returns %NULL. + * + * Returns: a pointer to the newly-allocated copy of the memory, or %NULL if @mem + * is %NULL. + */ +gpointer +g_memdup (gconstpointer mem, + guint byte_size) +{ + gpointer new_mem; + + if (mem) + { + new_mem = g_malloc (byte_size); + memcpy (new_mem, mem, byte_size); + } + else + new_mem = NULL; + + return new_mem; +} + +/** + * g_strndup: + * @str: the string to duplicate + * @n: the maximum number of bytes to copy from @str + * + * Duplicates the first @n bytes of a string, returning a newly-allocated + * buffer @n + 1 bytes long which will always be nul-terminated. + * If @str is less than @n bytes long the buffer is padded with nuls. + * If @str is %NULL it returns %NULL. + * The returned value should be freed when no longer needed. + * + * + * To copy a number of characters from a UTF-8 encoded string, use + * g_utf8_strncpy() instead. + * + * + * Returns: a newly-allocated buffer containing the first @n bytes + * of @str, nul-terminated + */ +gchar* +g_strndup (const gchar *str, + gsize n) +{ + gchar *new_str; + + if (str) + { + new_str = g_new (gchar, n + 1); + strncpy (new_str, str, n); + new_str[n] = '\0'; + } + else + new_str = NULL; + + return new_str; +} + +/** + * g_strnfill: + * @length: the length of the new string + * @fill_char: the byte to fill the string with + * + * Creates a new string @length bytes long filled with @fill_char. + * The returned string should be freed when no longer needed. + * + * Returns: a newly-allocated string filled the @fill_char + */ +gchar* +g_strnfill (gsize length, + gchar fill_char) +{ + gchar *str; + + str = g_new (gchar, length + 1); + memset (str, (guchar)fill_char, length); + str[length] = '\0'; + + return str; +} + +/** + * g_stpcpy: + * @dest: destination buffer. + * @src: source string. + * + * Copies a nul-terminated string into the dest buffer, include the + * trailing nul, and return a pointer to the trailing nul byte. + * This is useful for concatenating multiple strings together + * without having to repeatedly scan for the end. + * + * Return value: a pointer to trailing nul byte. + **/ +gchar * +g_stpcpy (gchar *dest, + const gchar *src) +{ +#ifdef HAVE_STPCPY + g_return_val_if_fail (dest != NULL, NULL); + g_return_val_if_fail (src != NULL, NULL); + return stpcpy (dest, src); +#else + register gchar *d = dest; + register const gchar *s = src; + + g_return_val_if_fail (dest != NULL, NULL); + g_return_val_if_fail (src != NULL, NULL); + do + *d++ = *s; + while (*s++ != '\0'); + + return d - 1; +#endif +} + +/** + * g_strdup_vprintf: + * @format: a standard printf() format string, but notice + * string precision pitfalls + * @args: the list of parameters to insert into the format string + * + * Similar to the standard C vsprintf() function but safer, since it + * calculates the maximum space required and allocates memory to hold + * the result. The returned string should be freed with g_free() when + * no longer needed. + * + * See also g_vasprintf(), which offers the same functionality, but + * additionally returns the length of the allocated string. + * + * Returns: a newly-allocated string holding the result + */ +gchar* +g_strdup_vprintf (const gchar *format, + va_list args) +{ + gchar *string = NULL; + + g_vasprintf (&string, format, args); + + return string; +} + +/** + * g_strdup_printf: + * @format: a standard printf() format string, but notice + * string precision pitfalls + * @...: the parameters to insert into the format string + * + * Similar to the standard C sprintf() function but safer, since it + * calculates the maximum space required and allocates memory to hold + * the result. The returned string should be freed with g_free() when no + * longer needed. + * + * Returns: a newly-allocated string holding the result + */ +gchar* +g_strdup_printf (const gchar *format, + ...) +{ + gchar *buffer; + va_list args; + + va_start (args, format); + buffer = g_strdup_vprintf (format, args); + va_end (args); + + return buffer; +} + +/** + * g_strconcat: + * @string1: the first string to add, which must not be %NULL + * @...: a %NULL-terminated list of strings to append to the string + * + * Concatenates all of the given strings into one long string. + * The returned string should be freed with g_free() when no longer needed. + * + * Note that this function is usually not the right function to use to + * assemble a translated message from pieces, since proper translation + * often requires the pieces to be reordered. + * + * The variable argument list must end + * with %NULL. If you forget the %NULL, g_strconcat() will start appending + * random memory junk to your string. + * + * Returns: a newly-allocated string containing all the string arguments + */ +gchar* +g_strconcat (const gchar *string1, ...) +{ + gsize l; + va_list args; + gchar *s; + gchar *concat; + gchar *ptr; + + if (!string1) + return NULL; + + l = 1 + strlen (string1); + va_start (args, string1); + s = va_arg (args, gchar*); + while (s) + { + l += strlen (s); + s = va_arg (args, gchar*); + } + va_end (args); + + concat = g_new (gchar, l); + ptr = concat; + + ptr = g_stpcpy (ptr, string1); + va_start (args, string1); + s = va_arg (args, gchar*); + while (s) + { + ptr = g_stpcpy (ptr, s); + s = va_arg (args, gchar*); + } + va_end (args); + + return concat; +} + +/** + * g_strtod: + * @nptr: the string to convert to a numeric value. + * @endptr: if non-%NULL, it returns the character after + * the last character used in the conversion. + * + * Converts a string to a #gdouble value. + * It calls the standard strtod() function to handle the conversion, but + * if the string is not completely converted it attempts the conversion + * again with g_ascii_strtod(), and returns the best match. + * + * This function should seldom be used. The normal situation when reading + * numbers not for human consumption is to use g_ascii_strtod(). Only when + * you know that you must expect both locale formatted and C formatted numbers + * should you use this. Make sure that you don't pass strings such as comma + * separated lists of values, since the commas may be interpreted as a decimal + * point in some locales, causing unexpected results. + * + * Return value: the #gdouble value. + **/ +gdouble +g_strtod (const gchar *nptr, + gchar **endptr) +{ + gchar *fail_pos_1; + gchar *fail_pos_2; + gdouble val_1; + gdouble val_2 = 0; + + g_return_val_if_fail (nptr != NULL, 0); + + fail_pos_1 = NULL; + fail_pos_2 = NULL; + + val_1 = strtod (nptr, &fail_pos_1); + + if (fail_pos_1 && fail_pos_1[0] != 0) + val_2 = g_ascii_strtod (nptr, &fail_pos_2); + + if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2) + { + if (endptr) + *endptr = fail_pos_1; + return val_1; + } + else + { + if (endptr) + *endptr = fail_pos_2; + return val_2; + } +} + +/** + * g_ascii_strtod: + * @nptr: the string to convert to a numeric value. + * @endptr: if non-%NULL, it returns the character after + * the last character used in the conversion. + * + * Converts a string to a #gdouble value. + * + * This function behaves like the standard strtod() function + * does in the C locale. It does this without actually changing + * the current locale, since that would not be thread-safe. + * A limitation of the implementation is that this function + * will still accept localized versions of infinities and NANs. + * + * This function is typically used when reading configuration + * files or other non-user input that should be locale independent. + * To handle input from the user you should normally use the + * locale-sensitive system strtod() function. + * + * To convert from a #gdouble to a string in a locale-insensitive + * way, use g_ascii_dtostr(). + * + * If the correct value would cause overflow, plus or minus HUGE_VAL + * is returned (according to the sign of the value), and ERANGE is + * stored in errno. If the correct value would cause underflow, + * zero is returned and ERANGE is stored in errno. + * + * This function resets errno before calling strtod() so that + * you can reliably detect overflow and underflow. + * + * Return value: the #gdouble value. + */ +gdouble +g_ascii_strtod (const gchar *nptr, + gchar **endptr) +{ +#ifdef HAVE_STRTOD_L + + g_return_val_if_fail (nptr != NULL, 0); + + errno = 0; + + return strtod_l (nptr, endptr, get_C_locale ()); + +#else + + gchar *fail_pos; + gdouble val; + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + const char *p, *decimal_point_pos; + const char *end = NULL; /* Silence gcc */ + int strtod_errno; + + g_return_val_if_fail (nptr != NULL, 0); + + fail_pos = NULL; + + locale_data = localeconv (); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen (decimal_point); + + g_assert (decimal_point_len != 0); + + decimal_point_pos = NULL; + end = NULL; + + if (decimal_point[0] != '.' || + decimal_point[1] != 0) + { + p = nptr; + /* Skip leading space */ + while (g_ascii_isspace (*p)) + p++; + + /* Skip leading optional sign */ + if (*p == '+' || *p == '-') + p++; + + if (p[0] == '0' && + (p[1] == 'x' || p[1] == 'X')) + { + p += 2; + /* HEX - find the (optional) decimal point */ + + while (g_ascii_isxdigit (*p)) + p++; + + if (*p == '.') + decimal_point_pos = p++; + + while (g_ascii_isxdigit (*p)) + p++; + + if (*p == 'p' || *p == 'P') + p++; + if (*p == '+' || *p == '-') + p++; + while (g_ascii_isdigit (*p)) + p++; + + end = p; + } + else if (g_ascii_isdigit (*p) || *p == '.') + { + while (g_ascii_isdigit (*p)) + p++; + + if (*p == '.') + decimal_point_pos = p++; + + while (g_ascii_isdigit (*p)) + p++; + + if (*p == 'e' || *p == 'E') + p++; + if (*p == '+' || *p == '-') + p++; + while (g_ascii_isdigit (*p)) + p++; + + end = p; + } + /* For the other cases, we need not convert the decimal point */ + } + + if (decimal_point_pos) + { + char *copy, *c; + + /* We need to convert the '.' to the locale specific decimal point */ + copy = g_malloc (end - nptr + 1 + decimal_point_len); + + c = copy; + memcpy (c, nptr, decimal_point_pos - nptr); + c += decimal_point_pos - nptr; + memcpy (c, decimal_point, decimal_point_len); + c += decimal_point_len; + memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1)); + c += end - (decimal_point_pos + 1); + *c = 0; + + errno = 0; + val = strtod (copy, &fail_pos); + strtod_errno = errno; + + if (fail_pos) + { + if (fail_pos - copy > decimal_point_pos - nptr) + fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1); + else + fail_pos = (char *)nptr + (fail_pos - copy); + } + + g_free (copy); + + } + else if (end) + { + char *copy; + + copy = g_malloc (end - (char *)nptr + 1); + memcpy (copy, nptr, end - nptr); + *(copy + (end - (char *)nptr)) = 0; + + errno = 0; + val = strtod (copy, &fail_pos); + strtod_errno = errno; + + if (fail_pos) + { + fail_pos = (char *)nptr + (fail_pos - copy); + } + + g_free (copy); + } + else + { + errno = 0; + val = strtod (nptr, &fail_pos); + strtod_errno = errno; + } + + if (endptr) + *endptr = fail_pos; + + errno = strtod_errno; + + return val; +#endif +} + + +/** + * g_ascii_dtostr: + * @buffer: A buffer to place the resulting string in + * @buf_len: The length of the buffer. + * @d: The #gdouble to convert + * + * Converts a #gdouble to a string, using the '.' as + * decimal point. + * + * This functions generates enough precision that converting + * the string back using g_ascii_strtod() gives the same machine-number + * (on machines with IEEE compatible 64bit doubles). It is + * guaranteed that the size of the resulting string will never + * be larger than @G_ASCII_DTOSTR_BUF_SIZE bytes. + * + * Return value: The pointer to the buffer with the converted string. + **/ +gchar * +g_ascii_dtostr (gchar *buffer, + gint buf_len, + gdouble d) +{ + return g_ascii_formatd (buffer, buf_len, "%.17g", d); +} + +/** + * g_ascii_formatd: + * @buffer: A buffer to place the resulting string in + * @buf_len: The length of the buffer. + * @format: The printf()-style format to use for the + * code to use for converting. + * @d: The #gdouble to convert + * + * Converts a #gdouble to a string, using the '.' as + * decimal point. To format the number you pass in + * a printf()-style format string. Allowed conversion + * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'. + * + * If you just want to want to serialize the value into a + * string, use g_ascii_dtostr(). + * + * Return value: The pointer to the buffer with the converted string. + */ +gchar * +g_ascii_formatd (gchar *buffer, + gint buf_len, + const gchar *format, + gdouble d) +{ +#ifdef HAVE_USELOCALE + locale_t old_locale; + + old_locale = uselocale (get_C_locale ()); + _g_snprintf (buffer, buf_len, format, d); + uselocale (old_locale); + + return buffer; +#else + struct lconv *locale_data; + const char *decimal_point; + int decimal_point_len; + gchar *p; + int rest_len; + gchar format_char; + + g_return_val_if_fail (buffer != NULL, NULL); + g_return_val_if_fail (format[0] == '%', NULL); + g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL); + + format_char = format[strlen (format) - 1]; + + g_return_val_if_fail (format_char == 'e' || format_char == 'E' || + format_char == 'f' || format_char == 'F' || + format_char == 'g' || format_char == 'G', + NULL); + + if (format[0] != '%') + return NULL; + + if (strpbrk (format + 1, "'l%")) + return NULL; + + if (!(format_char == 'e' || format_char == 'E' || + format_char == 'f' || format_char == 'F' || + format_char == 'g' || format_char == 'G')) + return NULL; + + _g_snprintf (buffer, buf_len, format, d); + + locale_data = localeconv (); + decimal_point = locale_data->decimal_point; + decimal_point_len = strlen (decimal_point); + + g_assert (decimal_point_len != 0); + + if (decimal_point[0] != '.' || + decimal_point[1] != 0) + { + p = buffer; + + while (g_ascii_isspace (*p)) + p++; + + if (*p == '+' || *p == '-') + p++; + + while (isdigit ((guchar)*p)) + p++; + + if (strncmp (p, decimal_point, decimal_point_len) == 0) + { + *p = '.'; + p++; + if (decimal_point_len > 1) + { + rest_len = strlen (p + (decimal_point_len-1)); + memmove (p, p + (decimal_point_len-1), rest_len); + p[rest_len] = 0; + } + } + } + + return buffer; +#endif +} + +#define ISSPACE(c) ((c) == ' ' || (c) == '\f' || (c) == '\n' || \ + (c) == '\r' || (c) == '\t' || (c) == '\v') +#define ISUPPER(c) ((c) >= 'A' && (c) <= 'Z') +#define ISLOWER(c) ((c) >= 'a' && (c) <= 'z') +#define ISALPHA(c) (ISUPPER (c) || ISLOWER (c)) +#define TOUPPER(c) (ISLOWER (c) ? (c) - 'a' + 'A' : (c)) +#define TOLOWER(c) (ISUPPER (c) ? (c) - 'A' + 'a' : (c)) + +#if !defined(HAVE_STRTOLL_L) || !defined(HAVE_STRTOULL_L) + +static guint64 +g_parse_long_long (const gchar *nptr, + const gchar **endptr, + guint base, + gboolean *negative) +{ + /* this code is based on on the strtol(3) code from GNU libc released under + * the GNU Lesser General Public License. + * + * Copyright (C) 1991,92,94,95,96,97,98,99,2000,01,02 + * Free Software Foundation, Inc. + */ + gboolean overflow; + guint64 cutoff; + guint64 cutlim; + guint64 ui64; + const gchar *s, *save; + guchar c; + + g_return_val_if_fail (nptr != NULL, 0); + + *negative = FALSE; + if (base == 1 || base > 36) + { + errno = EINVAL; + if (endptr) + *endptr = nptr; + return 0; + } + + save = s = nptr; + + /* Skip white space. */ + while (ISSPACE (*s)) + ++s; + + if (G_UNLIKELY (!*s)) + goto noconv; + + /* Check for a sign. */ + if (*s == '-') + { + *negative = TRUE; + ++s; + } + else if (*s == '+') + ++s; + + /* Recognize number prefix and if BASE is zero, figure it out ourselves. */ + if (*s == '0') + { + if ((base == 0 || base == 16) && TOUPPER (s[1]) == 'X') + { + s += 2; + base = 16; + } + else if (base == 0) + base = 8; + } + else if (base == 0) + base = 10; + + /* Save the pointer so we can check later if anything happened. */ + save = s; + cutoff = G_MAXUINT64 / base; + cutlim = G_MAXUINT64 % base; + + overflow = FALSE; + ui64 = 0; + c = *s; + for (; c; c = *++s) + { + if (c >= '0' && c <= '9') + c -= '0'; + else if (ISALPHA (c)) + c = TOUPPER (c) - 'A' + 10; + else + break; + if (c >= base) + break; + /* Check for overflow. */ + if (ui64 > cutoff || (ui64 == cutoff && c > cutlim)) + overflow = TRUE; + else + { + ui64 *= base; + ui64 += c; + } + } + + /* Check if anything actually happened. */ + if (s == save) + goto noconv; + + /* Store in ENDPTR the address of one character + past the last character we converted. */ + if (endptr) + *endptr = s; + + if (G_UNLIKELY (overflow)) + { + errno = ERANGE; + return G_MAXUINT64; + } + + return ui64; + + noconv: + /* We must handle a special case here: the base is 0 or 16 and the + first two characters are '0' and 'x', but the rest are no + hexadecimal digits. This is no error case. We return 0 and + ENDPTR points to the `x`. */ + if (endptr) + { + if (save - nptr >= 2 && TOUPPER (save[-1]) == 'X' + && save[-2] == '0') + *endptr = &save[-1]; + else + /* There was no number to convert. */ + *endptr = nptr; + } + return 0; +} +#endif + +/** + * g_ascii_strtoull: + * @nptr: the string to convert to a numeric value. + * @endptr: if non-%NULL, it returns the character after + * the last character used in the conversion. + * @base: to be used for the conversion, 2..36 or 0 + * + * Converts a string to a #guint64 value. + * This function behaves like the standard strtoull() function + * does in the C locale. It does this without actually + * changing the current locale, since that would not be + * thread-safe. + * + * This function is typically used when reading configuration + * files or other non-user input that should be locale independent. + * To handle input from the user you should normally use the + * locale-sensitive system strtoull() function. + * + * If the correct value would cause overflow, %G_MAXUINT64 + * is returned, and ERANGE is stored in errno. + * If the base is outside the valid range, zero is returned, and + * EINVAL is stored in errno. + * If the string conversion fails, zero is returned, and @endptr returns + * @nptr (if @endptr is non-%NULL). + * + * Return value: the #guint64 value or zero on error. + * + * Since: 2.2 + */ +guint64 +g_ascii_strtoull (const gchar *nptr, + gchar **endptr, + guint base) +{ +#ifdef HAVE_STRTOULL_L + return strtoull_l (nptr, endptr, base, get_C_locale ()); +#else + gboolean negative; + guint64 result; + + result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative); + + /* Return the result of the appropriate sign. */ + return negative ? -result : result; +#endif +} + +/** + * g_ascii_strtoll: + * @nptr: the string to convert to a numeric value. + * @endptr: if non-%NULL, it returns the character after + * the last character used in the conversion. + * @base: to be used for the conversion, 2..36 or 0 + * + * Converts a string to a #gint64 value. + * This function behaves like the standard strtoll() function + * does in the C locale. It does this without actually + * changing the current locale, since that would not be + * thread-safe. + * + * This function is typically used when reading configuration + * files or other non-user input that should be locale independent. + * To handle input from the user you should normally use the + * locale-sensitive system strtoll() function. + * + * If the correct value would cause overflow, %G_MAXINT64 or %G_MININT64 + * is returned, and ERANGE is stored in errno. + * If the base is outside the valid range, zero is returned, and + * EINVAL is stored in errno. If the + * string conversion fails, zero is returned, and @endptr returns @nptr + * (if @endptr is non-%NULL). + * + * Return value: the #gint64 value or zero on error. + * + * Since: 2.12 + */ +gint64 +g_ascii_strtoll (const gchar *nptr, + gchar **endptr, + guint base) +{ +#ifdef HAVE_STRTOLL_L + return strtoll_l (nptr, endptr, base, get_C_locale ()); +#else + gboolean negative; + guint64 result; + + result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative); + + if (negative && result > (guint64) G_MININT64) + { + errno = ERANGE; + return G_MININT64; + } + else if (!negative && result > (guint64) G_MAXINT64) + { + errno = ERANGE; + return G_MAXINT64; + } + else if (negative) + return - (gint64) result; + else + return (gint64) result; +#endif +} + +/** + * g_strerror: + * @errnum: the system error number. See the standard C %errno + * documentation + * + * Returns a string corresponding to the given error code, e.g. + * "no such process". You should use this function in preference to + * strerror(), because it returns a string in UTF-8 encoding, and since + * not all platforms support the strerror() function. + * + * Returns: a UTF-8 string describing the error code. If the error code + * is unknown, it returns "unknown error (<code>)". + */ +const gchar * +g_strerror (gint errnum) +{ + gchar buf[64]; + gchar *msg; + gchar *tofree; + const gchar *ret; + gint saved_errno = errno; + + msg = tofree = NULL; + +#ifdef HAVE_STRERROR + msg = strerror (errnum); + if (!g_get_charset (NULL)) + msg = tofree = g_locale_to_utf8 (msg, -1, NULL, NULL, NULL); +#endif + + if (!msg) + { + msg = buf; + _g_sprintf (msg, "unknown error (%d)", errnum); + } + + ret = g_intern_string (msg); + g_free (tofree); + errno = saved_errno; + return ret; +} + +/** + * g_strsignal: + * @signum: the signal number. See the signal + * documentation + * + * Returns a string describing the given signal, e.g. "Segmentation fault". + * You should use this function in preference to strsignal(), because it + * returns a string in UTF-8 encoding, and since not all platforms support + * the strsignal() function. + * + * Returns: a UTF-8 string describing the signal. If the signal is unknown, + * it returns "unknown signal (<signum>)". + */ +const gchar * +g_strsignal (gint signum) +{ + gchar *msg; + gchar *tofree; + const gchar *ret; + + msg = tofree = NULL; + +#ifdef HAVE_STRSIGNAL + msg = strsignal (signum); + if (!g_get_charset (NULL)) + msg = tofree = g_locale_to_utf8 (msg, -1, NULL, NULL, NULL); +#endif + + if (!msg) + msg = tofree = g_strdup_printf ("unknown signal (%d)", signum); + ret = g_intern_string (msg); + g_free (tofree); + + return ret; +} + +/* Functions g_strlcpy and g_strlcat were originally developed by + * Todd C. Miller to simplify writing secure code. + * See http://www.openbsd.org/cgi-bin/man.cgi?query=strlcpy + * for more information. + */ + +#ifdef HAVE_STRLCPY +/* Use the native ones, if available; they might be implemented in assembly */ +gsize +g_strlcpy (gchar *dest, + const gchar *src, + gsize dest_size) +{ + g_return_val_if_fail (dest != NULL, 0); + g_return_val_if_fail (src != NULL, 0); + + return strlcpy (dest, src, dest_size); +} + +gsize +g_strlcat (gchar *dest, + const gchar *src, + gsize dest_size) +{ + g_return_val_if_fail (dest != NULL, 0); + g_return_val_if_fail (src != NULL, 0); + + return strlcat (dest, src, dest_size); +} + +#else /* ! HAVE_STRLCPY */ +/** + * g_strlcpy: + * @dest: destination buffer + * @src: source buffer + * @dest_size: length of @dest in bytes + * + * Portability wrapper that calls strlcpy() on systems which have it, + * and emulates strlcpy() otherwise. Copies @src to @dest; @dest is + * guaranteed to be nul-terminated; @src must be nul-terminated; + * @dest_size is the buffer size, not the number of chars to copy. + * + * At most dest_size - 1 characters will be copied. Always nul-terminates + * (unless dest_size == 0). This function does not + * allocate memory. Unlike strncpy(), this function doesn't pad dest (so + * it's often faster). It returns the size of the attempted result, + * strlen (src), so if @retval >= @dest_size, truncation occurred. + * + * Caveat: strlcpy() is supposedly more secure than + * strcpy() or strncpy(), but if you really want to avoid screwups, + * g_strdup() is an even better idea. + * + * Returns: length of @src + */ +gsize +g_strlcpy (gchar *dest, + const gchar *src, + gsize dest_size) +{ + register gchar *d = dest; + register const gchar *s = src; + register gsize n = dest_size; + + g_return_val_if_fail (dest != NULL, 0); + g_return_val_if_fail (src != NULL, 0); + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) + do + { + register gchar c = *s++; + + *d++ = c; + if (c == 0) + break; + } + while (--n != 0); + + /* If not enough room in dest, add NUL and traverse rest of src */ + if (n == 0) + { + if (dest_size != 0) + *d = 0; + while (*s++) + ; + } + + return s - src - 1; /* count does not include NUL */ +} + +/** + * g_strlcat: + * @dest: destination buffer, already containing one nul-terminated string + * @src: source buffer + * @dest_size: length of @dest buffer in bytes (not length of existing string + * inside @dest) + * + * Portability wrapper that calls strlcat() on systems which have it, + * and emulates it otherwise. Appends nul-terminated @src string to @dest, + * guaranteeing nul-termination for @dest. The total size of @dest won't + * exceed @dest_size. + * + * At most dest_size - 1 characters will be copied. + * Unlike strncat, dest_size is the full size of dest, not the space left over. + * This function does NOT allocate memory. + * This always NUL terminates (unless siz == 0 or there were no NUL characters + * in the dest_size characters of dest to start with). + * + * Caveat: this is supposedly a more secure alternative to + * strcat() or strncat(), but for real security g_strconcat() is harder + * to mess up. + * + * Returns: size of attempted result, which is MIN (dest_size, strlen + * (original dest)) + strlen (src), so if retval >= dest_size, + * truncation occurred. + **/ +gsize +g_strlcat (gchar *dest, + const gchar *src, + gsize dest_size) +{ + register gchar *d = dest; + register const gchar *s = src; + register gsize bytes_left = dest_size; + gsize dlength; /* Logically, MIN (strlen (d), dest_size) */ + + g_return_val_if_fail (dest != NULL, 0); + g_return_val_if_fail (src != NULL, 0); + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (*d != 0 && bytes_left-- != 0) + d++; + dlength = d - dest; + bytes_left = dest_size - dlength; + + if (bytes_left == 0) + return dlength + strlen (s); + + while (*s != 0) + { + if (bytes_left != 1) + { + *d++ = *s; + bytes_left--; + } + s++; + } + *d = 0; + + return dlength + (s - src); /* count does not include NUL */ +} +#endif /* ! HAVE_STRLCPY */ + +/** + * g_ascii_strdown: + * @str: a string. + * @len: length of @str in bytes, or -1 if @str is nul-terminated. + * + * Converts all upper case ASCII letters to lower case ASCII letters. + * + * Return value: a newly-allocated string, with all the upper case + * characters in @str converted to lower case, with + * semantics that exactly match g_ascii_tolower(). (Note + * that this is unlike the old g_strdown(), which modified + * the string in place.) + **/ +gchar* +g_ascii_strdown (const gchar *str, + gssize len) +{ + gchar *result, *s; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) + len = strlen (str); + + result = g_strndup (str, len); + for (s = result; *s; s++) + *s = g_ascii_tolower (*s); + + return result; +} + +/** + * g_ascii_strup: + * @str: a string. + * @len: length of @str in bytes, or -1 if @str is nul-terminated. + * + * Converts all lower case ASCII letters to upper case ASCII letters. + * + * Return value: a newly allocated string, with all the lower case + * characters in @str converted to upper case, with + * semantics that exactly match g_ascii_toupper(). (Note + * that this is unlike the old g_strup(), which modified + * the string in place.) + **/ +gchar* +g_ascii_strup (const gchar *str, + gssize len) +{ + gchar *result, *s; + + g_return_val_if_fail (str != NULL, NULL); + + if (len < 0) + len = strlen (str); + + result = g_strndup (str, len); + for (s = result; *s; s++) + *s = g_ascii_toupper (*s); + + return result; +} + +/** + * g_strdown: + * @string: the string to convert. + * + * Converts a string to lower case. + * + * Return value: the string + * + * Deprecated:2.2: This function is totally broken for the reasons discussed + * in the g_strncasecmp() docs - use g_ascii_strdown() or g_utf8_strdown() + * instead. + **/ +gchar* +g_strdown (gchar *string) +{ + register guchar *s; + + g_return_val_if_fail (string != NULL, NULL); + + s = (guchar *) string; + + while (*s) + { + if (isupper (*s)) + *s = tolower (*s); + s++; + } + + return (gchar *) string; +} + +/** + * g_strup: + * @string: the string to convert. + * + * Converts a string to upper case. + * + * Return value: the string + * + * Deprecated:2.2: This function is totally broken for the reasons discussed + * in the g_strncasecmp() docs - use g_ascii_strup() or g_utf8_strup() instead. + **/ +gchar* +g_strup (gchar *string) +{ + register guchar *s; + + g_return_val_if_fail (string != NULL, NULL); + + s = (guchar *) string; + + while (*s) + { + if (islower (*s)) + *s = toupper (*s); + s++; + } + + return (gchar *) string; +} + +/** + * g_strreverse: + * @string: the string to reverse + * + * Reverses all of the bytes in a string. For example, + * g_strreverse ("abcdef") will result + * in "fedcba". + * + * Note that g_strreverse() doesn't work on UTF-8 strings + * containing multibyte characters. For that purpose, use + * g_utf8_strreverse(). + * + * Returns: the same pointer passed in as @string + */ +gchar* +g_strreverse (gchar *string) +{ + g_return_val_if_fail (string != NULL, NULL); + + if (*string) + { + register gchar *h, *t; + + h = string; + t = string + strlen (string) - 1; + + while (h < t) + { + register gchar c; + + c = *h; + *h = *t; + h++; + *t = c; + t--; + } + } + + return string; +} + +/** + * g_ascii_tolower: + * @c: any character. + * + * Convert a character to ASCII lower case. + * + * Unlike the standard C library tolower() function, this only + * recognizes standard ASCII letters and ignores the locale, returning + * all non-ASCII characters unchanged, even if they are lower case + * letters in a particular character set. Also unlike the standard + * library function, this takes and returns a char, not an int, so + * don't call it on EOF but no need to worry about casting to #guchar + * before passing a possibly non-ASCII character in. + * + * Return value: the result of converting @c to lower case. + * If @c is not an ASCII upper case letter, + * @c is returned unchanged. + **/ +gchar +g_ascii_tolower (gchar c) +{ + return g_ascii_isupper (c) ? c - 'A' + 'a' : c; +} + +/** + * g_ascii_toupper: + * @c: any character. + * + * Convert a character to ASCII upper case. + * + * Unlike the standard C library toupper() function, this only + * recognizes standard ASCII letters and ignores the locale, returning + * all non-ASCII characters unchanged, even if they are upper case + * letters in a particular character set. Also unlike the standard + * library function, this takes and returns a char, not an int, so + * don't call it on EOF but no need to worry about casting to #guchar + * before passing a possibly non-ASCII character in. + * + * Return value: the result of converting @c to upper case. + * If @c is not an ASCII lower case letter, + * @c is returned unchanged. + **/ +gchar +g_ascii_toupper (gchar c) +{ + return g_ascii_islower (c) ? c - 'a' + 'A' : c; +} + +/** + * g_ascii_digit_value: + * @c: an ASCII character. + * + * Determines the numeric value of a character as a decimal + * digit. Differs from g_unichar_digit_value() because it takes + * a char, so there's no worry about sign extension if characters + * are signed. + * + * Return value: If @c is a decimal digit (according to + * g_ascii_isdigit()), its numeric value. Otherwise, -1. + **/ +int +g_ascii_digit_value (gchar c) +{ + if (g_ascii_isdigit (c)) + return c - '0'; + return -1; +} + +/** + * g_ascii_xdigit_value: + * @c: an ASCII character. + * + * Determines the numeric value of a character as a hexidecimal + * digit. Differs from g_unichar_xdigit_value() because it takes + * a char, so there's no worry about sign extension if characters + * are signed. + * + * Return value: If @c is a hex digit (according to + * g_ascii_isxdigit()), its numeric value. Otherwise, -1. + **/ +int +g_ascii_xdigit_value (gchar c) +{ + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + return g_ascii_digit_value (c); +} + +/** + * g_ascii_strcasecmp: + * @s1: string to compare with @s2. + * @s2: string to compare with @s1. + * + * Compare two strings, ignoring the case of ASCII characters. + * + * Unlike the BSD strcasecmp() function, this only recognizes standard + * ASCII letters and ignores the locale, treating all non-ASCII + * bytes as if they are not letters. + * + * This function should be used only on strings that are known to be + * in encodings where the bytes corresponding to ASCII letters always + * represent themselves. This includes UTF-8 and the ISO-8859-* + * charsets, but not for instance double-byte encodings like the + * Windows Codepage 932, where the trailing bytes of double-byte + * characters include all ASCII letters. If you compare two CP932 + * strings using this function, you will get false matches. + * + * Return value: 0 if the strings match, a negative value if @s1 < @s2, + * or a positive value if @s1 > @s2. + **/ +gint +g_ascii_strcasecmp (const gchar *s1, + const gchar *s2) +{ + gint c1, c2; + + g_return_val_if_fail (s1 != NULL, 0); + g_return_val_if_fail (s2 != NULL, 0); + + while (*s1 && *s2) + { + c1 = (gint)(guchar) TOLOWER (*s1); + c2 = (gint)(guchar) TOLOWER (*s2); + if (c1 != c2) + return (c1 - c2); + s1++; s2++; + } + + return (((gint)(guchar) *s1) - ((gint)(guchar) *s2)); +} + +/** + * g_ascii_strncasecmp: + * @s1: string to compare with @s2. + * @s2: string to compare with @s1. + * @n: number of characters to compare. + * + * Compare @s1 and @s2, ignoring the case of ASCII characters and any + * characters after the first @n in each string. + * + * Unlike the BSD strcasecmp() function, this only recognizes standard + * ASCII letters and ignores the locale, treating all non-ASCII + * characters as if they are not letters. + * + * The same warning as in g_ascii_strcasecmp() applies: Use this + * function only on strings known to be in encodings where bytes + * corresponding to ASCII letters always represent themselves. + * + * Return value: 0 if the strings match, a negative value if @s1 < @s2, + * or a positive value if @s1 > @s2. + **/ +gint +g_ascii_strncasecmp (const gchar *s1, + const gchar *s2, + gsize n) +{ + gint c1, c2; + + g_return_val_if_fail (s1 != NULL, 0); + g_return_val_if_fail (s2 != NULL, 0); + + while (n && *s1 && *s2) + { + n -= 1; + c1 = (gint)(guchar) TOLOWER (*s1); + c2 = (gint)(guchar) TOLOWER (*s2); + if (c1 != c2) + return (c1 - c2); + s1++; s2++; + } + + if (n) + return (((gint) (guchar) *s1) - ((gint) (guchar) *s2)); + else + return 0; +} + +/** + * g_strcasecmp: + * @s1: a string. + * @s2: a string to compare with @s1. + * + * A case-insensitive string comparison, corresponding to the standard + * strcasecmp() function on platforms which support it. + * + * Return value: 0 if the strings match, a negative value if @s1 < @s2, + * or a positive value if @s1 > @s2. + * + * Deprecated:2.2: See g_strncasecmp() for a discussion of why this function + * is deprecated and how to replace it. + **/ +gint +g_strcasecmp (const gchar *s1, + const gchar *s2) +{ +#ifdef HAVE_STRCASECMP + g_return_val_if_fail (s1 != NULL, 0); + g_return_val_if_fail (s2 != NULL, 0); + + return strcasecmp (s1, s2); +#else + gint c1, c2; + + g_return_val_if_fail (s1 != NULL, 0); + g_return_val_if_fail (s2 != NULL, 0); + + while (*s1 && *s2) + { + /* According to A. Cox, some platforms have islower's that + * don't work right on non-uppercase + */ + c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1; + c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2; + if (c1 != c2) + return (c1 - c2); + s1++; s2++; + } + + return (((gint)(guchar) *s1) - ((gint)(guchar) *s2)); +#endif +} + +/** + * g_strncasecmp: + * @s1: a string. + * @s2: a string to compare with @s1. + * @n: the maximum number of characters to compare. + * + * A case-insensitive string comparison, corresponding to the standard + * strncasecmp() function on platforms which support it. + * It is similar to g_strcasecmp() except it only compares the first @n + * characters of the strings. + * + * Return value: 0 if the strings match, a negative value if @s1 < @s2, + * or a positive value if @s1 > @s2. + * + * Deprecated:2.2: The problem with g_strncasecmp() is that it does the + * comparison by calling toupper()/tolower(). These functions are + * locale-specific and operate on single bytes. However, it is impossible + * to handle things correctly from an I18N standpoint by operating on + * bytes, since characters may be multibyte. Thus g_strncasecmp() is + * broken if your string is guaranteed to be ASCII, since it's + * locale-sensitive, and it's broken if your string is localized, since + * it doesn't work on many encodings at all, including UTF-8, EUC-JP, + * etc. + * + * There are therefore two replacement functions: g_ascii_strncasecmp(), + * which only works on ASCII and is not locale-sensitive, and + * g_utf8_casefold(), which is good for case-insensitive sorting of UTF-8. + **/ +gint +g_strncasecmp (const gchar *s1, + const gchar *s2, + guint n) +{ +#ifdef HAVE_STRNCASECMP + return strncasecmp (s1, s2, n); +#else + gint c1, c2; + + g_return_val_if_fail (s1 != NULL, 0); + g_return_val_if_fail (s2 != NULL, 0); + + while (n && *s1 && *s2) + { + n -= 1; + /* According to A. Cox, some platforms have islower's that + * don't work right on non-uppercase + */ + c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1; + c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2; + if (c1 != c2) + return (c1 - c2); + s1++; s2++; + } + + if (n) + return (((gint) (guchar) *s1) - ((gint) (guchar) *s2)); + else + return 0; +#endif +} + +/** + * g_strdelimit: + * @string: the string to convert + * @delimiters: a string containing the current delimiters, or %NULL + * to use the standard delimiters defined in #G_STR_DELIMITERS + * @new_delimiter: the new delimiter character + * + * Converts any delimiter characters in @string to @new_delimiter. + * Any characters in @string which are found in @delimiters are + * changed to the @new_delimiter character. Modifies @string in place, + * and returns @string itself, not a copy. The return value is to + * allow nesting such as + * |[ + * g_ascii_strup (g_strdelimit (str, "abc", '?')) + * ]| + * + * Returns: @string + */ +gchar * +g_strdelimit (gchar *string, + const gchar *delimiters, + gchar new_delim) +{ + register gchar *c; + + g_return_val_if_fail (string != NULL, NULL); + + if (!delimiters) + delimiters = G_STR_DELIMITERS; + + for (c = string; *c; c++) + { + if (strchr (delimiters, *c)) + *c = new_delim; + } + + return string; +} + +/** + * g_strcanon: + * @string: a nul-terminated array of bytes + * @valid_chars: bytes permitted in @string + * @substitutor: replacement character for disallowed bytes + * + * For each character in @string, if the character is not in + * @valid_chars, replaces the character with @substitutor. + * Modifies @string in place, and return @string itself, not + * a copy. The return value is to allow nesting such as + * |[ + * g_ascii_strup (g_strcanon (str, "abc", '?')) + * ]| + * + * Returns: @string + */ +gchar * +g_strcanon (gchar *string, + const gchar *valid_chars, + gchar substitutor) +{ + register gchar *c; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (valid_chars != NULL, NULL); + + for (c = string; *c; c++) + { + if (!strchr (valid_chars, *c)) + *c = substitutor; + } + + return string; +} + +/** + * g_strcompress: + * @source: a string to compress + * + * Replaces all escaped characters with their one byte equivalent. + * + * This function does the reverse conversion of g_strescape(). + * + * Returns: a newly-allocated copy of @source with all escaped + * character compressed + */ +gchar * +g_strcompress (const gchar *source) +{ + const gchar *p = source, *octal; + gchar *dest; + gchar *q; + + g_return_val_if_fail (source != NULL, NULL); + + dest = g_malloc (strlen (source) + 1); + q = dest; + + while (*p) + { + if (*p == '\\') + { + p++; + switch (*p) + { + case '\0': + g_warning ("g_strcompress: trailing \\"); + goto out; + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': + *q = 0; + octal = p; + while ((p < octal + 3) && (*p >= '0') && (*p <= '7')) + { + *q = (*q * 8) + (*p - '0'); + p++; + } + q++; + p--; + break; + case 'b': + *q++ = '\b'; + break; + case 'f': + *q++ = '\f'; + break; + case 'n': + *q++ = '\n'; + break; + case 'r': + *q++ = '\r'; + break; + case 't': + *q++ = '\t'; + break; + case 'v': + *q++ = '\v'; + break; + default: /* Also handles \" and \\ */ + *q++ = *p; + break; + } + } + else + *q++ = *p; + p++; + } +out: + *q = 0; + + return dest; +} + +/** + * g_strescape: + * @source: a string to escape + * @exceptions: a string of characters not to escape in @source + * + * Escapes the special characters '\b', '\f', '\n', '\r', '\t', '\v', '\' + * and '"' in the string @source by inserting a '\' before + * them. Additionally all characters in the range 0x01-0x1F (everything + * below SPACE) and in the range 0x7F-0xFF (all non-ASCII chars) are + * replaced with a '\' followed by their octal representation. + * Characters supplied in @exceptions are not escaped. + * + * g_strcompress() does the reverse conversion. + * + * Returns: a newly-allocated copy of @source with certain + * characters escaped. See above. + */ +gchar * +g_strescape (const gchar *source, + const gchar *exceptions) +{ + const guchar *p; + gchar *dest; + gchar *q; + guchar excmap[256]; + + g_return_val_if_fail (source != NULL, NULL); + + p = (guchar *) source; + /* Each source byte needs maximally four destination chars (\777) */ + q = dest = g_malloc (strlen (source) * 4 + 1); + + memset (excmap, 0, 256); + if (exceptions) + { + guchar *e = (guchar *) exceptions; + + while (*e) + { + excmap[*e] = 1; + e++; + } + } + + while (*p) + { + if (excmap[*p]) + *q++ = *p; + else + { + switch (*p) + { + case '\b': + *q++ = '\\'; + *q++ = 'b'; + break; + case '\f': + *q++ = '\\'; + *q++ = 'f'; + break; + case '\n': + *q++ = '\\'; + *q++ = 'n'; + break; + case '\r': + *q++ = '\\'; + *q++ = 'r'; + break; + case '\t': + *q++ = '\\'; + *q++ = 't'; + break; + case '\v': + *q++ = '\\'; + *q++ = 'v'; + break; + case '\\': + *q++ = '\\'; + *q++ = '\\'; + break; + case '"': + *q++ = '\\'; + *q++ = '"'; + break; + default: + if ((*p < ' ') || (*p >= 0177)) + { + *q++ = '\\'; + *q++ = '0' + (((*p) >> 6) & 07); + *q++ = '0' + (((*p) >> 3) & 07); + *q++ = '0' + ((*p) & 07); + } + else + *q++ = *p; + break; + } + } + p++; + } + *q = 0; + return dest; +} + +/** + * g_strchug: + * @string: a string to remove the leading whitespace from + * + * Removes leading whitespace from a string, by moving the rest + * of the characters forward. + * + * This function doesn't allocate or reallocate any memory; + * it modifies @string in place. The pointer to @string is + * returned to allow the nesting of functions. + * + * Also see g_strchomp() and g_strstrip(). + * + * Returns: @string + */ +gchar * +g_strchug (gchar *string) +{ + guchar *start; + + g_return_val_if_fail (string != NULL, NULL); + + for (start = (guchar*) string; *start && g_ascii_isspace (*start); start++) + ; + + g_memmove (string, start, strlen ((gchar *) start) + 1); + + return string; +} + +/** + * g_strchomp: + * @string: a string to remove the trailing whitespace from + * + * Removes trailing whitespace from a string. + * + * This function doesn't allocate or reallocate any memory; + * it modifies @string in place. The pointer to @string is + * returned to allow the nesting of functions. + * + * Also see g_strchug() and g_strstrip(). + * + * Returns: @string. + */ +gchar * +g_strchomp (gchar *string) +{ + gsize len; + + g_return_val_if_fail (string != NULL, NULL); + + len = strlen (string); + while (len--) + { + if (g_ascii_isspace ((guchar) string[len])) + string[len] = '\0'; + else + break; + } + + return string; +} + +/** + * g_strsplit: + * @string: a string to split + * @delimiter: a string which specifies the places at which to split + * the string. The delimiter is not included in any of the resulting + * strings, unless @max_tokens is reached. + * @max_tokens: the maximum number of pieces to split @string into. + * If this is less than 1, the string is split completely. + * + * Splits a string into a maximum of @max_tokens pieces, using the given + * @delimiter. If @max_tokens is reached, the remainder of @string is + * appended to the last token. + * + * As a special case, the result of splitting the empty string "" is an empty + * vector, not a vector containing a single string. The reason for this + * special case is that being able to represent a empty vector is typically + * more useful than consistent handling of empty elements. If you do need + * to represent empty elements, you'll need to check for the empty string + * before calling g_strsplit(). + * + * Return value: a newly-allocated %NULL-terminated array of strings. Use + * g_strfreev() to free it. + */ +gchar** +g_strsplit (const gchar *string, + const gchar *delimiter, + gint max_tokens) +{ + GSList *string_list = NULL, *slist; + gchar **str_array, *s; + guint n = 0; + const gchar *remainder; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiter != NULL, NULL); + g_return_val_if_fail (delimiter[0] != '\0', NULL); + + if (max_tokens < 1) + max_tokens = G_MAXINT; + + remainder = string; + s = strstr (remainder, delimiter); + if (s) + { + gsize delimiter_len = strlen (delimiter); + + while (--max_tokens && s) + { + gsize len; + + len = s - remainder; + string_list = g_slist_prepend (string_list, + g_strndup (remainder, len)); + n++; + remainder = s + delimiter_len; + s = strstr (remainder, delimiter); + } + } + if (*string) + { + n++; + string_list = g_slist_prepend (string_list, g_strdup (remainder)); + } + + str_array = g_new (gchar*, n + 1); + + str_array[n--] = NULL; + for (slist = string_list; slist; slist = slist->next) + str_array[n--] = slist->data; + + g_slist_free (string_list); + + return str_array; +} + +/** + * g_strsplit_set: + * @string: The string to be tokenized + * @delimiters: A nul-terminated string containing bytes that are used + * to split the string. + * @max_tokens: The maximum number of tokens to split @string into. + * If this is less than 1, the string is split completely + * + * Splits @string into a number of tokens not containing any of the characters + * in @delimiter. A token is the (possibly empty) longest string that does not + * contain any of the characters in @delimiters. If @max_tokens is reached, the + * remainder is appended to the last token. + * + * For example the result of g_strsplit_set ("abc:def/ghi", ":/", -1) is a + * %NULL-terminated vector containing the three strings "abc", "def", + * and "ghi". + * + * The result if g_strsplit_set (":def/ghi:", ":/", -1) is a %NULL-terminated + * vector containing the four strings "", "def", "ghi", and "". + * + * As a special case, the result of splitting the empty string "" is an empty + * vector, not a vector containing a single string. The reason for this + * special case is that being able to represent a empty vector is typically + * more useful than consistent handling of empty elements. If you do need + * to represent empty elements, you'll need to check for the empty string + * before calling g_strsplit_set(). + * + * Note that this function works on bytes not characters, so it can't be used + * to delimit UTF-8 strings for anything but ASCII characters. + * + * Return value: a newly-allocated %NULL-terminated array of strings. Use + * g_strfreev() to free it. + * + * Since: 2.4 + **/ +gchar ** +g_strsplit_set (const gchar *string, + const gchar *delimiters, + gint max_tokens) +{ + gboolean delim_table[256]; + GSList *tokens, *list; + gint n_tokens; + const gchar *s; + const gchar *current; + gchar *token; + gchar **result; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (delimiters != NULL, NULL); + + if (max_tokens < 1) + max_tokens = G_MAXINT; + + if (*string == '\0') + { + result = g_new (char *, 1); + result[0] = NULL; + return result; + } + + memset (delim_table, FALSE, sizeof (delim_table)); + for (s = delimiters; *s != '\0'; ++s) + delim_table[*(guchar *)s] = TRUE; + + tokens = NULL; + n_tokens = 0; + + s = current = string; + while (*s != '\0') + { + if (delim_table[*(guchar *)s] && n_tokens + 1 < max_tokens) + { + token = g_strndup (current, s - current); + tokens = g_slist_prepend (tokens, token); + ++n_tokens; + + current = s + 1; + } + + ++s; + } + + token = g_strndup (current, s - current); + tokens = g_slist_prepend (tokens, token); + ++n_tokens; + + result = g_new (gchar *, n_tokens + 1); + + result[n_tokens] = NULL; + for (list = tokens; list != NULL; list = list->next) + result[--n_tokens] = list->data; + + g_slist_free (tokens); + + return result; +} + +/** + * g_strfreev: + * @str_array: a %NULL-terminated array of strings to free + + * Frees a %NULL-terminated array of strings, and the array itself. + * If called on a %NULL value, g_strfreev() simply returns. + **/ +void +g_strfreev (gchar **str_array) +{ + if (str_array) + { + int i; + + for (i = 0; str_array[i] != NULL; i++) + g_free (str_array[i]); + + g_free (str_array); + } +} + +/** + * g_strdupv: + * @str_array: a %NULL-terminated array of strings + * + * Copies %NULL-terminated array of strings. The copy is a deep copy; + * the new array should be freed by first freeing each string, then + * the array itself. g_strfreev() does this for you. If called + * on a %NULL value, g_strdupv() simply returns %NULL. + * + * Return value: a new %NULL-terminated array of strings. + */ +gchar** +g_strdupv (gchar **str_array) +{ + if (str_array) + { + gint i; + gchar **retval; + + i = 0; + while (str_array[i]) + ++i; + + retval = g_new (gchar*, i + 1); + + i = 0; + while (str_array[i]) + { + retval[i] = g_strdup (str_array[i]); + ++i; + } + retval[i] = NULL; + + return retval; + } + else + return NULL; +} + +/** + * g_strjoinv: + * @separator: a string to insert between each of the strings, or %NULL + * @str_array: a %NULL-terminated array of strings to join + * + * Joins a number of strings together to form one long string, with the + * optional @separator inserted between each of them. The returned string + * should be freed with g_free(). + * + * Returns: a newly-allocated string containing all of the strings joined + * together, with @separator between them + */ +gchar* +g_strjoinv (const gchar *separator, + gchar **str_array) +{ + gchar *string; + gchar *ptr; + + g_return_val_if_fail (str_array != NULL, NULL); + + if (separator == NULL) + separator = ""; + + if (*str_array) + { + gint i; + gsize len; + gsize separator_len; + + separator_len = strlen (separator); + /* First part, getting length */ + len = 1 + strlen (str_array[0]); + for (i = 1; str_array[i] != NULL; i++) + len += strlen (str_array[i]); + len += separator_len * (i - 1); + + /* Second part, building string */ + string = g_new (gchar, len); + ptr = g_stpcpy (string, *str_array); + for (i = 1; str_array[i] != NULL; i++) + { + ptr = g_stpcpy (ptr, separator); + ptr = g_stpcpy (ptr, str_array[i]); + } + } + else + string = g_strdup (""); + + return string; +} + +/** + * g_strjoin: + * @separator: a string to insert between each of the strings, or %NULL + * @...: a %NULL-terminated list of strings to join + * + * Joins a number of strings together to form one long string, with the + * optional @separator inserted between each of them. The returned string + * should be freed with g_free(). + * + * Returns: a newly-allocated string containing all of the strings joined + * together, with @separator between them + */ +gchar* +g_strjoin (const gchar *separator, + ...) +{ + gchar *string, *s; + va_list args; + gsize len; + gsize separator_len; + gchar *ptr; + + if (separator == NULL) + separator = ""; + + separator_len = strlen (separator); + + va_start (args, separator); + + s = va_arg (args, gchar*); + + if (s) + { + /* First part, getting length */ + len = 1 + strlen (s); + + s = va_arg (args, gchar*); + while (s) + { + len += separator_len + strlen (s); + s = va_arg (args, gchar*); + } + va_end (args); + + /* Second part, building string */ + string = g_new (gchar, len); + + va_start (args, separator); + + s = va_arg (args, gchar*); + ptr = g_stpcpy (string, s); + + s = va_arg (args, gchar*); + while (s) + { + ptr = g_stpcpy (ptr, separator); + ptr = g_stpcpy (ptr, s); + s = va_arg (args, gchar*); + } + } + else + string = g_strdup (""); + + va_end (args); + + return string; +} + + +/** + * g_strstr_len: + * @haystack: a string + * @haystack_len: the maximum length of @haystack. Note that -1 is + * a valid length, if @haystack is nul-terminated, meaning it will + * search through the whole string. + * @needle: the string to search for + * + * Searches the string @haystack for the first occurrence + * of the string @needle, limiting the length of the search + * to @haystack_len. + * + * Return value: a pointer to the found occurrence, or + * %NULL if not found. + */ +gchar * +g_strstr_len (const gchar *haystack, + gssize haystack_len, + const gchar *needle) +{ + g_return_val_if_fail (haystack != NULL, NULL); + g_return_val_if_fail (needle != NULL, NULL); + + if (haystack_len < 0) + return strstr (haystack, needle); + else + { + const gchar *p = haystack; + gsize needle_len = strlen (needle); + const gchar *end; + gsize i; + + if (needle_len == 0) + return (gchar *)haystack; + + if (haystack_len < needle_len) + return NULL; + + end = haystack + haystack_len - needle_len; + + while (p <= end && *p) + { + for (i = 0; i < needle_len; i++) + if (p[i] != needle[i]) + goto next; + + return (gchar *)p; + + next: + p++; + } + + return NULL; + } +} + +/** + * g_strrstr: + * @haystack: a nul-terminated string + * @needle: the nul-terminated string to search for + * + * Searches the string @haystack for the last occurrence + * of the string @needle. + * + * Return value: a pointer to the found occurrence, or + * %NULL if not found. + */ +gchar * +g_strrstr (const gchar *haystack, + const gchar *needle) +{ + gsize i; + gsize needle_len; + gsize haystack_len; + const gchar *p; + + g_return_val_if_fail (haystack != NULL, NULL); + g_return_val_if_fail (needle != NULL, NULL); + + needle_len = strlen (needle); + haystack_len = strlen (haystack); + + if (needle_len == 0) + return (gchar *)haystack; + + if (haystack_len < needle_len) + return NULL; + + p = haystack + haystack_len - needle_len; + + while (p >= haystack) + { + for (i = 0; i < needle_len; i++) + if (p[i] != needle[i]) + goto next; + + return (gchar *)p; + + next: + p--; + } + + return NULL; +} + +/** + * g_strrstr_len: + * @haystack: a nul-terminated string + * @haystack_len: the maximum length of @haystack + * @needle: the nul-terminated string to search for + * + * Searches the string @haystack for the last occurrence + * of the string @needle, limiting the length of the search + * to @haystack_len. + * + * Return value: a pointer to the found occurrence, or + * %NULL if not found. + */ +gchar * +g_strrstr_len (const gchar *haystack, + gssize haystack_len, + const gchar *needle) +{ + g_return_val_if_fail (haystack != NULL, NULL); + g_return_val_if_fail (needle != NULL, NULL); + + if (haystack_len < 0) + return g_strrstr (haystack, needle); + else + { + gsize needle_len = strlen (needle); + const gchar *haystack_max = haystack + haystack_len; + const gchar *p = haystack; + gsize i; + + while (p < haystack_max && *p) + p++; + + if (p < haystack + needle_len) + return NULL; + + p -= needle_len; + + while (p >= haystack) + { + for (i = 0; i < needle_len; i++) + if (p[i] != needle[i]) + goto next; + + return (gchar *)p; + + next: + p--; + } + + return NULL; + } +} + + +/** + * g_str_has_suffix: + * @str: a nul-terminated string + * @suffix: the nul-terminated suffix to look for + * + * Looks whether the string @str ends with @suffix. + * + * Return value: %TRUE if @str end with @suffix, %FALSE otherwise. + * + * Since: 2.2 + */ +gboolean +g_str_has_suffix (const gchar *str, + const gchar *suffix) +{ + int str_len; + int suffix_len; + + g_return_val_if_fail (str != NULL, FALSE); + g_return_val_if_fail (suffix != NULL, FALSE); + + str_len = strlen (str); + suffix_len = strlen (suffix); + + if (str_len < suffix_len) + return FALSE; + + return strcmp (str + str_len - suffix_len, suffix) == 0; +} + +/** + * g_str_has_prefix: + * @str: a nul-terminated string + * @prefix: the nul-terminated prefix to look for + * + * Looks whether the string @str begins with @prefix. + * + * Return value: %TRUE if @str begins with @prefix, %FALSE otherwise. + * + * Since: 2.2 + */ +gboolean +g_str_has_prefix (const gchar *str, + const gchar *prefix) +{ + int str_len; + int prefix_len; + + g_return_val_if_fail (str != NULL, FALSE); + g_return_val_if_fail (prefix != NULL, FALSE); + + str_len = strlen (str); + prefix_len = strlen (prefix); + + if (str_len < prefix_len) + return FALSE; + + return strncmp (str, prefix, prefix_len) == 0; +} + +/** + * g_strv_length: + * @str_array: a %NULL-terminated array of strings + * + * Returns the length of the given %NULL-terminated + * string array @str_array. + * + * Return value: length of @str_array. + * + * Since: 2.6 + */ +guint +g_strv_length (gchar **str_array) +{ + guint i = 0; + + g_return_val_if_fail (str_array != NULL, 0); + + while (str_array[i]) + ++i; + + return i; +} diff --git a/glib/glib/gstrfuncs.h b/glib/glib/gstrfuncs.h new file mode 100644 index 0000000..68c89fd --- /dev/null +++ b/glib/glib/gstrfuncs.h @@ -0,0 +1,247 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_STRFUNCS_H__ +#define __G_STRFUNCS_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +/* Functions like the ones in that are not affected by locale. */ +typedef enum { + G_ASCII_ALNUM = 1 << 0, + G_ASCII_ALPHA = 1 << 1, + G_ASCII_CNTRL = 1 << 2, + G_ASCII_DIGIT = 1 << 3, + G_ASCII_GRAPH = 1 << 4, + G_ASCII_LOWER = 1 << 5, + G_ASCII_PRINT = 1 << 6, + G_ASCII_PUNCT = 1 << 7, + G_ASCII_SPACE = 1 << 8, + G_ASCII_UPPER = 1 << 9, + G_ASCII_XDIGIT = 1 << 10 +} GAsciiType; + +GLIB_VAR const guint16 * const g_ascii_table; + +#define g_ascii_isalnum(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_ALNUM) != 0) + +#define g_ascii_isalpha(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_ALPHA) != 0) + +#define g_ascii_iscntrl(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_CNTRL) != 0) + +#define g_ascii_isdigit(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_DIGIT) != 0) + +#define g_ascii_isgraph(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_GRAPH) != 0) + +#define g_ascii_islower(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_LOWER) != 0) + +#define g_ascii_isprint(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0) + +#define g_ascii_ispunct(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_PUNCT) != 0) + +#define g_ascii_isspace(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_SPACE) != 0) + +#define g_ascii_isupper(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_UPPER) != 0) + +#define g_ascii_isxdigit(c) \ + ((g_ascii_table[(guchar) (c)] & G_ASCII_XDIGIT) != 0) + +gchar g_ascii_tolower (gchar c) G_GNUC_CONST; +gchar g_ascii_toupper (gchar c) G_GNUC_CONST; + +gint g_ascii_digit_value (gchar c) G_GNUC_CONST; +gint g_ascii_xdigit_value (gchar c) G_GNUC_CONST; + +/* String utility functions that modify a string argument or + * return a constant string that must not be freed. + */ +#define G_STR_DELIMITERS "_-|> <." +gchar* g_strdelimit (gchar *string, + const gchar *delimiters, + gchar new_delimiter); +gchar* g_strcanon (gchar *string, + const gchar *valid_chars, + gchar substitutor); +const gchar * g_strerror (gint errnum) G_GNUC_CONST; +const gchar * g_strsignal (gint signum) G_GNUC_CONST; +gchar * g_strreverse (gchar *string); +gsize g_strlcpy (gchar *dest, + const gchar *src, + gsize dest_size); +gsize g_strlcat (gchar *dest, + const gchar *src, + gsize dest_size); +gchar * g_strstr_len (const gchar *haystack, + gssize haystack_len, + const gchar *needle); +gchar * g_strrstr (const gchar *haystack, + const gchar *needle); +gchar * g_strrstr_len (const gchar *haystack, + gssize haystack_len, + const gchar *needle); + +gboolean g_str_has_suffix (const gchar *str, + const gchar *suffix); +gboolean g_str_has_prefix (const gchar *str, + const gchar *prefix); + +/* String to/from double conversion functions */ + +gdouble g_strtod (const gchar *nptr, + gchar **endptr); +gdouble g_ascii_strtod (const gchar *nptr, + gchar **endptr); +guint64 g_ascii_strtoull (const gchar *nptr, + gchar **endptr, + guint base); +gint64 g_ascii_strtoll (const gchar *nptr, + gchar **endptr, + guint base); +/* 29 bytes should enough for all possible values that + * g_ascii_dtostr can produce. + * Then add 10 for good measure */ +#define G_ASCII_DTOSTR_BUF_SIZE (29 + 10) +gchar * g_ascii_dtostr (gchar *buffer, + gint buf_len, + gdouble d); +gchar * g_ascii_formatd (gchar *buffer, + gint buf_len, + const gchar *format, + gdouble d); + +/* removes leading spaces */ +gchar* g_strchug (gchar *string); +/* removes trailing spaces */ +gchar* g_strchomp (gchar *string); +/* removes leading & trailing spaces */ +#define g_strstrip( string ) g_strchomp (g_strchug (string)) + +gint g_ascii_strcasecmp (const gchar *s1, + const gchar *s2); +gint g_ascii_strncasecmp (const gchar *s1, + const gchar *s2, + gsize n); +gchar* g_ascii_strdown (const gchar *str, + gssize len) G_GNUC_MALLOC; +gchar* g_ascii_strup (const gchar *str, + gssize len) G_GNUC_MALLOC; + + +GLIB_DEPRECATED +gint g_strcasecmp (const gchar *s1, + const gchar *s2); +GLIB_DEPRECATED +gint g_strncasecmp (const gchar *s1, + const gchar *s2, + guint n); +GLIB_DEPRECATED +gchar* g_strdown (gchar *string); +GLIB_DEPRECATED +gchar* g_strup (gchar *string); + + +/* String utility functions that return a newly allocated string which + * ought to be freed with g_free from the caller at some point. + */ +gchar* g_strdup (const gchar *str) G_GNUC_MALLOC; +gchar* g_strdup_printf (const gchar *format, + ...) G_GNUC_PRINTF (1, 2) G_GNUC_MALLOC; +gchar* g_strdup_vprintf (const gchar *format, + va_list args) G_GNUC_MALLOC; +gchar* g_strndup (const gchar *str, + gsize n) G_GNUC_MALLOC; +gchar* g_strnfill (gsize length, + gchar fill_char) G_GNUC_MALLOC; +gchar* g_strconcat (const gchar *string1, + ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; +gchar* g_strjoin (const gchar *separator, + ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED; + +/* Make a copy of a string interpreting C string -style escape + * sequences. Inverse of g_strescape. The recognized sequences are \b + * \f \n \r \t \\ \" and the octal format. + */ +gchar* g_strcompress (const gchar *source) G_GNUC_MALLOC; + +/* Copy a string escaping nonprintable characters like in C strings. + * Inverse of g_strcompress. The exceptions parameter, if non-NULL, points + * to a string containing characters that are not to be escaped. + * + * Deprecated API: gchar* g_strescape (const gchar *source); + * Luckily this function wasn't used much, using NULL as second parameter + * provides mostly identical semantics. + */ +gchar* g_strescape (const gchar *source, + const gchar *exceptions) G_GNUC_MALLOC; + +gpointer g_memdup (gconstpointer mem, + guint byte_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(2); + +/* NULL terminated string arrays. + * g_strsplit(), g_strsplit_set() split up string into max_tokens tokens + * at delim and return a newly allocated string array. + * g_strjoinv() concatenates all of str_array's strings, sliding in an + * optional separator, the returned string is newly allocated. + * g_strfreev() frees the array itself and all of its strings. + * g_strdupv() copies a NULL-terminated array of strings + * g_strv_length() returns the length of a NULL-terminated array of strings + */ +gchar** g_strsplit (const gchar *string, + const gchar *delimiter, + gint max_tokens) G_GNUC_MALLOC; +gchar ** g_strsplit_set (const gchar *string, + const gchar *delimiters, + gint max_tokens) G_GNUC_MALLOC; +gchar* g_strjoinv (const gchar *separator, + gchar **str_array) G_GNUC_MALLOC; +void g_strfreev (gchar **str_array); +gchar** g_strdupv (gchar **str_array) G_GNUC_MALLOC; +guint g_strv_length (gchar **str_array); + +gchar* g_stpcpy (gchar *dest, + const char *src); + +G_END_DECLS + +#endif /* __G_STRFUNCS_H__ */ diff --git a/glib/glib/gstring.c b/glib/glib/gstring.c new file mode 100644 index 0000000..9fac86c --- /dev/null +++ b/glib/glib/gstring.c @@ -0,0 +1,1234 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include + +#include "gstring.h" + +#include "gprintf.h" + + +/** + * SECTION:strings + * @title: Strings + * @short_description: text buffers which grow automatically + * as text is added + * + * A #GString is an object that handles the memory management + * of a C string for you. You can think of it as similar to a + * Java StringBuffer. In addition to the string itself, GString + * stores the length of the string, so can be used for binary + * data with embedded nul bytes. To access the C string managed + * by the GString @string, simply use @string->str. + */ + +/** + * GString: + * @str: points to the character data. It may move as text is added. + * The @str field is null-terminated and so + * can be used as an ordinary C string. + * @len: contains the length of the string, not including the + * terminating nul byte. + * @allocated_len: the number of bytes that can be stored in the + * string before it needs to be reallocated. May be larger than @len. + * + * The GString struct contains the public fields of a GString. + */ + + +#define MY_MAXSIZE ((gsize)-1) + +static inline gsize +nearest_power (gsize base, gsize num) +{ + if (num > MY_MAXSIZE / 2) + { + return MY_MAXSIZE; + } + else + { + gsize n = base; + + while (n < num) + n <<= 1; + + return n; + } +} + +static void +g_string_maybe_expand (GString *string, + gsize len) +{ + if (string->len + len >= string->allocated_len) + { + string->allocated_len = nearest_power (1, string->len + len + 1); + string->str = g_realloc (string->str, string->allocated_len); + } +} + +/** + * g_string_sized_new: + * @dfl_size: the default size of the space allocated to + * hold the string + * + * Creates a new #GString, with enough space for @dfl_size + * bytes. This is useful if you are going to add a lot of + * text to the string and don't want it to be reallocated + * too often. + * + * Returns: the new #GString + */ +GString * +g_string_sized_new (gsize dfl_size) +{ + GString *string = g_slice_new (GString); + + string->allocated_len = 0; + string->len = 0; + string->str = NULL; + + g_string_maybe_expand (string, MAX (dfl_size, 2)); + string->str[0] = 0; + + return string; +} + +/** + * g_string_new: + * @init: the initial text to copy into the string + * + * Creates a new #GString, initialized with the given string. + * + * Returns: the new #GString + */ +GString * +g_string_new (const gchar *init) +{ + GString *string; + + if (init == NULL || *init == '\0') + string = g_string_sized_new (2); + else + { + gint len; + + len = strlen (init); + string = g_string_sized_new (len + 2); + + g_string_append_len (string, init, len); + } + + return string; +} + +/** + * g_string_new_len: + * @init: initial contents of the string + * @len: length of @init to use + * + * Creates a new #GString with @len bytes of the @init buffer. + * Because a length is provided, @init need not be nul-terminated, + * and can contain embedded nul bytes. + * + * Since this function does not stop at nul bytes, it is the caller's + * responsibility to ensure that @init has at least @len addressable + * bytes. + * + * Returns: a new #GString + */ +GString * +g_string_new_len (const gchar *init, + gssize len) +{ + GString *string; + + if (len < 0) + return g_string_new (init); + else + { + string = g_string_sized_new (len); + + if (init) + g_string_append_len (string, init, len); + + return string; + } +} + +/** + * g_string_free: + * @string: a #GString + * @free_segment: if %TRUE, the actual character data is freed as well + * + * Frees the memory allocated for the #GString. + * If @free_segment is %TRUE it also frees the character data. If + * it's %FALSE, the caller gains ownership of the buffer and must + * free it after use with g_free(). + * + * Returns: the character data of @string + * (i.e. %NULL if @free_segment is %TRUE) + */ +gchar * +g_string_free (GString *string, + gboolean free_segment) +{ + gchar *segment; + + g_return_val_if_fail (string != NULL, NULL); + + if (free_segment) + { + g_free (string->str); + segment = NULL; + } + else + segment = string->str; + + g_slice_free (GString, string); + + return segment; +} + +/** + * g_string_equal: + * @v: a #GString + * @v2: another #GString + * + * Compares two strings for equality, returning %TRUE if they are equal. + * For use with #GHashTable. + * + * Returns: %TRUE if they strings are the same length and contain the + * same bytes + */ +gboolean +g_string_equal (const GString *v, + const GString *v2) +{ + gchar *p, *q; + GString *string1 = (GString *) v; + GString *string2 = (GString *) v2; + gsize i = string1->len; + + if (i != string2->len) + return FALSE; + + p = string1->str; + q = string2->str; + while (i) + { + if (*p != *q) + return FALSE; + p++; + q++; + i--; + } + return TRUE; +} + +/** + * g_string_hash: + * @str: a string to hash + * + * Creates a hash code for @str; for use with #GHashTable. + * + * Returns: hash code for @str + */ +guint +g_string_hash (const GString *str) +{ + const gchar *p = str->str; + gsize n = str->len; + guint h = 0; + + /* 31 bit hash function */ + while (n--) + { + h = (h << 5) - h + *p; + p++; + } + + return h; +} + +/** + * g_string_assign: + * @string: the destination #GString. Its current contents + * are destroyed. + * @rval: the string to copy into @string + * + * Copies the bytes from a string into a #GString, + * destroying any previous contents. It is rather like + * the standard strcpy() function, except that you do not + * have to worry about having enough space to copy the string. + * + * Returns: @string + */ +GString * +g_string_assign (GString *string, + const gchar *rval) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (rval != NULL, string); + + /* Make sure assigning to itself doesn't corrupt the string. */ + if (string->str != rval) + { + /* Assigning from substring should be ok, since + * g_string_truncate() does not reallocate. + */ + g_string_truncate (string, 0); + g_string_append (string, rval); + } + + return string; +} + +/** + * g_string_truncate: + * @string: a #GString + * @len: the new size of @string + * + * Cuts off the end of the GString, leaving the first @len bytes. + * + * Returns: @string + */ +GString * +g_string_truncate (GString *string, + gsize len) +{ + g_return_val_if_fail (string != NULL, NULL); + + string->len = MIN (len, string->len); + string->str[string->len] = 0; + + return string; +} + +/** + * g_string_set_size: + * @string: a #GString + * @len: the new length + * + * Sets the length of a #GString. If the length is less than + * the current length, the string will be truncated. If the + * length is greater than the current length, the contents + * of the newly added area are undefined. (However, as + * always, string->str[string->len] will be a nul byte.) + * + * Return value: @string + */ +GString * +g_string_set_size (GString *string, + gsize len) +{ + g_return_val_if_fail (string != NULL, NULL); + + if (len >= string->allocated_len) + g_string_maybe_expand (string, len - string->len); + + string->len = len; + string->str[len] = 0; + + return string; +} + +/** + * g_string_insert_len: + * @string: a #GString + * @pos: position in @string where insertion should + * happen, or -1 for at the end + * @val: bytes to insert + * @len: number of bytes of @val to insert + * + * Inserts @len bytes of @val into @string at @pos. + * Because @len is provided, @val may contain embedded + * nuls and need not be nul-terminated. If @pos is -1, + * bytes are inserted at the end of the string. + * + * Since this function does not stop at nul bytes, it is + * the caller's responsibility to ensure that @val has at + * least @len addressable bytes. + * + * Returns: @string + */ +GString * +g_string_insert_len (GString *string, + gssize pos, + const gchar *val, + gssize len) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (len == 0 || val != NULL, string); + + if (len == 0) + return string; + + if (len < 0) + len = strlen (val); + + if (pos < 0) + pos = string->len; + else + g_return_val_if_fail (pos <= string->len, string); + + /* Check whether val represents a substring of string. + * This test probably violates chapter and verse of the C standards, + * since ">=" and "<=" are only valid when val really is a substring. + * In practice, it will work on modern archs. + */ + if (val >= string->str && val <= string->str + string->len) + { + gsize offset = val - string->str; + gsize precount = 0; + + g_string_maybe_expand (string, len); + val = string->str + offset; + /* At this point, val is valid again. */ + + /* Open up space where we are going to insert. */ + if (pos < string->len) + g_memmove (string->str + pos + len, string->str + pos, string->len - pos); + + /* Move the source part before the gap, if any. */ + if (offset < pos) + { + precount = MIN (len, pos - offset); + memcpy (string->str + pos, val, precount); + } + + /* Move the source part after the gap, if any. */ + if (len > precount) + memcpy (string->str + pos + precount, + val + /* Already moved: */ precount + /* Space opened up: */ len, + len - precount); + } + else + { + g_string_maybe_expand (string, len); + + /* If we aren't appending at the end, move a hunk + * of the old string to the end, opening up space + */ + if (pos < string->len) + g_memmove (string->str + pos + len, string->str + pos, string->len - pos); + + /* insert the new string */ + if (len == 1) + string->str[pos] = *val; + else + memcpy (string->str + pos, val, len); + } + + string->len += len; + + string->str[string->len] = 0; + + return string; +} + +#define SUB_DELIM_CHARS "!$&'()*+,;=" + +static gboolean +is_valid (char c, + const char *reserved_chars_allowed) +{ + if (g_ascii_isalnum (c) || + c == '-' || + c == '.' || + c == '_' || + c == '~') + return TRUE; + + if (reserved_chars_allowed && + strchr (reserved_chars_allowed, c) != NULL) + return TRUE; + + return FALSE; +} + +static gboolean +gunichar_ok (gunichar c) +{ + return + (c != (gunichar) -2) && + (c != (gunichar) -1); +} + +/** + * g_string_append_uri_escaped: + * @string: a #GString + * @unescaped: a string + * @reserved_chars_allowed: a string of reserved characters allowed + * to be used, or %NULL + * @allow_utf8: set %TRUE if the escaped string may include UTF8 characters + * + * Appends @unescaped to @string, escaped any characters that + * are reserved in URIs using URI-style escape sequences. + * + * Returns: @string + * + * Since: 2.16 + */ +GString * +g_string_append_uri_escaped (GString *string, + const gchar *unescaped, + const gchar *reserved_chars_allowed, + gboolean allow_utf8) +{ + unsigned char c; + const gchar *end; + static const gchar hex[16] = "0123456789ABCDEF"; + + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (unescaped != NULL, NULL); + + end = unescaped + strlen (unescaped); + + while ((c = *unescaped) != 0) + { + if (c >= 0x80 && allow_utf8 && + gunichar_ok (g_utf8_get_char_validated (unescaped, end - unescaped))) + { + int len = g_utf8_skip [c]; + g_string_append_len (string, unescaped, len); + unescaped += len; + } + else if (is_valid (c, reserved_chars_allowed)) + { + g_string_append_c (string, c); + unescaped++; + } + else + { + g_string_append_c (string, '%'); + g_string_append_c (string, hex[((guchar)c) >> 4]); + g_string_append_c (string, hex[((guchar)c) & 0xf]); + unescaped++; + } + } + + return string; +} + +/** + * g_string_append: + * @string: a #GString + * @val: the string to append onto the end of @string + * + * Adds a string onto the end of a #GString, expanding + * it if necessary. + * + * Returns: @string + */ +GString * +g_string_append (GString *string, + const gchar *val) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (val != NULL, string); + + return g_string_insert_len (string, -1, val, -1); +} + +/** + * g_string_append_len: + * @string: a #GString + * @val: bytes to append + * @len: number of bytes of @val to use + * + * Appends @len bytes of @val to @string. Because @len is + * provided, @val may contain embedded nuls and need not + * be nul-terminated. + * + * Since this function does not stop at nul bytes, it is + * the caller's responsibility to ensure that @val has at + * least @len addressable bytes. + * + * Returns: @string + */ +GString * +g_string_append_len (GString *string, + const gchar *val, + gssize len) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (len == 0 || val != NULL, string); + + return g_string_insert_len (string, -1, val, len); +} + +/** + * g_string_append_c: + * @string: a #GString + * @c: the byte to append onto the end of @string + * + * Adds a byte onto the end of a #GString, expanding + * it if necessary. + * + * Returns: @string + */ +#undef g_string_append_c +GString * +g_string_append_c (GString *string, + gchar c) +{ + g_return_val_if_fail (string != NULL, NULL); + + return g_string_insert_c (string, -1, c); +} + +/** + * g_string_append_unichar: + * @string: a #GString + * @wc: a Unicode character + * + * Converts a Unicode character into UTF-8, and appends it + * to the string. + * + * Return value: @string + */ +GString * +g_string_append_unichar (GString *string, + gunichar wc) +{ + g_return_val_if_fail (string != NULL, NULL); + + return g_string_insert_unichar (string, -1, wc); +} + +/** + * g_string_prepend: + * @string: a #GString + * @val: the string to prepend on the start of @string + * + * Adds a string on to the start of a #GString, + * expanding it if necessary. + * + * Returns: @string + */ +GString * +g_string_prepend (GString *string, + const gchar *val) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (val != NULL, string); + + return g_string_insert_len (string, 0, val, -1); +} + +/** + * g_string_prepend_len: + * @string: a #GString + * @val: bytes to prepend + * @len: number of bytes in @val to prepend + * + * Prepends @len bytes of @val to @string. + * Because @len is provided, @val may contain + * embedded nuls and need not be nul-terminated. + * + * Since this function does not stop at nul bytes, + * it is the caller's responsibility to ensure that + * @val has at least @len addressable bytes. + * + * Returns: @string + */ +GString * +g_string_prepend_len (GString *string, + const gchar *val, + gssize len) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (val != NULL, string); + + return g_string_insert_len (string, 0, val, len); +} + +/** + * g_string_prepend_c: + * @string: a #GString + * @c: the byte to prepend on the start of the #GString + * + * Adds a byte onto the start of a #GString, + * expanding it if necessary. + * + * Returns: @string + */ +GString * +g_string_prepend_c (GString *string, + gchar c) +{ + g_return_val_if_fail (string != NULL, NULL); + + return g_string_insert_c (string, 0, c); +} + +/** + * g_string_prepend_unichar: + * @string: a #GString + * @wc: a Unicode character + * + * Converts a Unicode character into UTF-8, and prepends it + * to the string. + * + * Return value: @string + */ +GString * +g_string_prepend_unichar (GString *string, + gunichar wc) +{ + g_return_val_if_fail (string != NULL, NULL); + + return g_string_insert_unichar (string, 0, wc); +} + +/** + * g_string_insert: + * @string: a #GString + * @pos: the position to insert the copy of the string + * @val: the string to insert + * + * Inserts a copy of a string into a #GString, + * expanding it if necessary. + * + * Returns: @string + */ +GString * +g_string_insert (GString *string, + gssize pos, + const gchar *val) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (val != NULL, string); + + if (pos >= 0) + g_return_val_if_fail (pos <= string->len, string); + + return g_string_insert_len (string, pos, val, -1); +} + +/** + * g_string_insert_c: + * @string: a #GString + * @pos: the position to insert the byte + * @c: the byte to insert + * + * Inserts a byte into a #GString, expanding it if necessary. + * + * Returns: @string + */ +GString * +g_string_insert_c (GString *string, + gssize pos, + gchar c) +{ + g_return_val_if_fail (string != NULL, NULL); + + g_string_maybe_expand (string, 1); + + if (pos < 0) + pos = string->len; + else + g_return_val_if_fail (pos <= string->len, string); + + /* If not just an append, move the old stuff */ + if (pos < string->len) + g_memmove (string->str + pos + 1, string->str + pos, string->len - pos); + + string->str[pos] = c; + + string->len += 1; + + string->str[string->len] = 0; + + return string; +} + +/** + * g_string_insert_unichar: + * @string: a #GString + * @pos: the position at which to insert character, or -1 + * to append at the end of the string + * @wc: a Unicode character + * + * Converts a Unicode character into UTF-8, and insert it + * into the string at the given position. + * + * Return value: @string + */ +GString * +g_string_insert_unichar (GString *string, + gssize pos, + gunichar wc) +{ + gint charlen, first, i; + gchar *dest; + + g_return_val_if_fail (string != NULL, NULL); + + /* Code copied from g_unichar_to_utf() */ + if (wc < 0x80) + { + first = 0; + charlen = 1; + } + else if (wc < 0x800) + { + first = 0xc0; + charlen = 2; + } + else if (wc < 0x10000) + { + first = 0xe0; + charlen = 3; + } + else if (wc < 0x200000) + { + first = 0xf0; + charlen = 4; + } + else if (wc < 0x4000000) + { + first = 0xf8; + charlen = 5; + } + else + { + first = 0xfc; + charlen = 6; + } + /* End of copied code */ + + g_string_maybe_expand (string, charlen); + + if (pos < 0) + pos = string->len; + else + g_return_val_if_fail (pos <= string->len, string); + + /* If not just an append, move the old stuff */ + if (pos < string->len) + g_memmove (string->str + pos + charlen, string->str + pos, string->len - pos); + + dest = string->str + pos; + /* Code copied from g_unichar_to_utf() */ + for (i = charlen - 1; i > 0; --i) + { + dest[i] = (wc & 0x3f) | 0x80; + wc >>= 6; + } + dest[0] = wc | first; + /* End of copied code */ + + string->len += charlen; + + string->str[string->len] = 0; + + return string; +} + +/** + * g_string_overwrite: + * @string: a #GString + * @pos: the position at which to start overwriting + * @val: the string that will overwrite the @string starting at @pos + * + * Overwrites part of a string, lengthening it if necessary. + * + * Return value: @string + * + * Since: 2.14 + */ +GString * +g_string_overwrite (GString *string, + gsize pos, + const gchar *val) +{ + g_return_val_if_fail (val != NULL, string); + return g_string_overwrite_len (string, pos, val, strlen (val)); +} + +/** + * g_string_overwrite_len: + * @string: a #GString + * @pos: the position at which to start overwriting + * @val: the string that will overwrite the @string starting at @pos + * @len: the number of bytes to write from @val + * + * Overwrites part of a string, lengthening it if necessary. + * This function will work with embedded nuls. + * + * Return value: @string + * + * Since: 2.14 + */ +GString * +g_string_overwrite_len (GString *string, + gsize pos, + const gchar *val, + gssize len) +{ + gsize end; + + g_return_val_if_fail (string != NULL, NULL); + + if (!len) + return string; + + g_return_val_if_fail (val != NULL, string); + g_return_val_if_fail (pos <= string->len, string); + + if (len < 0) + len = strlen (val); + + end = pos + len; + + if (end > string->len) + g_string_maybe_expand (string, end - string->len); + + memcpy (string->str + pos, val, len); + + if (end > string->len) + { + string->str[end] = '\0'; + string->len = end; + } + + return string; +} + +/** + * g_string_erase: + * @string: a #GString + * @pos: the position of the content to remove + * @len: the number of bytes to remove, or -1 to remove all + * following bytes + * + * Removes @len bytes from a #GString, starting at position @pos. + * The rest of the #GString is shifted down to fill the gap. + * + * Returns: @string + */ +GString * +g_string_erase (GString *string, + gssize pos, + gssize len) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (pos >= 0, string); + g_return_val_if_fail (pos <= string->len, string); + + if (len < 0) + len = string->len - pos; + else + { + g_return_val_if_fail (pos + len <= string->len, string); + + if (pos + len < string->len) + g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len)); + } + + string->len -= len; + + string->str[string->len] = 0; + + return string; +} + +/** + * g_string_ascii_down: + * @string: a GString + * + * Converts all uppercase ASCII letters to lowercase ASCII letters. + * + * Return value: passed-in @string pointer, with all the + * uppercase characters converted to lowercase in place, + * with semantics that exactly match g_ascii_tolower(). + */ +GString * +g_string_ascii_down (GString *string) +{ + gchar *s; + gint n; + + g_return_val_if_fail (string != NULL, NULL); + + n = string->len; + s = string->str; + + while (n) + { + *s = g_ascii_tolower (*s); + s++; + n--; + } + + return string; +} + +/** + * g_string_ascii_up: + * @string: a GString + * + * Converts all lowercase ASCII letters to uppercase ASCII letters. + * + * Return value: passed-in @string pointer, with all the + * lowercase characters converted to uppercase in place, + * with semantics that exactly match g_ascii_toupper(). + */ +GString * +g_string_ascii_up (GString *string) +{ + gchar *s; + gint n; + + g_return_val_if_fail (string != NULL, NULL); + + n = string->len; + s = string->str; + + while (n) + { + *s = g_ascii_toupper (*s); + s++; + n--; + } + + return string; +} + +/** + * g_string_down: + * @string: a #GString + * + * Converts a #GString to lowercase. + * + * Returns: the #GString + * + * Deprecated:2.2: This function uses the locale-specific + * tolower() function, which is almost never the right thing. + * Use g_string_ascii_down() or g_utf8_strdown() instead. + */ +GString * +g_string_down (GString *string) +{ + guchar *s; + glong n; + + g_return_val_if_fail (string != NULL, NULL); + + n = string->len; + s = (guchar *) string->str; + + while (n) + { + if (isupper (*s)) + *s = tolower (*s); + s++; + n--; + } + + return string; +} + +/** + * g_string_up: + * @string: a #GString + * + * Converts a #GString to uppercase. + * + * Return value: @string + * + * Deprecated:2.2: This function uses the locale-specific + * toupper() function, which is almost never the right thing. + * Use g_string_ascii_up() or g_utf8_strup() instead. + */ +GString * +g_string_up (GString *string) +{ + guchar *s; + glong n; + + g_return_val_if_fail (string != NULL, NULL); + + n = string->len; + s = (guchar *) string->str; + + while (n) + { + if (islower (*s)) + *s = toupper (*s); + s++; + n--; + } + + return string; +} + +/** + * g_string_append_vprintf: + * @string: a #GString + * @format: the string format. See the printf() documentation + * @args: the list of arguments to insert in the output + * + * Appends a formatted string onto the end of a #GString. + * This function is similar to g_string_append_printf() + * except that the arguments to the format string are passed + * as a va_list. + * + * Since: 2.14 + */ +void +g_string_append_vprintf (GString *string, + const gchar *format, + va_list args) +{ + gchar *buf; + gint len; + + g_return_if_fail (string != NULL); + g_return_if_fail (format != NULL); + + len = g_vasprintf (&buf, format, args); + + if (len >= 0) + { + g_string_maybe_expand (string, len); + memcpy (string->str + string->len, buf, len + 1); + string->len += len; + g_free (buf); + } +} + +/** + * g_string_vprintf: + * @string: a #GString + * @format: the string format. See the printf() documentation + * @args: the parameters to insert into the format string + * + * Writes a formatted string into a #GString. + * This function is similar to g_string_printf() except that + * the arguments to the format string are passed as a va_list. + * + * Since: 2.14 + */ +void +g_string_vprintf (GString *string, + const gchar *format, + va_list args) +{ + g_string_truncate (string, 0); + g_string_append_vprintf (string, format, args); +} + +/** + * g_string_sprintf: + * @string: a #GString + * @format: the string format. See the sprintf() documentation + * @...: the parameters to insert into the format string + * + * Writes a formatted string into a #GString. + * This is similar to the standard sprintf() function, + * except that the #GString buffer automatically expands + * to contain the results. The previous contents of the + * #GString are destroyed. + * + * Deprecated: This function has been renamed to g_string_printf(). + */ + +/** + * g_string_printf: + * @string: a #GString + * @format: the string format. See the printf() documentation + * @...: the parameters to insert into the format string + * + * Writes a formatted string into a #GString. + * This is similar to the standard sprintf() function, + * except that the #GString buffer automatically expands + * to contain the results. The previous contents of the + * #GString are destroyed. + */ +void +g_string_printf (GString *string, + const gchar *format, + ...) +{ + va_list args; + + g_string_truncate (string, 0); + + va_start (args, format); + g_string_append_vprintf (string, format, args); + va_end (args); +} + +/** + * g_string_sprintfa: + * @string: a #GString + * @format: the string format. See the sprintf() documentation + * @...: the parameters to insert into the format string + * + * Appends a formatted string onto the end of a #GString. + * This function is similar to g_string_sprintf() except that + * the text is appended to the #GString. + * + * Deprecated: This function has been renamed to g_string_append_printf() + */ + +/** + * g_string_append_printf: + * @string: a #GString + * @format: the string format. See the printf() documentation + * @...: the parameters to insert into the format string + * + * Appends a formatted string onto the end of a #GString. + * This function is similar to g_string_printf() except + * that the text is appended to the #GString. + */ +void +g_string_append_printf (GString *string, + const gchar *format, + ...) +{ + va_list args; + + va_start (args, format); + g_string_append_vprintf (string, format, args); + va_end (args); +} diff --git a/glib/glib/gstring.h b/glib/glib/gstring.h new file mode 100644 index 0000000..0797343 --- /dev/null +++ b/glib/glib/gstring.h @@ -0,0 +1,155 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_STRING_H__ +#define __G_STRING_H__ + +#include +#include +#include /* for G_CAN_INLINE */ + +G_BEGIN_DECLS + +typedef struct _GString GString; + +struct _GString +{ + gchar *str; + gsize len; + gsize allocated_len; +}; + +GString* g_string_new (const gchar *init); +GString* g_string_new_len (const gchar *init, + gssize len); +GString* g_string_sized_new (gsize dfl_size); +gchar* g_string_free (GString *string, + gboolean free_segment); +gboolean g_string_equal (const GString *v, + const GString *v2); +guint g_string_hash (const GString *str); +GString* g_string_assign (GString *string, + const gchar *rval); +GString* g_string_truncate (GString *string, + gsize len); +GString* g_string_set_size (GString *string, + gsize len); +GString* g_string_insert_len (GString *string, + gssize pos, + const gchar *val, + gssize len); +GString* g_string_append (GString *string, + const gchar *val); +GString* g_string_append_len (GString *string, + const gchar *val, + gssize len); +GString* g_string_append_c (GString *string, + gchar c); +GString* g_string_append_unichar (GString *string, + gunichar wc); +GString* g_string_prepend (GString *string, + const gchar *val); +GString* g_string_prepend_c (GString *string, + gchar c); +GString* g_string_prepend_unichar (GString *string, + gunichar wc); +GString* g_string_prepend_len (GString *string, + const gchar *val, + gssize len); +GString* g_string_insert (GString *string, + gssize pos, + const gchar *val); +GString* g_string_insert_c (GString *string, + gssize pos, + gchar c); +GString* g_string_insert_unichar (GString *string, + gssize pos, + gunichar wc); +GString* g_string_overwrite (GString *string, + gsize pos, + const gchar *val); +GString* g_string_overwrite_len (GString *string, + gsize pos, + const gchar *val, + gssize len); +GString* g_string_erase (GString *string, + gssize pos, + gssize len); +GString* g_string_ascii_down (GString *string); +GString* g_string_ascii_up (GString *string); +void g_string_vprintf (GString *string, + const gchar *format, + va_list args); +void g_string_printf (GString *string, + const gchar *format, + ...) G_GNUC_PRINTF (2, 3); +void g_string_append_vprintf (GString *string, + const gchar *format, + va_list args); +void g_string_append_printf (GString *string, + const gchar *format, + ...) G_GNUC_PRINTF (2, 3); +GString* g_string_append_uri_escaped (GString *string, + const gchar *unescaped, + const gchar *reserved_chars_allowed, + gboolean allow_utf8); + +/* -- optimize g_strig_append_c --- */ +#ifdef G_CAN_INLINE +static inline GString* +g_string_append_c_inline (GString *gstring, + gchar c) +{ + if (gstring->len + 1 < gstring->allocated_len) + { + gstring->str[gstring->len++] = c; + gstring->str[gstring->len] = 0; + } + else + g_string_insert_c (gstring, -1, c); + return gstring; +} +#define g_string_append_c(gstr,c) g_string_append_c_inline (gstr, c) +#endif /* G_CAN_INLINE */ + + +GLIB_DEPRECATED +GString *g_string_down (GString *string); +GLIB_DEPRECATED +GString *g_string_up (GString *string); + +#ifndef G_DISABLE_DEPRECATED +#define g_string_sprintf g_string_printf +#define g_string_sprintfa g_string_append_printf +#endif + +G_END_DECLS + +#endif /* __G_STRING_H__ */ diff --git a/glib/glib/gstringchunk.c b/glib/glib/gstringchunk.c new file mode 100644 index 0000000..1c40a48 --- /dev/null +++ b/glib/glib/gstringchunk.c @@ -0,0 +1,327 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include + +#include "gstringchunk.h" + +#include "ghash.h" +#include "gslist.h" +#include "gmessages.h" + +#include "gutils.h" + +/** + * SECTION:string_chunks + * @title: String Chunks + * @short_description: efficient storage of groups of strings + * + * String chunks are used to store groups of strings. Memory is + * allocated in blocks, and as strings are added to the #GStringChunk + * they are copied into the next free position in a block. When a block + * is full a new block is allocated. + * + * When storing a large number of strings, string chunks are more + * efficient than using g_strdup() since fewer calls to malloc() are + * needed, and less memory is wasted in memory allocation overheads. + * + * By adding strings with g_string_chunk_insert_const() it is also + * possible to remove duplicates. + * + * To create a new #GStringChunk use g_string_chunk_new(). + * + * To add strings to a #GStringChunk use g_string_chunk_insert(). + * + * To add strings to a #GStringChunk, but without duplicating strings + * which are already in the #GStringChunk, use + * g_string_chunk_insert_const(). + * + * To free the entire #GStringChunk use g_string_chunk_free(). It is + * not possible to free individual strings. + */ + +/** + * GStringChunk: + * + * An opaque data structure representing String Chunks. + * It should only be accessed by using the following functions. + */ +struct _GStringChunk +{ + GHashTable *const_table; + GSList *storage_list; + gsize storage_next; + gsize this_size; + gsize default_size; +}; + +#define MY_MAXSIZE ((gsize)-1) + +static inline gsize +nearest_power (gsize base, + gsize num) +{ + if (num > MY_MAXSIZE / 2) + { + return MY_MAXSIZE; + } + else + { + gsize n = base; + + while (n < num) + n <<= 1; + + return n; + } +} + +/** + * g_string_chunk_new: + * @size: the default size of the blocks of memory which are + * allocated to store the strings. If a particular string + * is larger than this default size, a larger block of + * memory will be allocated for it. + * + * Creates a new #GStringChunk. + * + * Returns: a new #GStringChunk + */ +GStringChunk * +g_string_chunk_new (gsize size) +{ + GStringChunk *new_chunk = g_new (GStringChunk, 1); + gsize actual_size = 1; + + actual_size = nearest_power (1, size); + + new_chunk->const_table = NULL; + new_chunk->storage_list = NULL; + new_chunk->storage_next = actual_size; + new_chunk->default_size = actual_size; + new_chunk->this_size = actual_size; + + return new_chunk; +} + +/** + * g_string_chunk_free: + * @chunk: a #GStringChunk + * + * Frees all memory allocated by the #GStringChunk. + * After calling g_string_chunk_free() it is not safe to + * access any of the strings which were contained within it. + */ +void +g_string_chunk_free (GStringChunk *chunk) +{ + GSList *tmp_list; + + g_return_if_fail (chunk != NULL); + + if (chunk->storage_list) + { + for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next) + g_free (tmp_list->data); + + g_slist_free (chunk->storage_list); + } + + if (chunk->const_table) + g_hash_table_destroy (chunk->const_table); + + g_free (chunk); +} + +/** + * g_string_chunk_clear: + * @chunk: a #GStringChunk + * + * Frees all strings contained within the #GStringChunk. + * After calling g_string_chunk_clear() it is not safe to + * access any of the strings which were contained within it. + * + * Since: 2.14 + */ +void +g_string_chunk_clear (GStringChunk *chunk) +{ + GSList *tmp_list; + + g_return_if_fail (chunk != NULL); + + if (chunk->storage_list) + { + for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next) + g_free (tmp_list->data); + + g_slist_free (chunk->storage_list); + + chunk->storage_list = NULL; + chunk->storage_next = chunk->default_size; + chunk->this_size = chunk->default_size; + } + + if (chunk->const_table) + g_hash_table_remove_all (chunk->const_table); +} + +/** + * g_string_chunk_insert: + * @chunk: a #GStringChunk + * @string: the string to add + * + * Adds a copy of @string to the #GStringChunk. + * It returns a pointer to the new copy of the string + * in the #GStringChunk. The characters in the string + * can be changed, if necessary, though you should not + * change anything after the end of the string. + * + * Unlike g_string_chunk_insert_const(), this function + * does not check for duplicates. Also strings added + * with g_string_chunk_insert() will not be searched + * by g_string_chunk_insert_const() when looking for + * duplicates. + * + * Returns: a pointer to the copy of @string within + * the #GStringChunk + */ +gchar* +g_string_chunk_insert (GStringChunk *chunk, + const gchar *string) +{ + g_return_val_if_fail (chunk != NULL, NULL); + + return g_string_chunk_insert_len (chunk, string, -1); +} + +/** + * g_string_chunk_insert_const: + * @chunk: a #GStringChunk + * @string: the string to add + * + * Adds a copy of @string to the #GStringChunk, unless the same + * string has already been added to the #GStringChunk with + * g_string_chunk_insert_const(). + * + * This function is useful if you need to copy a large number + * of strings but do not want to waste space storing duplicates. + * But you must remember that there may be several pointers to + * the same string, and so any changes made to the strings + * should be done very carefully. + * + * Note that g_string_chunk_insert_const() will not return a + * pointer to a string added with g_string_chunk_insert(), even + * if they do match. + * + * Returns: a pointer to the new or existing copy of @string + * within the #GStringChunk + */ +gchar* +g_string_chunk_insert_const (GStringChunk *chunk, + const gchar *string) +{ + char* lookup; + + g_return_val_if_fail (chunk != NULL, NULL); + + if (!chunk->const_table) + chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal); + + lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string); + + if (!lookup) + { + lookup = g_string_chunk_insert (chunk, string); + g_hash_table_insert (chunk->const_table, lookup, lookup); + } + + return lookup; +} + +/** + * g_string_chunk_insert_len: + * @chunk: a #GStringChunk + * @string: bytes to insert + * @len: number of bytes of @string to insert, or -1 to insert a + * nul-terminated string + * + * Adds a copy of the first @len bytes of @string to the #GStringChunk. + * The copy is nul-terminated. + * + * Since this function does not stop at nul bytes, it is the caller's + * responsibility to ensure that @string has at least @len addressable + * bytes. + * + * The characters in the returned string can be changed, if necessary, + * though you should not change anything after the end of the string. + * + * Return value: a pointer to the copy of @string within the #GStringChunk + * + * Since: 2.4 + */ +gchar* +g_string_chunk_insert_len (GStringChunk *chunk, + const gchar *string, + gssize len) +{ + gssize size; + gchar* pos; + + g_return_val_if_fail (chunk != NULL, NULL); + + if (len < 0) + size = strlen (string); + else + size = len; + + if ((chunk->storage_next + size + 1) > chunk->this_size) + { + gsize new_size = nearest_power (chunk->default_size, size + 1); + + chunk->storage_list = g_slist_prepend (chunk->storage_list, + g_new (gchar, new_size)); + + chunk->this_size = new_size; + chunk->storage_next = 0; + } + + pos = ((gchar *) chunk->storage_list->data) + chunk->storage_next; + + *(pos + size) = '\0'; + + memcpy (pos, string, size); + + chunk->storage_next += size + 1; + + return pos; +} diff --git a/glib/glib/gstringchunk.h b/glib/glib/gstringchunk.h new file mode 100644 index 0000000..5ab2e8a --- /dev/null +++ b/glib/glib/gstringchunk.h @@ -0,0 +1,53 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_STRINGCHUNK_H__ +#define __G_STRINGCHUNK_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GStringChunk GStringChunk; + +GStringChunk* g_string_chunk_new (gsize size); +void g_string_chunk_free (GStringChunk *chunk); +void g_string_chunk_clear (GStringChunk *chunk); +gchar* g_string_chunk_insert (GStringChunk *chunk, + const gchar *string); +gchar* g_string_chunk_insert_len (GStringChunk *chunk, + const gchar *string, + gssize len); +gchar* g_string_chunk_insert_const (GStringChunk *chunk, + const gchar *string); + +G_END_DECLS + +#endif /* __G_STRING_H__ */ diff --git a/glib/glib/gtester-report b/glib/glib/gtester-report new file mode 100755 index 0000000..0fcdd9a --- /dev/null +++ b/glib/glib/gtester-report @@ -0,0 +1,492 @@ +#! /usr/bin/env python +# GLib Testing Framework Utility -*- Mode: python; -*- +# Copyright (C) 2007 Imendio AB +# Authors: Tim Janik +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. +import datetime +import optparse +import sys, re, xml.dom.minidom + +try: + import subunit + from subunit import iso8601 + from testtools.content import Content, ContentType + mime_utf8 = ContentType('text', 'plain', {'charset': 'utf8'}) +except ImportError: + subunit = None + + +pkginstall_configvars = { + #@PKGINSTALL_CONFIGVARS_IN24LINES@ # configvars are substituted upon script installation +} + +# xml utilities +def find_child (node, child_name): + for child in node.childNodes: + if child.nodeName == child_name: + return child + return None +def list_children (node, child_name): + rlist = [] + for child in node.childNodes: + if child.nodeName == child_name: + rlist += [ child ] + return rlist +def find_node (node, name = None): + if not node or node.nodeName == name or not name: + return node + for child in node.childNodes: + c = find_node (child, name) + if c: + return c + return None +def node_as_text (node, name = None): + if name: + node = find_node (node, name) + txt = '' + if node: + if node.nodeValue: + txt += node.nodeValue + for child in node.childNodes: + txt += node_as_text (child) + return txt +def attribute_as_text (node, aname, node_name = None): + node = find_node (node, node_name) + if not node: + return '' + attr = node.attributes.get (aname, '') + if hasattr (attr, 'value'): + return attr.value + return '' + +# HTML utilities +def html_indent_string (n): + uncollapsible_space = '  ' # HTML won't compress alternating sequences of ' ' and ' ' + string = '' + for i in range (0, (n + 1) / 2): + string += uncollapsible_space + return string + +# TestBinary object, instantiated per test binary in the log file +class TestBinary: + def __init__ (self, name): + self.name = name + self.testcases = [] + self.duration = 0 + self.success_cases = 0 + self.skipped_cases = 0 + self.file = '???' + self.random_seed = '' + +# base class to handle processing/traversion of XML nodes +class TreeProcess: + def __init__ (self): + self.nest_level = 0 + def trampoline (self, node): + name = node.nodeName + if name == '#text': + self.handle_text (node) + else: + try: method = getattr (self, 'handle_' + re.sub ('[^a-zA-Z0-9]', '_', name)) + except: method = None + if method: + return method (node) + else: + return self.process_recursive (name, node) + def process_recursive (self, node_name, node): + self.process_children (node) + def process_children (self, node): + self.nest_level += 1 + for child in node.childNodes: + self.trampoline (child) + self.nest_level += 1 + +# test report reader, this class collects some statistics and merges duplicate test binary runs +class ReportReader (TreeProcess): + def __init__ (self): + TreeProcess.__init__ (self) + self.binary_names = [] + self.binaries = {} + self.last_binary = None + self.info = {} + def binary_list (self): + lst = [] + for name in self.binary_names: + lst += [ self.binaries[name] ] + return lst + def get_info (self): + return self.info + def handle_info (self, node): + dn = find_child (node, 'package') + self.info['package'] = node_as_text (dn) + dn = find_child (node, 'version') + self.info['version'] = node_as_text (dn) + dn = find_child (node, 'revision') + if dn is not None: + self.info['revision'] = node_as_text (dn) + def handle_testcase (self, node): + self.last_binary.testcases += [ node ] + result = attribute_as_text (node, 'result', 'status') + if result == 'success': + self.last_binary.success_cases += 1 + if bool (int (attribute_as_text (node, 'skipped') + '0')): + self.last_binary.skipped_cases += 1 + def handle_text (self, node): + pass + def handle_testbinary (self, node): + path = node.attributes.get ('path', None).value + if self.binaries.get (path, -1) == -1: + self.binaries[path] = TestBinary (path) + self.binary_names += [ path ] + self.last_binary = self.binaries[path] + dn = find_child (node, 'duration') + dur = node_as_text (dn) + try: dur = float (dur) + except: dur = 0 + if dur: + self.last_binary.duration += dur + bin = find_child (node, 'binary') + if bin: + self.last_binary.file = attribute_as_text (bin, 'file') + rseed = find_child (node, 'random-seed') + if rseed: + self.last_binary.random_seed = node_as_text (rseed) + self.process_children (node) + + +class ReportWriter(object): + """Base class for reporting.""" + + def __init__(self, binary_list): + self.binaries = binary_list + + def _error_text(self, node): + """Get a string representing the error children of node.""" + rlist = list_children(node, 'error') + txt = '' + for enode in rlist: + txt += node_as_text (enode) + if txt and txt[-1] != '\n': + txt += '\n' + return txt + + +class HTMLReportWriter(ReportWriter): + # Javascript/CSS snippet to toggle element visibility + cssjs = r''' + + + ''' + def __init__ (self, info, binary_list): + ReportWriter.__init__(self, binary_list) + self.info = info + self.bcounter = 0 + self.tcounter = 0 + self.total_tcounter = 0 + self.total_fcounter = 0 + self.total_duration = 0 + self.indent_depth = 0 + self.lastchar = '' + def oprint (self, message): + sys.stdout.write (message) + if message: + self.lastchar = message[-1] + def handle_info (self): + self.oprint ('

Package: %(package)s, version: %(version)s

\n' % self.info) + if self.info['revision']: + self.oprint ('
Report generated from: %(revision)s
\n' % self.info) + def handle_text (self, node): + self.oprint (node.nodeValue) + def handle_testcase (self, node, binary): + skipped = bool (int (attribute_as_text (node, 'skipped') + '0')) + if skipped: + return # skipped tests are uninteresting for HTML reports + path = attribute_as_text (node, 'path') + duration = node_as_text (node, 'duration') + result = attribute_as_text (node, 'result', 'status') + rcolor = { + 'success': 'bgcolor="lightgreen"', + 'failed': 'bgcolor="red"', + }.get (result, '') + if result != 'success': + duration = '-' # ignore bogus durations + self.oprint ('\n' % (self.bcounter, self.tcounter, result)) + self.oprint ('%s %s %s \n' % (html_indent_string (4), path, duration)) + perflist = list_children (node, 'performance') + if result != 'success': + txt = self._error_text(node) + txt = re.sub (r'"', r'\\"', txt) + txt = re.sub (r'\n', r'\\n', txt) + txt = re.sub (r'&', r'&', txt) + txt = re.sub (r'<', r'<', txt) + self.oprint ('\n' % (self.bcounter, self.tcounter, txt)) + self.oprint ('Details\n' % + ('TestResultWindow', binary.file, binary.random_seed, path, self.bcounter, self.tcounter)) + elif perflist: + presults = [] + for perf in perflist: + pmin = bool (int (attribute_as_text (perf, 'minimize'))) + pmax = bool (int (attribute_as_text (perf, 'maximize'))) + pval = float (attribute_as_text (perf, 'value')) + txt = node_as_text (perf) + txt = re.sub (r'&', r'&', txt) + txt = re.sub (r'<', r'>', txt) + txt = 'Performance(' + (pmin and 'minimized' or 'maximized') + '): ' + txt.strip() + '
\n' + txt = re.sub (r'"', r'\\"', txt) + txt = re.sub (r'\n', r'\\n', txt) + presults += [ (pval, txt) ] + presults.sort() + ptxt = ''.join ([e[1] for e in presults]) + self.oprint ('\n' % (self.bcounter, self.tcounter, ptxt)) + self.oprint ('Details\n' % + ('TestResultWindow', binary.file, binary.random_seed, path, self.bcounter, self.tcounter)) + else: + self.oprint ('-\n') + self.oprint ('%s\n' % (rcolor, result)) + self.oprint ('\n') + self.tcounter += 1 + self.total_tcounter += 1 + self.total_fcounter += result != 'success' + def handle_binary (self, binary): + self.tcounter = 1 + self.bcounter += 1 + self.total_duration += binary.duration + self.oprint ('%s%f \n' % (binary.name, binary.duration)) + erlink, oklink = ('', '') + real_cases = len (binary.testcases) - binary.skipped_cases + if binary.success_cases < real_cases: + erlink = 'href="javascript:toggle_display (\'ResultTable\', \'tr\', \'b%u_\', \'failed\')"' % self.bcounter + if binary.success_cases: + oklink = 'href="javascript:toggle_display (\'ResultTable\', \'tr\', \'b%u_\', \'success\')"' % self.bcounter + if real_cases != 0: + self.oprint ('ER\n' % erlink) + self.oprint ('OK\n' % oklink) + self.oprint ('\n') + perc = binary.success_cases * 100.0 / real_cases + pcolor = { + 100 : 'bgcolor="lightgreen"', + 0 : 'bgcolor="red"', + }.get (int (perc), 'bgcolor="yellow"') + self.oprint ('%.2f%%\n' % (pcolor, perc)) + self.oprint ('\n') + else: + self.oprint ('Empty\n') + self.oprint ('\n') + self.oprint ('\n') + for tc in binary.testcases: + self.handle_testcase (tc, binary) + def handle_totals (self): + self.oprint ('') + self.oprint ('Totals: %u Binaries, %u Tests, %u Failed, %u Succeeded' % + (self.bcounter, self.total_tcounter, self.total_fcounter, self.total_tcounter - self.total_fcounter)) + self.oprint ('%f\n' % self.total_duration) + self.oprint ('-\n') + if self.total_tcounter != 0: + perc = (self.total_tcounter - self.total_fcounter) * 100.0 / self.total_tcounter + else: + perc = 0.0 + pcolor = { + 100 : 'bgcolor="lightgreen"', + 0 : 'bgcolor="red"', + }.get (int (perc), 'bgcolor="yellow"') + self.oprint ('%.2f%%\n' % (pcolor, perc)) + self.oprint ('\n') + def printout (self): + self.oprint ('\n') + self.oprint ('GTester Unit Test Report\n') + self.oprint (self.cssjs) + self.oprint ('\n') + self.oprint ('\n') + self.oprint ('

GTester Unit Test Report

\n') + self.handle_info () + self.oprint ('\n\n') + self.oprint ('\n') + self.oprint ('\n') + self.oprint ('\n') + self.oprint ('\n') + self.oprint ('\n') + for tb in self.binaries: + self.handle_binary (tb) + self.handle_totals() + self.oprint ('
Program / Testcase Duration (sec)ViewResult
\n') + self.oprint ('\n') + self.oprint ('\n') + + +class SubunitWriter(ReportWriter): + """Reporter to output a subunit stream.""" + + def printout(self): + reporter = subunit.TestProtocolClient(sys.stdout) + for binary in self.binaries: + for tc in binary.testcases: + test = GTestCase(tc, binary) + test.run(reporter) + + +class GTestCase(object): + """A representation of a gtester test result as a pyunit TestCase.""" + + def __init__(self, case, binary): + """Create a GTestCase for case `case` from binary program `binary`.""" + self._case = case + self._binary = binary + # the name of the case - e.g. /dbusmenu/glib/objects/menuitem/props_boolstr + self._path = attribute_as_text(self._case, 'path') + + def id(self): + """What test is this? Returns the gtester path for the testcase.""" + return self._path + + def _get_details(self): + """Calculate a details dict for the test - attachments etc.""" + details = {} + result = attribute_as_text(self._case, 'result', 'status') + details['filename'] = Content(mime_utf8, lambda:[self._binary.file]) + details['random_seed'] = Content(mime_utf8, + lambda:[self._binary.random_seed]) + if self._get_outcome() == 'addFailure': + # Extract the error details. Skips have no details because its not + # skip like unittest does, instead the runner just bypasses N test. + txt = self._error_text(self._case) + details['error'] = Content(mime_utf8, lambda:[txt]) + if self._get_outcome() == 'addSuccess': + # Sucessful tests may have performance metrics. + perflist = list_children(self._case, 'performance') + if perflist: + presults = [] + for perf in perflist: + pmin = bool (int (attribute_as_text (perf, 'minimize'))) + pmax = bool (int (attribute_as_text (perf, 'maximize'))) + pval = float (attribute_as_text (perf, 'value')) + txt = node_as_text (perf) + txt = 'Performance(' + (pmin and 'minimized' or 'maximized' + ) + '): ' + txt.strip() + '\n' + presults += [(pval, txt)] + presults.sort() + perf_details = [e[1] for e in presults] + details['performance'] = Content(mime_utf8, lambda:perf_details) + return details + + def _get_outcome(self): + if int(attribute_as_text(self._case, 'skipped') + '0'): + return 'addSkip' + outcome = attribute_as_text(self._case, 'result', 'status') + if outcome == 'success': + return 'addSuccess' + else: + return 'addFailure' + + def run(self, result): + time = datetime.datetime.utcnow().replace(tzinfo=iso8601.Utc()) + result.time(time) + result.startTest(self) + try: + outcome = self._get_outcome() + details = self._get_details() + # Only provide a duration IFF outcome == 'addSuccess' - the main + # parser claims bogus results otherwise: in that case emit time as + # zero perhaps. + if outcome == 'addSuccess': + duration = float(node_as_text(self._case, 'duration')) + duration = duration * 1000000 + timedelta = datetime.timedelta(0, 0, duration) + time = time + timedelta + result.time(time) + getattr(result, outcome)(self, details=details) + finally: + result.stopTest(self) + + + +# main program handling +def parse_opts(): + """Parse program options. + + :return: An options object and the program arguments. + """ + parser = optparse.OptionParser() + parser.version = pkginstall_configvars.get ('glib-version', '0.0-uninstalled') + parser.usage = "%prog [OPTIONS] " + parser.description = "Generate HTML reports from the XML log files generated by gtester." + parser.epilog = "gtester-report (GLib utils) version %s."% (parser.version,) + parser.add_option("-v", "--version", action="store_true", dest="version", default=False, + help="Show program version.") + parser.add_option("-s", "--subunit", action="store_true", dest="subunit", default=False, + help="Output subunit [See https://launchpad.net/subunit/" + " Needs python-subunit]") + options, files = parser.parse_args() + if options.version: + print parser.epilog + return None, None + if len(files) != 1: + parser.error("Must supply a log file to parse.") + if options.subunit and subunit is None: + parser.error("python-subunit is not installed.") + return options, files + + +def main(): + options, files = parse_opts() + if options is None: + return 0 + xd = xml.dom.minidom.parse (files[0]) + rr = ReportReader() + rr.trampoline (xd) + if not options.subunit: + HTMLReportWriter(rr.get_info(), rr.binary_list()).printout() + else: + SubunitWriter(rr.get_info(), rr.binary_list()).printout() + + +if __name__ == '__main__': + main() diff --git a/glib/glib/gtester.c b/glib/glib/gtester.c new file mode 100644 index 0000000..279f6f2 --- /dev/null +++ b/glib/glib/gtester.c @@ -0,0 +1,729 @@ +/* GLib testing framework runner + * Copyright (C) 2007 Sven Herzberg + * Copyright (C) 2007 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* the read buffer size in bytes */ +#define READ_BUFFER_SIZE 4096 + +/* --- prototypes --- */ +static int main_selftest (int argc, + char **argv); +static void parse_args (gint *argc_p, + gchar ***argv_p); + +/* --- variables --- */ +static GIOChannel *ioc_report = NULL; +static gboolean gtester_quiet = FALSE; +static gboolean gtester_verbose = FALSE; +static gboolean gtester_list_tests = FALSE; +static gboolean gtester_selftest = FALSE; +static gboolean subtest_running = FALSE; +static gint subtest_exitstatus = 0; +static gboolean subtest_io_pending = FALSE; +static gboolean subtest_quiet = TRUE; +static gboolean subtest_verbose = FALSE; +static gboolean subtest_mode_fatal = TRUE; +static gboolean subtest_mode_perf = FALSE; +static gboolean subtest_mode_quick = TRUE; +static gboolean subtest_mode_undefined = TRUE; +static const gchar *subtest_seedstr = NULL; +static gchar *subtest_last_seed = NULL; +static GSList *subtest_paths = NULL; +static GSList *skipped_paths = NULL; +static GSList *subtest_args = NULL; +static gboolean testcase_open = FALSE; +static guint testcase_count = 0; +static guint testcase_fail_count = 0; +static const gchar *output_filename = NULL; +static guint log_indent = 0; +static gint log_fd = -1; + +/* --- functions --- */ +static const char* +sindent (guint n) +{ + static const char spaces[] = " "; + int l = sizeof (spaces) - 1; + n = MIN (n, l); + return spaces + l - n; +} + +static void G_GNUC_PRINTF (1, 2) +test_log_printfe (const char *format, + ...) +{ + char *result; + int r; + va_list args; + va_start (args, format); + result = g_markup_vprintf_escaped (format, args); + va_end (args); + do + r = write (log_fd, result, strlen (result)); + while (r < 0 && errno == EINTR); + g_free (result); +} + +static void +terminate (void) +{ + kill (getpid(), SIGTERM); + abort(); +} + +static void +testcase_close (long double duration, + gint exit_status, + guint n_forks) +{ + g_return_if_fail (testcase_open > 0); + test_log_printfe ("%s%.6Lf\n", sindent (log_indent), duration); + test_log_printfe ("%s\n", + sindent (log_indent), exit_status, n_forks, + exit_status ? "failed" : "success"); + log_indent -= 2; + test_log_printfe ("%s\n", sindent (log_indent)); + testcase_open--; + if (gtester_verbose) + g_print ("%s\n", exit_status ? "FAIL" : "OK"); + if (exit_status && subtest_last_seed) + g_print ("GTester: last random seed: %s\n", subtest_last_seed); + if (exit_status) + testcase_fail_count += 1; + if (subtest_mode_fatal && exit_status) + terminate(); +} + +static void +test_log_msg (GTestLogMsg *msg) +{ + switch (msg->log_type) + { + guint i; + gchar **strv; + case G_TEST_LOG_NONE: + break; + case G_TEST_LOG_ERROR: + strv = g_strsplit (msg->strings[0], "\n", -1); + for (i = 0; strv[i]; i++) + test_log_printfe ("%s%s\n", sindent (log_indent), strv[i]); + g_strfreev (strv); + break; + case G_TEST_LOG_START_BINARY: + test_log_printfe ("%s\n", sindent (log_indent), msg->strings[0]); + subtest_last_seed = g_strdup (msg->strings[1]); + test_log_printfe ("%s%s\n", sindent (log_indent), subtest_last_seed); + break; + case G_TEST_LOG_LIST_CASE: + g_print ("%s\n", msg->strings[0]); + break; + case G_TEST_LOG_START_CASE: + testcase_count++; + if (gtester_verbose) + { + gchar *sc = g_strconcat (msg->strings[0], ":", NULL); + gchar *sleft = g_strdup_printf ("%-68s", sc); + g_free (sc); + g_print ("%70s ", sleft); + g_free (sleft); + } + g_return_if_fail (testcase_open == 0); + testcase_open++; + test_log_printfe ("%s\n", sindent (log_indent), msg->strings[0]); + log_indent += 2; + break; + case G_TEST_LOG_SKIP_CASE: + if (FALSE && gtester_verbose) /* enable to debug test case skipping logic */ + { + gchar *sc = g_strconcat (msg->strings[0], ":", NULL); + gchar *sleft = g_strdup_printf ("%-68s", sc); + g_free (sc); + g_print ("%70s SKIPPED\n", sleft); + g_free (sleft); + } + test_log_printfe ("%s\n", sindent (log_indent), msg->strings[0]); + break; + case G_TEST_LOG_STOP_CASE: + testcase_close (msg->nums[2], (int) msg->nums[0], (int) msg->nums[1]); + break; + case G_TEST_LOG_MIN_RESULT: + case G_TEST_LOG_MAX_RESULT: + test_log_printfe ("%s\n", + sindent (log_indent), msg->log_type == G_TEST_LOG_MIN_RESULT, msg->log_type == G_TEST_LOG_MAX_RESULT, msg->nums[0]); + test_log_printfe ("%s%s\n", sindent (log_indent + 2), msg->strings[0]); + test_log_printfe ("%s\n", sindent (log_indent)); + break; + case G_TEST_LOG_MESSAGE: + test_log_printfe ("%s\n%s\n%s\n", sindent (log_indent), msg->strings[0], sindent (log_indent)); + break; + } +} + +static gboolean +child_report_cb (GIOChannel *source, + GIOCondition condition, + gpointer data) +{ + GTestLogBuffer *tlb = data; + GIOStatus status = G_IO_STATUS_NORMAL; + gboolean first_read_eof = FALSE, first_read = TRUE; + gsize length = 0; + do + { + guint8 buffer[READ_BUFFER_SIZE]; + GError *error = NULL; + status = g_io_channel_read_chars (source, (gchar*) buffer, sizeof (buffer), &length, &error); + if (first_read && (condition & G_IO_IN)) + { + /* on some unixes (MacOS) we need to detect non-blocking fd EOF + * by an IO_IN select/poll followed by read()==0. + */ + first_read_eof = length == 0; + } + first_read = FALSE; + if (length) + { + GTestLogMsg *msg; + g_test_log_buffer_push (tlb, length, buffer); + do + { + msg = g_test_log_buffer_pop (tlb); + if (msg) + { + test_log_msg (msg); + g_test_log_msg_free (msg); + } + } + while (msg); + } + g_clear_error (&error); + /* ignore the io channel status, which will report intermediate EOFs for non blocking fds */ + (void) status; + } + while (length > 0); + /* g_print ("LASTIOSTATE: first_read_eof=%d condition=%d\n", first_read_eof, condition); */ + if (first_read_eof || (condition & (G_IO_ERR | G_IO_HUP))) + { + /* if there's no data to read and select() reports an error or hangup, + * the fd must have been closed remotely + */ + subtest_io_pending = FALSE; + return FALSE; + } + return TRUE; /* keep polling */ +} + +static void +child_watch_cb (GPid pid, + gint status, + gpointer data) +{ + g_spawn_close_pid (pid); + if (WIFEXITED (status)) /* normal exit */ + subtest_exitstatus = WEXITSTATUS (status); + else /* signal or core dump, etc */ + subtest_exitstatus = 0xffffffff; + subtest_running = FALSE; +} + +static gchar* +queue_gfree (GSList **slistp, + gchar *string) +{ + *slistp = g_slist_prepend (*slistp, string); + return string; +} + +static void +unset_cloexec_fdp (gpointer fdp_data) +{ + int r, *fdp = fdp_data; + do + r = fcntl (*fdp, F_SETFD, 0 /* FD_CLOEXEC */); + while (r < 0 && errno == EINTR); +} + +static gboolean +launch_test_binary (const char *binary, + guint skip_tests) +{ + GTestLogBuffer *tlb; + GSList *slist, *free_list = NULL; + GError *error = NULL; + int argc = 0; + const gchar **argv; + GPid pid = 0; + gint report_pipe[2] = { -1, -1 }; + guint child_report_cb_id = 0; + gboolean loop_pending; + gint i = 0; + + if (pipe (report_pipe) < 0) + { + if (subtest_mode_fatal) + g_error ("Failed to open pipe for test binary: %s: %s", binary, g_strerror (errno)); + else + g_warning ("Failed to open pipe for test binary: %s: %s", binary, g_strerror (errno)); + return FALSE; + } + + /* setup argc */ + for (slist = subtest_args; slist; slist = slist->next) + argc++; + /* argc++; */ + if (subtest_quiet) + argc++; + if (subtest_verbose) + argc++; + if (!subtest_mode_fatal) + argc++; + if (subtest_mode_quick) + argc++; + else + argc++; + if (subtest_mode_perf) + argc++; + if (!subtest_mode_undefined) + argc++; + if (gtester_list_tests) + argc++; + if (subtest_seedstr) + argc++; + argc++; + if (skip_tests) + argc++; + for (slist = subtest_paths; slist; slist = slist->next) + argc++; + for (slist = skipped_paths; slist; slist = slist->next) + argc++; + + /* setup argv */ + argv = g_malloc ((argc + 2) * sizeof(gchar *)); + argv[i++] = binary; + for (slist = subtest_args; slist; slist = slist->next) + argv[i++] = (gchar*) slist->data; + /* argv[i++] = "--debug-log"; */ + if (subtest_quiet) + argv[i++] = "--quiet"; + if (subtest_verbose) + argv[i++] = "--verbose"; + if (!subtest_mode_fatal) + argv[i++] = "--keep-going"; + if (subtest_mode_quick) + argv[i++] = "-m=quick"; + else + argv[i++] = "-m=slow"; + if (subtest_mode_perf) + argv[i++] = "-m=perf"; + if (!subtest_mode_undefined) + argv[i++] = "-m=no-undefined"; + if (gtester_list_tests) + argv[i++] = "-l"; + if (subtest_seedstr) + argv[i++] = queue_gfree (&free_list, g_strdup_printf ("--seed=%s", subtest_seedstr)); + argv[i++] = queue_gfree (&free_list, g_strdup_printf ("--GTestLogFD=%u", report_pipe[1])); + if (skip_tests) + argv[i++] = queue_gfree (&free_list, g_strdup_printf ("--GTestSkipCount=%u", skip_tests)); + for (slist = subtest_paths; slist; slist = slist->next) + argv[i++] = queue_gfree (&free_list, g_strdup_printf ("-p=%s", (gchar*) slist->data)); + for (slist = skipped_paths; slist; slist = slist->next) + argv[i++] = queue_gfree (&free_list, g_strdup_printf ("-s=%s", (gchar*) slist->data)); + argv[i++] = NULL; + + g_spawn_async_with_pipes (NULL, /* g_get_current_dir() */ + (gchar**) argv, + NULL, /* envp */ + G_SPAWN_DO_NOT_REAP_CHILD, /* G_SPAWN_SEARCH_PATH */ + unset_cloexec_fdp, &report_pipe[1], /* pre-exec callback */ + &pid, + NULL, /* standard_input */ + NULL, /* standard_output */ + NULL, /* standard_error */ + &error); + g_slist_foreach (free_list, (void(*)(void*,void*)) g_free, NULL); + g_slist_free (free_list); + free_list = NULL; + close (report_pipe[1]); + + if (!gtester_quiet) + g_print ("(pid=%lu)\n", (unsigned long) pid); + + if (error) + { + close (report_pipe[0]); + if (subtest_mode_fatal) + g_error ("Failed to execute test binary: %s: %s", argv[0], error->message); + else + g_warning ("Failed to execute test binary: %s: %s", argv[0], error->message); + g_clear_error (&error); + g_free (argv); + return FALSE; + } + g_free (argv); + + subtest_running = TRUE; + subtest_io_pending = TRUE; + tlb = g_test_log_buffer_new(); + if (report_pipe[0] >= 0) + { + ioc_report = g_io_channel_unix_new (report_pipe[0]); + g_io_channel_set_flags (ioc_report, G_IO_FLAG_NONBLOCK, NULL); + g_io_channel_set_encoding (ioc_report, NULL, NULL); + g_io_channel_set_buffered (ioc_report, FALSE); + child_report_cb_id = g_io_add_watch_full (ioc_report, G_PRIORITY_DEFAULT - 1, G_IO_IN | G_IO_ERR | G_IO_HUP, child_report_cb, tlb, NULL); + g_io_channel_unref (ioc_report); + } + g_child_watch_add_full (G_PRIORITY_DEFAULT + 1, pid, child_watch_cb, NULL, NULL); + + loop_pending = g_main_context_pending (NULL); + while (subtest_running || /* FALSE once child exits */ + subtest_io_pending || /* FALSE once ioc_report closes */ + loop_pending) /* TRUE while idler, etc are running */ + { + /* g_print ("LOOPSTATE: subtest_running=%d subtest_io_pending=%d\n", subtest_running, subtest_io_pending); */ + /* check for unexpected hangs that are not signalled on report_pipe */ + if (!subtest_running && /* child exited */ + subtest_io_pending && /* no EOF detected on report_pipe */ + !loop_pending) /* no IO events pending however */ + break; + g_main_context_iteration (NULL, TRUE); + loop_pending = g_main_context_pending (NULL); + } + + g_source_remove (child_report_cb_id); + close (report_pipe[0]); + g_test_log_buffer_free (tlb); + + return TRUE; +} + +static void +launch_test (const char *binary) +{ + gboolean success = TRUE; + GTimer *btimer = g_timer_new(); + gboolean need_restart; + + testcase_count = 0; + if (!gtester_quiet) + g_print ("TEST: %s... ", binary); + + retry: + test_log_printfe ("%s\n", sindent (log_indent), binary); + log_indent += 2; + g_timer_start (btimer); + subtest_exitstatus = 0; + success &= launch_test_binary (binary, testcase_count); + success &= subtest_exitstatus == 0; + need_restart = testcase_open != 0; + if (testcase_open) + testcase_close (0, -256, 0); + g_timer_stop (btimer); + test_log_printfe ("%s%.6f\n", sindent (log_indent), g_timer_elapsed (btimer, NULL)); + log_indent -= 2; + test_log_printfe ("%s\n", sindent (log_indent)); + g_free (subtest_last_seed); + subtest_last_seed = NULL; + if (need_restart) + { + /* restart test binary, skipping processed test cases */ + goto retry; + } + + /* count the inability to run a test as a failure */ + if (!success && testcase_count == 0) + testcase_fail_count++; + + if (!gtester_quiet) + g_print ("%s: %s\n", !success ? "FAIL" : "PASS", binary); + g_timer_destroy (btimer); + if (subtest_mode_fatal && !success) + terminate(); +} + +static void +usage (gboolean just_version) +{ + if (just_version) + { + g_print ("gtester version %d.%d.%d\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); + return; + } + g_print ("Usage: gtester [OPTIONS] testprogram...\n"); + /* 12345678901234567890123456789012345678901234567890123456789012345678901234567890 */ + g_print ("Options:\n"); + g_print (" -h, --help show this help message\n"); + g_print (" -v, --version print version informations\n"); + g_print (" --g-fatal-warnings make warnings fatal (abort)\n"); + g_print (" -k, --keep-going continue running after tests failed\n"); + g_print (" -l list paths of available test cases\n"); + g_print (" -m=perf, -m=slow, -m=quick -m=thorough\n"); + g_print (" run test cases in mode perf, slow/thorough or quick (default)\n"); + g_print (" -m=no-undefined don't run test cases that provoke assertions\n"); + g_print (" -p=TESTPATH only start test cases matching TESTPATH\n"); + g_print (" -s=TESTPATH skip test cases matching TESTPATH\n"); + g_print (" --seed=SEEDSTRING start all tests with random number seed SEEDSTRING\n"); + g_print (" -o=LOGFILE write the test log to LOGFILE\n"); + g_print (" -q, --quiet suppress per test binary output\n"); + g_print (" --verbose report success per testcase\n"); +} + +static void +parse_args (gint *argc_p, + gchar ***argv_p) +{ + guint argc = *argc_p; + gchar **argv = *argv_p; + guint i, e; + /* parse known args */ + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "--g-fatal-warnings") == 0) + { + GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK); + fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); + g_log_set_always_fatal (fatal_mask); + argv[i] = NULL; + } + else if (strcmp (argv[i], "--gtester-selftest") == 0) + { + gtester_selftest = TRUE; + argv[i] = NULL; + break; /* stop parsing regular gtester arguments */ + } + else if (strcmp (argv[i], "-h") == 0 || strcmp (argv[i], "--help") == 0) + { + usage (FALSE); + exit (0); + argv[i] = NULL; + } + else if (strcmp (argv[i], "-v") == 0 || strcmp (argv[i], "--version") == 0) + { + usage (TRUE); + exit (0); + argv[i] = NULL; + } + else if (strcmp (argv[i], "--keep-going") == 0 || + strcmp (argv[i], "-k") == 0) + { + subtest_mode_fatal = FALSE; + argv[i] = NULL; + } + else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0) + { + gchar *equal = argv[i] + 2; + if (*equal == '=') + subtest_paths = g_slist_prepend (subtest_paths, equal + 1); + else if (i + 1 < argc) + { + argv[i++] = NULL; + subtest_paths = g_slist_prepend (subtest_paths, argv[i]); + } + argv[i] = NULL; + } + else if (strcmp ("-s", argv[i]) == 0 || strncmp ("-s=", argv[i], 3) == 0) + { + gchar *equal = argv[i] + 2; + if (*equal == '=') + skipped_paths = g_slist_prepend (skipped_paths, equal + 1); + else if (i + 1 < argc) + { + argv[i++] = NULL; + skipped_paths = g_slist_prepend (skipped_paths, argv[i]); + } + argv[i] = NULL; + } + else if (strcmp ("--test-arg", argv[i]) == 0 || strncmp ("--test-arg=", argv[i], 11) == 0) + { + gchar *equal = argv[i] + 10; + if (*equal == '=') + subtest_args = g_slist_prepend (subtest_args, equal + 1); + else if (i + 1 < argc) + { + argv[i++] = NULL; + subtest_args = g_slist_prepend (subtest_args, argv[i]); + } + argv[i] = NULL; + } + else if (strcmp ("-o", argv[i]) == 0 || strncmp ("-o=", argv[i], 3) == 0) + { + gchar *equal = argv[i] + 2; + if (*equal == '=') + output_filename = equal + 1; + else if (i + 1 < argc) + { + argv[i++] = NULL; + output_filename = argv[i]; + } + argv[i] = NULL; + } + else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0) + { + gchar *equal = argv[i] + 2; + const gchar *mode = ""; + if (*equal == '=') + mode = equal + 1; + else if (i + 1 < argc) + { + argv[i++] = NULL; + mode = argv[i]; + } + if (strcmp (mode, "perf") == 0) + subtest_mode_perf = TRUE; + else if (strcmp (mode, "slow") == 0 || strcmp (mode, "thorough") == 0) + subtest_mode_quick = FALSE; + else if (strcmp (mode, "quick") == 0) + { + subtest_mode_quick = TRUE; + subtest_mode_perf = FALSE; + } + else if (strcmp (mode, "undefined") == 0) + subtest_mode_undefined = TRUE; + else if (strcmp (mode, "no-undefined") == 0) + subtest_mode_undefined = FALSE; + else + g_error ("unknown test mode: -m %s", mode); + argv[i] = NULL; + } + else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0) + { + gtester_quiet = TRUE; + gtester_verbose = FALSE; + argv[i] = NULL; + } + else if (strcmp ("--verbose", argv[i]) == 0) + { + gtester_quiet = FALSE; + gtester_verbose = TRUE; + argv[i] = NULL; + } + else if (strcmp ("-l", argv[i]) == 0) + { + gtester_list_tests = TRUE; + argv[i] = NULL; + } + else if (strcmp ("--seed", argv[i]) == 0 || strncmp ("--seed=", argv[i], 7) == 0) + { + gchar *equal = argv[i] + 6; + if (*equal == '=') + subtest_seedstr = equal + 1; + else if (i + 1 < argc) + { + argv[i++] = NULL; + subtest_seedstr = argv[i]; + } + argv[i] = NULL; + } + } + /* collapse argv */ + e = 1; + for (i = 1; i < argc; i++) + if (argv[i]) + { + argv[e++] = argv[i]; + if (i >= e) + argv[i] = NULL; + } + *argc_p = e; +} + +int +main (int argc, + char **argv) +{ + guint ui; + + g_set_prgname (argv[0]); + parse_args (&argc, &argv); + if (gtester_selftest) + return main_selftest (argc, argv); + + if (argc <= 1) + { + usage (FALSE); + return 1; + } + + if (output_filename) + { + log_fd = g_open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (log_fd < 0) + g_error ("Failed to open log file '%s': %s", output_filename, g_strerror (errno)); + } + + test_log_printfe ("\n"); + test_log_printfe ("%s\n", sindent (log_indent)); + log_indent += 2; + for (ui = 1; ui < argc; ui++) + { + const char *binary = argv[ui]; + launch_test (binary); + /* we only get here on success or if !subtest_mode_fatal */ + } + log_indent -= 2; + test_log_printfe ("%s\n", sindent (log_indent)); + + close (log_fd); + + return testcase_fail_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE; +} + +static void +fixture_setup (guint *fix, + gconstpointer test_data) +{ + g_assert_cmphex (*fix, ==, 0); + *fix = 0xdeadbeef; +} +static void +fixture_test (guint *fix, + gconstpointer test_data) +{ + g_assert_cmphex (*fix, ==, 0xdeadbeef); + g_test_message ("This is a test message API test message."); + g_test_bug_base ("http://www.example.com/bugtracker/"); + g_test_bug ("123"); + g_test_bug_base ("http://www.example.com/bugtracker?bugnum=%s;cmd=showbug"); + g_test_bug ("456"); +} +static void +fixture_teardown (guint *fix, + gconstpointer test_data) +{ + g_assert_cmphex (*fix, ==, 0xdeadbeef); +} + +static int +main_selftest (int argc, + char **argv) +{ + /* gtester main() for --gtester-selftest invocations */ + g_test_init (&argc, &argv, NULL); + g_test_add ("/gtester/fixture-test", guint, NULL, fixture_setup, fixture_test, fixture_teardown); + return g_test_run(); +} diff --git a/glib/glib/gtestutils.c b/glib/glib/gtestutils.c new file mode 100644 index 0000000..e9d7f84 --- /dev/null +++ b/glib/glib/gtestutils.c @@ -0,0 +1,2573 @@ +/* GLib testing utilities + * Copyright (C) 2007 Imendio AB + * Authors: Tim Janik, Sven Herzberg + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include "gtestutils.h" +#include "gfileutils.h" + +#include +#ifdef G_OS_UNIX +#include +#include +#include +#endif +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef G_OS_WIN32 +#include +#endif +#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif /* HAVE_SYS_SELECT_H */ + +#include "gmain.h" +#include "gpattern.h" +#include "grand.h" +#include "gstrfuncs.h" +#include "gtimer.h" +#include "gslice.h" + + +/** + * SECTION:testing + * @title: Testing + * @short_description: a test framework + * @see_also: gtester, + * gtester-report + * + * GLib provides a framework for writing and maintaining unit tests + * in parallel to the code they are testing. The API is designed according + * to established concepts found in the other test frameworks (JUnit, NUnit, + * RUnit), which in turn is based on smalltalk unit testing concepts. + * + * + * + * Test case + * Tests (test methods) are grouped together with their + * fixture into test cases. + * + * + * Fixture + * A test fixture consists of fixture data and setup and + * teardown methods to establish the environment for the test + * functions. We use fresh fixtures, i.e. fixtures are newly set + * up and torn down around each test invocation to avoid dependencies + * between tests. + * + * + * Test suite + * Test cases can be grouped into test suites, to allow + * subsets of the available tests to be run. Test suites can be + * grouped into other test suites as well. + * + * + * The API is designed to handle creation and registration of test suites + * and test cases implicitly. A simple call like + * |[ + * g_test_add_func ("/misc/assertions", test_assertions); + * ]| + * creates a test suite called "misc" with a single test case named + * "assertions", which consists of running the test_assertions function. + * + * In addition to the traditional g_assert(), the test framework provides + * an extended set of assertions for string and numerical comparisons: + * g_assert_cmpfloat(), g_assert_cmpint(), g_assert_cmpuint(), + * g_assert_cmphex(), g_assert_cmpstr(). The advantage of these variants + * over plain g_assert() is that the assertion messages can be more + * elaborate, and include the values of the compared entities. + * + * GLib ships with two utilities called gtester and gtester-report to + * facilitate running tests and producing nicely formatted test reports. + */ + +/** + * g_test_quick: + * + * Returns %TRUE if tests are run in quick mode. + * Exactly one of g_test_quick() and g_test_slow() is active in any run; + * there is no "medium speed". + * + * Returns: %TRUE if in quick mode + */ + +/** + * g_test_slow: + * + * Returns %TRUE if tests are run in slow mode. + * Exactly one of g_test_quick() and g_test_slow() is active in any run; + * there is no "medium speed". + * + * Returns: the opposite of g_test_quick() + */ + +/** + * g_test_thorough: + * + * Returns %TRUE if tests are run in thorough mode, equivalent to + * g_test_slow(). + * + * Returns: the same thing as g_test_slow() + */ + +/** + * g_test_perf: + * + * Returns %TRUE if tests are run in performance mode. + * + * Returns: %TRUE if in performance mode + */ + +/** + * g_test_undefined: + * + * Returns %TRUE if tests may provoke assertions and other formally-undefined + * behaviour under g_test_trap_fork(), to verify that appropriate warnings + * are given. It can be useful to turn this off if running tests under + * valgrind. + * + * Returns: %TRUE if tests may provoke programming errors + */ + +/** + * g_test_verbose: + * + * Returns %TRUE if tests are run in verbose mode. + * The default is neither g_test_verbose() nor g_test_quiet(). + * + * Returns: %TRUE if in verbose mode + */ + +/** + * g_test_quiet: + * + * Returns %TRUE if tests are run in quiet mode. + * The default is neither g_test_verbose() nor g_test_quiet(). + * + * Returns: %TRUE if in quiet mode + */ + +/** + * g_test_queue_unref: + * @gobject: the object to unref + * + * Enqueue an object to be released with g_object_unref() during + * the next teardown phase. This is equivalent to calling + * g_test_queue_destroy() with a destroy callback of g_object_unref(). + * + * Since: 2.16 + */ + +/** + * GTestTrapFlags: + * @G_TEST_TRAP_SILENCE_STDOUT: Redirect stdout of the test child to + * /dev/null so it cannot be observed on the + * console during test runs. The actual output is still captured + * though to allow later tests with g_test_trap_assert_stdout(). + * @G_TEST_TRAP_SILENCE_STDERR: Redirect stderr of the test child to + * /dev/null so it cannot be observed on the + * console during test runs. The actual output is still captured + * though to allow later tests with g_test_trap_assert_stderr(). + * @G_TEST_TRAP_INHERIT_STDIN: If this flag is given, stdin of the + * forked child process is shared with stdin of its parent process. + * It is redirected to /dev/null otherwise. + * + * Test traps are guards around forked tests. + * These flags determine what traps to set. + */ + +/** + * g_test_trap_assert_passed: + * + * Assert that the last forked test passed. + * See g_test_trap_fork(). + * + * Since: 2.16 + */ + +/** + * g_test_trap_assert_failed: + * + * Assert that the last forked test failed. + * See g_test_trap_fork(). + * + * This is sometimes used to test situations that are formally considered to + * be undefined behaviour, like inputs that fail a g_return_if_fail() + * check. In these situations you should skip the entire test, including the + * call to g_test_trap_fork(), unless g_test_undefined() returns %TRUE + * to indicate that undefined behaviour may be tested. + * + * Since: 2.16 + */ + +/** + * g_test_trap_assert_stdout: + * @soutpattern: a glob-style + * pattern + * + * Assert that the stdout output of the last forked test matches + * @soutpattern. See g_test_trap_fork(). + * + * Since: 2.16 + */ + +/** + * g_test_trap_assert_stdout_unmatched: + * @soutpattern: a glob-style + * pattern + * + * Assert that the stdout output of the last forked test + * does not match @soutpattern. See g_test_trap_fork(). + * + * Since: 2.16 + */ + +/** + * g_test_trap_assert_stderr: + * @serrpattern: a glob-style + * pattern + * + * Assert that the stderr output of the last forked test + * matches @serrpattern. See g_test_trap_fork(). + * + * This is sometimes used to test situations that are formally considered to + * be undefined behaviour, like inputs that fail a g_return_if_fail() + * check. In these situations you should skip the entire test, including the + * call to g_test_trap_fork(), unless g_test_undefined() returns %TRUE + * to indicate that undefined behaviour may be tested. + * + * Since: 2.16 + */ + +/** + * g_test_trap_assert_stderr_unmatched: + * @serrpattern: a glob-style + * pattern + * + * Assert that the stderr output of the last forked test + * does not match @serrpattern. See g_test_trap_fork(). + * + * Since: 2.16 + */ + +/** + * g_test_rand_bit: + * + * Get a reproducible random bit (0 or 1), see g_test_rand_int() + * for details on test case random numbers. + * + * Since: 2.16 + */ + +/** + * g_assert: + * @expr: the expression to check + * + * Debugging macro to terminate the application if the assertion + * fails. If the assertion fails (i.e. the expression is not true), + * an error message is logged and the application is terminated. + * + * The macro can be turned off in final releases of code by defining + * G_DISABLE_ASSERT when compiling the application. + */ + +/** + * g_assert_not_reached: + * + * Debugging macro to terminate the application if it is ever + * reached. If it is reached, an error message is logged and the + * application is terminated. + * + * The macro can be turned off in final releases of code by defining + * G_DISABLE_ASSERT when compiling the application. + */ + +/** + * g_assert_cmpstr: + * @s1: a string (may be %NULL) + * @cmp: The comparison operator to use. + * One of ==, !=, <, >, <=, >=. + * @s2: another string (may be %NULL) + * + * Debugging macro to terminate the application with a warning + * message if a string comparison fails. The strings are compared + * using g_strcmp0(). + * + * The effect of g_assert_cmpstr (s1, op, s2) is + * the same as g_assert (g_strcmp0 (s1, s2) op 0). + * The advantage of this macro is that it can produce a message that + * includes the actual values of @s1 and @s2. + * + * |[ + * g_assert_cmpstr (mystring, ==, "fubar"); + * ]| + * + * Since: 2.16 + */ + +/** + * g_assert_cmpint: + * @n1: an integer + * @cmp: The comparison operator to use. + * One of ==, !=, <, >, <=, >=. + * @n2: another integer + * + * Debugging macro to terminate the application with a warning + * message if an integer comparison fails. + * + * The effect of g_assert_cmpint (n1, op, n2) is + * the same as g_assert (n1 op n2). The advantage + * of this macro is that it can produce a message that includes the + * actual values of @n1 and @n2. + * + * Since: 2.16 + */ + +/** + * g_assert_cmpuint: + * @n1: an unsigned integer + * @cmp: The comparison operator to use. + * One of ==, !=, <, >, <=, >=. + * @n2: another unsigned integer + * + * Debugging macro to terminate the application with a warning + * message if an unsigned integer comparison fails. + * + * The effect of g_assert_cmpuint (n1, op, n2) is + * the same as g_assert (n1 op n2). The advantage + * of this macro is that it can produce a message that includes the + * actual values of @n1 and @n2. + * + * Since: 2.16 + */ + +/** + * g_assert_cmphex: + * @n1: an unsigned integer + * @cmp: The comparison operator to use. + * One of ==, !=, <, >, <=, >=. + * @n2: another unsigned integer + * + * Debugging macro to terminate the application with a warning + * message if an unsigned integer comparison fails. + * + * This is a variant of g_assert_cmpuint() that displays the numbers + * in hexadecimal notation in the message. + * + * Since: 2.16 + */ + +/** + * g_assert_cmpfloat: + * @n1: an floating point number + * @cmp: The comparison operator to use. + * One of ==, !=, <, >, <=, >=. + * @n2: another floating point number + * + * Debugging macro to terminate the application with a warning + * message if a floating point number comparison fails. + * + * The effect of g_assert_cmpfloat (n1, op, n2) is + * the same as g_assert (n1 op n2). The advantage + * of this macro is that it can produce a message that includes the + * actual values of @n1 and @n2. + * + * Since: 2.16 + */ + +/** + * g_assert_no_error: + * @err: a #GError, possibly %NULL + * + * Debugging macro to terminate the application with a warning + * message if a method has returned a #GError. + * + * The effect of g_assert_no_error (err) is + * the same as g_assert (err == NULL). The advantage + * of this macro is that it can produce a message that includes + * the error message and code. + * + * Since: 2.20 + */ + +/** + * g_assert_error: + * @err: a #GError, possibly %NULL + * @dom: the expected error domain (a #GQuark) + * @c: the expected error code + * + * Debugging macro to terminate the application with a warning + * message if a method has not returned the correct #GError. + * + * The effect of g_assert_error (err, dom, c) is + * the same as g_assert (err != NULL && err->domain + * == dom && err->code == c). The advantage of this + * macro is that it can produce a message that includes the incorrect + * error message and code. + * + * This can only be used to test for a specific error. If you want to + * test that @err is set, but don't care what it's set to, just use + * g_assert (err != NULL) + * + * Since: 2.20 + */ + +/** + * GTestCase: + * + * An opaque structure representing a test case. + */ + +/** + * GTestSuite: + * + * An opaque structure representing a test suite. + */ + + +/* Global variable for storing assertion messages; this is the counterpart to + * glibc's (private) __abort_msg variable, and allows developers and crash + * analysis systems like Apport and ABRT to fish out assertion messages from + * core dumps, instead of having to catch them on screen output. + */ +char *__glib_assert_msg = NULL; + +/* --- structures --- */ +struct GTestCase +{ + gchar *name; + guint fixture_size; + void (*fixture_setup) (void*, gconstpointer); + void (*fixture_test) (void*, gconstpointer); + void (*fixture_teardown) (void*, gconstpointer); + gpointer test_data; +}; +struct GTestSuite +{ + gchar *name; + GSList *suites; + GSList *cases; +}; +typedef struct DestroyEntry DestroyEntry; +struct DestroyEntry +{ + DestroyEntry *next; + GDestroyNotify destroy_func; + gpointer destroy_data; +}; + +/* --- prototypes --- */ +static void test_run_seed (const gchar *rseed); +static void test_trap_clear (void); +static guint8* g_test_log_dump (GTestLogMsg *msg, + guint *len); +static void gtest_default_log_handler (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer unused_data); + + +/* --- variables --- */ +static int test_log_fd = -1; +static gboolean test_mode_fatal = TRUE; +static gboolean g_test_run_once = TRUE; +static gboolean test_run_list = FALSE; +static gchar *test_run_seedstr = NULL; +static GRand *test_run_rand = NULL; +static gchar *test_run_name = ""; +static guint test_run_forks = 0; +static guint test_run_count = 0; +static guint test_run_success = FALSE; +static guint test_skip_count = 0; +static GTimer *test_user_timer = NULL; +static double test_user_stamp = 0; +static GSList *test_paths = NULL; +static GSList *test_paths_skipped = NULL; +static GTestSuite *test_suite_root = NULL; +static int test_trap_last_status = 0; +static int test_trap_last_pid = 0; +static char *test_trap_last_stdout = NULL; +static char *test_trap_last_stderr = NULL; +static char *test_uri_base = NULL; +static gboolean test_debug_log = FALSE; +static DestroyEntry *test_destroy_queue = NULL; +static GTestConfig mutable_test_config_vars = { + FALSE, /* test_initialized */ + TRUE, /* test_quick */ + FALSE, /* test_perf */ + FALSE, /* test_verbose */ + FALSE, /* test_quiet */ + TRUE, /* test_undefined */ +}; +const GTestConfig * const g_test_config_vars = &mutable_test_config_vars; + +/* --- functions --- */ +const char* +g_test_log_type_name (GTestLogType log_type) +{ + switch (log_type) + { + case G_TEST_LOG_NONE: return "none"; + case G_TEST_LOG_ERROR: return "error"; + case G_TEST_LOG_START_BINARY: return "binary"; + case G_TEST_LOG_LIST_CASE: return "list"; + case G_TEST_LOG_SKIP_CASE: return "skip"; + case G_TEST_LOG_START_CASE: return "start"; + case G_TEST_LOG_STOP_CASE: return "stop"; + case G_TEST_LOG_MIN_RESULT: return "minperf"; + case G_TEST_LOG_MAX_RESULT: return "maxperf"; + case G_TEST_LOG_MESSAGE: return "message"; + } + return "???"; +} + +static void +g_test_log_send (guint n_bytes, + const guint8 *buffer) +{ + if (test_log_fd >= 0) + { + int r; + do + r = write (test_log_fd, buffer, n_bytes); + while (r < 0 && errno == EINTR); + } + if (test_debug_log) + { + GTestLogBuffer *lbuffer = g_test_log_buffer_new (); + GTestLogMsg *msg; + guint ui; + g_test_log_buffer_push (lbuffer, n_bytes, buffer); + msg = g_test_log_buffer_pop (lbuffer); + g_warn_if_fail (msg != NULL); + g_warn_if_fail (lbuffer->data->len == 0); + g_test_log_buffer_free (lbuffer); + /* print message */ + g_printerr ("{*LOG(%s)", g_test_log_type_name (msg->log_type)); + for (ui = 0; ui < msg->n_strings; ui++) + g_printerr (":{%s}", msg->strings[ui]); + if (msg->n_nums) + { + g_printerr (":("); + for (ui = 0; ui < msg->n_nums; ui++) + g_printerr ("%s%.16Lg", ui ? ";" : "", msg->nums[ui]); + g_printerr (")"); + } + g_printerr (":LOG*}\n"); + g_test_log_msg_free (msg); + } +} + +static void +g_test_log (GTestLogType lbit, + const gchar *string1, + const gchar *string2, + guint n_args, + long double *largs) +{ + gboolean fail = lbit == G_TEST_LOG_STOP_CASE && largs[0] != 0; + GTestLogMsg msg; + gchar *astrings[3] = { NULL, NULL, NULL }; + guint8 *dbuffer; + guint32 dbufferlen; + + switch (lbit) + { + case G_TEST_LOG_START_BINARY: + if (g_test_verbose()) + g_print ("GTest: random seed: %s\n", string2); + break; + case G_TEST_LOG_STOP_CASE: + if (g_test_verbose()) + g_print ("GTest: result: %s\n", fail ? "FAIL" : "OK"); + else if (!g_test_quiet()) + g_print ("%s\n", fail ? "FAIL" : "OK"); + if (fail && test_mode_fatal) + abort(); + break; + case G_TEST_LOG_MIN_RESULT: + if (g_test_verbose()) + g_print ("(MINPERF:%s)\n", string1); + break; + case G_TEST_LOG_MAX_RESULT: + if (g_test_verbose()) + g_print ("(MAXPERF:%s)\n", string1); + break; + case G_TEST_LOG_MESSAGE: + if (g_test_verbose()) + g_print ("(MSG: %s)\n", string1); + break; + default: ; + } + + msg.log_type = lbit; + msg.n_strings = (string1 != NULL) + (string1 && string2); + msg.strings = astrings; + astrings[0] = (gchar*) string1; + astrings[1] = astrings[0] ? (gchar*) string2 : NULL; + msg.n_nums = n_args; + msg.nums = largs; + dbuffer = g_test_log_dump (&msg, &dbufferlen); + g_test_log_send (dbufferlen, dbuffer); + g_free (dbuffer); + + switch (lbit) + { + case G_TEST_LOG_START_CASE: + if (g_test_verbose()) + g_print ("GTest: run: %s\n", string1); + else if (!g_test_quiet()) + g_print ("%s: ", string1); + break; + default: ; + } +} + +/* We intentionally parse the command line without GOptionContext + * because otherwise you would never be able to test it. + */ +static void +parse_args (gint *argc_p, + gchar ***argv_p) +{ + guint argc = *argc_p; + gchar **argv = *argv_p; + guint i, e; + /* parse known args */ + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "--g-fatal-warnings") == 0) + { + GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK); + fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); + g_log_set_always_fatal (fatal_mask); + argv[i] = NULL; + } + else if (strcmp (argv[i], "--keep-going") == 0 || + strcmp (argv[i], "-k") == 0) + { + test_mode_fatal = FALSE; + argv[i] = NULL; + } + else if (strcmp (argv[i], "--debug-log") == 0) + { + test_debug_log = TRUE; + argv[i] = NULL; + } + else if (strcmp ("--GTestLogFD", argv[i]) == 0 || strncmp ("--GTestLogFD=", argv[i], 13) == 0) + { + gchar *equal = argv[i] + 12; + if (*equal == '=') + test_log_fd = g_ascii_strtoull (equal + 1, NULL, 0); + else if (i + 1 < argc) + { + argv[i++] = NULL; + test_log_fd = g_ascii_strtoull (argv[i], NULL, 0); + } + argv[i] = NULL; + } + else if (strcmp ("--GTestSkipCount", argv[i]) == 0 || strncmp ("--GTestSkipCount=", argv[i], 17) == 0) + { + gchar *equal = argv[i] + 16; + if (*equal == '=') + test_skip_count = g_ascii_strtoull (equal + 1, NULL, 0); + else if (i + 1 < argc) + { + argv[i++] = NULL; + test_skip_count = g_ascii_strtoull (argv[i], NULL, 0); + } + argv[i] = NULL; + } + else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0) + { + gchar *equal = argv[i] + 2; + if (*equal == '=') + test_paths = g_slist_prepend (test_paths, equal + 1); + else if (i + 1 < argc) + { + argv[i++] = NULL; + test_paths = g_slist_prepend (test_paths, argv[i]); + } + argv[i] = NULL; + } + else if (strcmp ("-s", argv[i]) == 0 || strncmp ("-s=", argv[i], 3) == 0) + { + gchar *equal = argv[i] + 2; + if (*equal == '=') + test_paths_skipped = g_slist_prepend (test_paths_skipped, equal + 1); + else if (i + 1 < argc) + { + argv[i++] = NULL; + test_paths_skipped = g_slist_prepend (test_paths_skipped, argv[i]); + } + argv[i] = NULL; + } + else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0) + { + gchar *equal = argv[i] + 2; + const gchar *mode = ""; + if (*equal == '=') + mode = equal + 1; + else if (i + 1 < argc) + { + argv[i++] = NULL; + mode = argv[i]; + } + if (strcmp (mode, "perf") == 0) + mutable_test_config_vars.test_perf = TRUE; + else if (strcmp (mode, "slow") == 0) + mutable_test_config_vars.test_quick = FALSE; + else if (strcmp (mode, "thorough") == 0) + mutable_test_config_vars.test_quick = FALSE; + else if (strcmp (mode, "quick") == 0) + { + mutable_test_config_vars.test_quick = TRUE; + mutable_test_config_vars.test_perf = FALSE; + } + else if (strcmp (mode, "undefined") == 0) + mutable_test_config_vars.test_undefined = TRUE; + else if (strcmp (mode, "no-undefined") == 0) + mutable_test_config_vars.test_undefined = FALSE; + else + g_error ("unknown test mode: -m %s", mode); + argv[i] = NULL; + } + else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0) + { + mutable_test_config_vars.test_quiet = TRUE; + mutable_test_config_vars.test_verbose = FALSE; + argv[i] = NULL; + } + else if (strcmp ("--verbose", argv[i]) == 0) + { + mutable_test_config_vars.test_quiet = FALSE; + mutable_test_config_vars.test_verbose = TRUE; + argv[i] = NULL; + } + else if (strcmp ("-l", argv[i]) == 0) + { + test_run_list = TRUE; + argv[i] = NULL; + } + else if (strcmp ("--seed", argv[i]) == 0 || strncmp ("--seed=", argv[i], 7) == 0) + { + gchar *equal = argv[i] + 6; + if (*equal == '=') + test_run_seedstr = equal + 1; + else if (i + 1 < argc) + { + argv[i++] = NULL; + test_run_seedstr = argv[i]; + } + argv[i] = NULL; + } + else if (strcmp ("-?", argv[i]) == 0 || strcmp ("--help", argv[i]) == 0) + { + printf ("Usage:\n" + " %s [OPTION...]\n\n" + "Help Options:\n" + " -?, --help Show help options\n" + "Test Options:\n" + " -l List test cases available in a test executable\n" + " -seed=RANDOMSEED Provide a random seed to reproduce test\n" + " runs using random numbers\n" + " --verbose Run tests verbosely\n" + " -q, --quiet Run tests quietly\n" + " -p TESTPATH execute all tests matching TESTPATH\n" + " -s TESTPATH skip all tests matching TESTPATH\n" + " -m {perf|slow|thorough|quick} Execute tests according modes\n" + " -m {undefined|no-undefined} Execute tests according modes\n" + " --debug-log debug test logging output\n" + " -k, --keep-going gtester-specific argument\n" + " --GTestLogFD=N gtester-specific argument\n" + " --GTestSkipCount=N gtester-specific argument\n", + argv[0]); + exit (0); + } + } + /* collapse argv */ + e = 1; + for (i = 1; i < argc; i++) + if (argv[i]) + { + argv[e++] = argv[i]; + if (i >= e) + argv[i] = NULL; + } + *argc_p = e; +} + +/** + * g_test_init: + * @argc: Address of the @argc parameter of the main() function. + * Changed if any arguments were handled. + * @argv: Address of the @argv parameter of main(). + * Any parameters understood by g_test_init() stripped before return. + * @...: Reserved for future extension. Currently, you must pass %NULL. + * + * Initialize the GLib testing framework, e.g. by seeding the + * test random number generator, the name for g_get_prgname() + * and parsing test related command line args. + * So far, the following arguments are understood: + * + * + * + * + * list test cases available in a test executable. + * + * + * + * + * + * provide a random seed to reproduce test runs using random numbers. + * + * + * + * + * run tests verbosely. + * + * + * , + * run tests quietly. + * + * + * + * + * execute all tests matching TESTPATH. + * + * + * + * + * + * execute tests according to these test modes: + * + * + * perf + * + * performance tests, may take long and report results. + * + * + * + * slow, thorough + * + * slow and thorough tests, may take quite long and + * maximize coverage. + * + * + * + * quick + * + * quick tests, should run really quickly and give good coverage. + * + * + * + * undefined + * + * tests for undefined behaviour, may provoke programming errors + * under g_test_trap_fork() to check that appropriate assertions + * or warnings are given + * + * + * + * no-undefined + * + * avoid tests for undefined behaviour + * + * + * + * + * + * + * + * debug test logging output. + * + * + * , + * gtester-specific argument. + * + * + * + * gtester-specific argument. + * + * + * + * gtester-specific argument. + * + * + * + * Since: 2.16 + */ +void +g_test_init (int *argc, + char ***argv, + ...) +{ + static char seedstr[4 + 4 * 8 + 1]; + va_list args; + gpointer vararg1; + /* make warnings and criticals fatal for all test programs */ + GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK); + fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL); + g_log_set_always_fatal (fatal_mask); + /* check caller args */ + g_return_if_fail (argc != NULL); + g_return_if_fail (argv != NULL); + g_return_if_fail (g_test_config_vars->test_initialized == FALSE); + mutable_test_config_vars.test_initialized = TRUE; + + va_start (args, argv); + vararg1 = va_arg (args, gpointer); /* reserved for future extensions */ + va_end (args); + g_return_if_fail (vararg1 == NULL); + + /* setup random seed string */ + g_snprintf (seedstr, sizeof (seedstr), "R02S%08x%08x%08x%08x", g_random_int(), g_random_int(), g_random_int(), g_random_int()); + test_run_seedstr = seedstr; + + /* parse args, sets up mode, changes seed, etc. */ + parse_args (argc, argv); + if (!g_get_prgname()) + g_set_prgname ((*argv)[0]); + + /* verify GRand reliability, needed for reliable seeds */ + if (1) + { + GRand *rg = g_rand_new_with_seed (0xc8c49fb6); + guint32 t1 = g_rand_int (rg), t2 = g_rand_int (rg), t3 = g_rand_int (rg), t4 = g_rand_int (rg); + /* g_print ("GRand-current: 0x%x 0x%x 0x%x 0x%x\n", t1, t2, t3, t4); */ + if (t1 != 0xfab39f9b || t2 != 0xb948fb0e || t3 != 0x3d31be26 || t4 != 0x43a19d66) + g_warning ("random numbers are not GRand-2.2 compatible, seeds may be broken (check $G_RANDOM_VERSION)"); + g_rand_free (rg); + } + + /* check rand seed */ + test_run_seed (test_run_seedstr); + + /* report program start */ + g_log_set_default_handler (gtest_default_log_handler, NULL); + g_test_log (G_TEST_LOG_START_BINARY, g_get_prgname(), test_run_seedstr, 0, NULL); +} + +static void +test_run_seed (const gchar *rseed) +{ + guint seed_failed = 0; + if (test_run_rand) + g_rand_free (test_run_rand); + test_run_rand = NULL; + while (strchr (" \t\v\r\n\f", *rseed)) + rseed++; + if (strncmp (rseed, "R02S", 4) == 0) /* seed for random generator 02 (GRand-2.2) */ + { + const char *s = rseed + 4; + if (strlen (s) >= 32) /* require 4 * 8 chars */ + { + guint32 seedarray[4]; + gchar *p, hexbuf[9] = { 0, }; + memcpy (hexbuf, s + 0, 8); + seedarray[0] = g_ascii_strtoull (hexbuf, &p, 16); + seed_failed += p != NULL && *p != 0; + memcpy (hexbuf, s + 8, 8); + seedarray[1] = g_ascii_strtoull (hexbuf, &p, 16); + seed_failed += p != NULL && *p != 0; + memcpy (hexbuf, s + 16, 8); + seedarray[2] = g_ascii_strtoull (hexbuf, &p, 16); + seed_failed += p != NULL && *p != 0; + memcpy (hexbuf, s + 24, 8); + seedarray[3] = g_ascii_strtoull (hexbuf, &p, 16); + seed_failed += p != NULL && *p != 0; + if (!seed_failed) + { + test_run_rand = g_rand_new_with_seed_array (seedarray, 4); + return; + } + } + } + g_error ("Unknown or invalid random seed: %s", rseed); +} + +/** + * g_test_rand_int: + * + * Get a reproducible random integer number. + * + * The random numbers generated by the g_test_rand_*() family of functions + * change with every new test program start, unless the --seed option is + * given when starting test programs. + * + * For individual test cases however, the random number generator is + * reseeded, to avoid dependencies between tests and to make --seed + * effective for all test cases. + * + * Returns: a random number from the seeded random number generator. + * + * Since: 2.16 + */ +gint32 +g_test_rand_int (void) +{ + return g_rand_int (test_run_rand); +} + +/** + * g_test_rand_int_range: + * @begin: the minimum value returned by this function + * @end: the smallest value not to be returned by this function + * + * Get a reproducible random integer number out of a specified range, + * see g_test_rand_int() for details on test case random numbers. + * + * Returns: a number with @begin <= number < @end. + * + * Since: 2.16 + */ +gint32 +g_test_rand_int_range (gint32 begin, + gint32 end) +{ + return g_rand_int_range (test_run_rand, begin, end); +} + +/** + * g_test_rand_double: + * + * Get a reproducible random floating point number, + * see g_test_rand_int() for details on test case random numbers. + * + * Returns: a random number from the seeded random number generator. + * + * Since: 2.16 + */ +double +g_test_rand_double (void) +{ + return g_rand_double (test_run_rand); +} + +/** + * g_test_rand_double_range: + * @range_start: the minimum value returned by this function + * @range_end: the minimum value not returned by this function + * + * Get a reproducible random floating pointer number out of a specified range, + * see g_test_rand_int() for details on test case random numbers. + * + * Returns: a number with @range_start <= number < @range_end. + * + * Since: 2.16 + */ +double +g_test_rand_double_range (double range_start, + double range_end) +{ + return g_rand_double_range (test_run_rand, range_start, range_end); +} + +/** + * g_test_timer_start: + * + * Start a timing test. Call g_test_timer_elapsed() when the task is supposed + * to be done. Call this function again to restart the timer. + * + * Since: 2.16 + */ +void +g_test_timer_start (void) +{ + if (!test_user_timer) + test_user_timer = g_timer_new(); + test_user_stamp = 0; + g_timer_start (test_user_timer); +} + +/** + * g_test_timer_elapsed: + * + * Get the time since the last start of the timer with g_test_timer_start(). + * + * Returns: the time since the last start of the timer, as a double + * + * Since: 2.16 + */ +double +g_test_timer_elapsed (void) +{ + test_user_stamp = test_user_timer ? g_timer_elapsed (test_user_timer, NULL) : 0; + return test_user_stamp; +} + +/** + * g_test_timer_last: + * + * Report the last result of g_test_timer_elapsed(). + * + * Returns: the last result of g_test_timer_elapsed(), as a double + * + * Since: 2.16 + */ +double +g_test_timer_last (void) +{ + return test_user_stamp; +} + +/** + * g_test_minimized_result: + * @minimized_quantity: the reported value + * @format: the format string of the report message + * @...: arguments to pass to the printf() function + * + * Report the result of a performance or measurement test. + * The test should generally strive to minimize the reported + * quantities (smaller values are better than larger ones), + * this and @minimized_quantity can determine sorting + * order for test result reports. + * + * Since: 2.16 + */ +void +g_test_minimized_result (double minimized_quantity, + const char *format, + ...) +{ + long double largs = minimized_quantity; + gchar *buffer; + va_list args; + + va_start (args, format); + buffer = g_strdup_vprintf (format, args); + va_end (args); + + g_test_log (G_TEST_LOG_MIN_RESULT, buffer, NULL, 1, &largs); + g_free (buffer); +} + +/** + * g_test_maximized_result: + * @maximized_quantity: the reported value + * @format: the format string of the report message + * @...: arguments to pass to the printf() function + * + * Report the result of a performance or measurement test. + * The test should generally strive to maximize the reported + * quantities (larger values are better than smaller ones), + * this and @maximized_quantity can determine sorting + * order for test result reports. + * + * Since: 2.16 + */ +void +g_test_maximized_result (double maximized_quantity, + const char *format, + ...) +{ + long double largs = maximized_quantity; + gchar *buffer; + va_list args; + + va_start (args, format); + buffer = g_strdup_vprintf (format, args); + va_end (args); + + g_test_log (G_TEST_LOG_MAX_RESULT, buffer, NULL, 1, &largs); + g_free (buffer); +} + +/** + * g_test_message: + * @format: the format string + * @...: printf-like arguments to @format + * + * Add a message to the test report. + * + * Since: 2.16 + */ +void +g_test_message (const char *format, + ...) +{ + gchar *buffer; + va_list args; + + va_start (args, format); + buffer = g_strdup_vprintf (format, args); + va_end (args); + + g_test_log (G_TEST_LOG_MESSAGE, buffer, NULL, 0, NULL); + g_free (buffer); +} + +/** + * g_test_bug_base: + * @uri_pattern: the base pattern for bug URIs + * + * Specify the base URI for bug reports. + * + * The base URI is used to construct bug report messages for + * g_test_message() when g_test_bug() is called. + * Calling this function outside of a test case sets the + * default base URI for all test cases. Calling it from within + * a test case changes the base URI for the scope of the test + * case only. + * Bug URIs are constructed by appending a bug specific URI + * portion to @uri_pattern, or by replacing the special string + * '\%s' within @uri_pattern if that is present. + * + * Since: 2.16 + */ +void +g_test_bug_base (const char *uri_pattern) +{ + g_free (test_uri_base); + test_uri_base = g_strdup (uri_pattern); +} + +/** + * g_test_bug: + * @bug_uri_snippet: Bug specific bug tracker URI portion. + * + * This function adds a message to test reports that + * associates a bug URI with a test case. + * Bug URIs are constructed from a base URI set with g_test_bug_base() + * and @bug_uri_snippet. + * + * Since: 2.16 + */ +void +g_test_bug (const char *bug_uri_snippet) +{ + char *c; + + g_return_if_fail (test_uri_base != NULL); + g_return_if_fail (bug_uri_snippet != NULL); + + c = strstr (test_uri_base, "%s"); + if (c) + { + char *b = g_strndup (test_uri_base, c - test_uri_base); + char *s = g_strconcat (b, bug_uri_snippet, c + 2, NULL); + g_free (b); + g_test_message ("Bug Reference: %s", s); + g_free (s); + } + else + g_test_message ("Bug Reference: %s%s", test_uri_base, bug_uri_snippet); +} + +/** + * g_test_get_root: + * + * Get the toplevel test suite for the test path API. + * + * Returns: the toplevel #GTestSuite + * + * Since: 2.16 + */ +GTestSuite* +g_test_get_root (void) +{ + if (!test_suite_root) + { + test_suite_root = g_test_create_suite ("root"); + g_free (test_suite_root->name); + test_suite_root->name = g_strdup (""); + } + + return test_suite_root; +} + +/** + * g_test_run: + * + * Runs all tests under the toplevel suite which can be retrieved + * with g_test_get_root(). Similar to g_test_run_suite(), the test + * cases to be run are filtered according to + * test path arguments (-p testpath) as + * parsed by g_test_init(). + * g_test_run_suite() or g_test_run() may only be called once + * in a program. + * + * Returns: 0 on success + * + * Since: 2.16 + */ +int +g_test_run (void) +{ + return g_test_run_suite (g_test_get_root()); +} + +/** + * g_test_create_case: + * @test_name: the name for the test case + * @data_size: the size of the fixture data structure + * @test_data: test data argument for the test functions + * @data_setup: the function to set up the fixture data + * @data_test: the actual test function + * @data_teardown: the function to teardown the fixture data + * + * Create a new #GTestCase, named @test_name, this API is fairly + * low level, calling g_test_add() or g_test_add_func() is preferable. + * When this test is executed, a fixture structure of size @data_size + * will be allocated and filled with 0s. Then @data_setup is called + * to initialize the fixture. After fixture setup, the actual test + * function @data_test is called. Once the test run completed, the + * fixture structure is torn down by calling @data_teardown and + * after that the memory is released. + * + * Splitting up a test run into fixture setup, test function and + * fixture teardown is most usful if the same fixture is used for + * multiple tests. In this cases, g_test_create_case() will be + * called with the same fixture, but varying @test_name and + * @data_test arguments. + * + * Returns: a newly allocated #GTestCase. + * + * Since: 2.16 + */ +GTestCase* +g_test_create_case (const char *test_name, + gsize data_size, + gconstpointer test_data, + GTestFixtureFunc data_setup, + GTestFixtureFunc data_test, + GTestFixtureFunc data_teardown) +{ + GTestCase *tc; + + g_return_val_if_fail (test_name != NULL, NULL); + g_return_val_if_fail (strchr (test_name, '/') == NULL, NULL); + g_return_val_if_fail (test_name[0] != 0, NULL); + g_return_val_if_fail (data_test != NULL, NULL); + + tc = g_slice_new0 (GTestCase); + tc->name = g_strdup (test_name); + tc->test_data = (gpointer) test_data; + tc->fixture_size = data_size; + tc->fixture_setup = (void*) data_setup; + tc->fixture_test = (void*) data_test; + tc->fixture_teardown = (void*) data_teardown; + + return tc; +} + +/** + * GTestFixtureFunc: + * @fixture: the test fixture + * @user_data: the data provided when registering the test + * + * The type used for functions that operate on test fixtures. This is + * used for the fixture setup and teardown functions as well as for the + * testcases themselves. + * + * @user_data is a pointer to the data that was given when registering + * the test case. + * + * @fixture will be a pointer to the area of memory allocated by the + * test framework, of the size requested. If the requested size was + * zero then @fixture will be equal to @user_data. + * + * Since: 2.28 + */ +void +g_test_add_vtable (const char *testpath, + gsize data_size, + gconstpointer test_data, + GTestFixtureFunc data_setup, + GTestFixtureFunc fixture_test_func, + GTestFixtureFunc data_teardown) +{ + gchar **segments; + guint ui; + GTestSuite *suite; + + g_return_if_fail (testpath != NULL); + g_return_if_fail (g_path_is_absolute (testpath)); + g_return_if_fail (fixture_test_func != NULL); + + if (g_slist_find_custom (test_paths_skipped, testpath, (GCompareFunc)g_strcmp0)) + return; + + suite = g_test_get_root(); + segments = g_strsplit (testpath, G_DIR_SEPARATOR_S, -1); + for (ui = 0; segments[ui] != NULL; ui++) + { + const char *seg = segments[ui]; + gboolean islast = segments[ui + 1] == NULL; + if (islast && !seg[0]) + g_error ("invalid test case path: %s", testpath); + else if (!seg[0]) + continue; /* initial or duplicate slash */ + else if (!islast) + { + GTestSuite *csuite = g_test_create_suite (seg); + g_test_suite_add_suite (suite, csuite); + suite = csuite; + } + else /* islast */ + { + GTestCase *tc = g_test_create_case (seg, data_size, test_data, data_setup, fixture_test_func, data_teardown); + g_test_suite_add (suite, tc); + } + } + g_strfreev (segments); +} + +/** + * g_test_fail: + * + * Indicates that a test failed. This function can be called + * multiple times from the same test. You can use this function + * if your test failed in a recoverable way. + * + * Do not use this function if the failure of a test could cause + * other tests to malfunction. + * + * Calling this function will not stop the test from running, you + * need to return from the test function yourself. So you can + * produce additional diagnostic messages or even continue running + * the test. + * + * If not called from inside a test, this function does nothing. + * + * Since: 2.30 + **/ +void +g_test_fail (void) +{ + test_run_success = FALSE; +} + +/** + * GTestFunc: + * + * The type used for test case functions. + * + * Since: 2.28 + */ + +/** + * g_test_add_func: + * @testpath: Slash-separated test case path name for the test. + * @test_func: The test function to invoke for this test. + * + * Create a new test case, similar to g_test_create_case(). However + * the test is assumed to use no fixture, and test suites are automatically + * created on the fly and added to the root fixture, based on the + * slash-separated portions of @testpath. + * + * Since: 2.16 + */ +void +g_test_add_func (const char *testpath, + GTestFunc test_func) +{ + g_return_if_fail (testpath != NULL); + g_return_if_fail (testpath[0] == '/'); + g_return_if_fail (test_func != NULL); + g_test_add_vtable (testpath, 0, NULL, NULL, (GTestFixtureFunc) test_func, NULL); +} + +/** + * GTestDataFunc: + * @user_data: the data provided when registering the test + * + * The type used for test case functions that take an extra pointer + * argument. + * + * Since: 2.28 + */ + +/** + * g_test_add_data_func: + * @testpath: Slash-separated test case path name for the test. + * @test_data: Test data argument for the test function. + * @test_func: The test function to invoke for this test. + * + * Create a new test case, similar to g_test_create_case(). However + * the test is assumed to use no fixture, and test suites are automatically + * created on the fly and added to the root fixture, based on the + * slash-separated portions of @testpath. The @test_data argument + * will be passed as first argument to @test_func. + * + * Since: 2.16 + */ +void +g_test_add_data_func (const char *testpath, + gconstpointer test_data, + GTestDataFunc test_func) +{ + g_return_if_fail (testpath != NULL); + g_return_if_fail (testpath[0] == '/'); + g_return_if_fail (test_func != NULL); + g_test_add_vtable (testpath, 0, test_data, NULL, (GTestFixtureFunc) test_func, NULL); +} + +/** + * g_test_create_suite: + * @suite_name: a name for the suite + * + * Create a new test suite with the name @suite_name. + * + * Returns: A newly allocated #GTestSuite instance. + * + * Since: 2.16 + */ +GTestSuite* +g_test_create_suite (const char *suite_name) +{ + GTestSuite *ts; + g_return_val_if_fail (suite_name != NULL, NULL); + g_return_val_if_fail (strchr (suite_name, '/') == NULL, NULL); + g_return_val_if_fail (suite_name[0] != 0, NULL); + ts = g_slice_new0 (GTestSuite); + ts->name = g_strdup (suite_name); + return ts; +} + +/** + * g_test_suite_add: + * @suite: a #GTestSuite + * @test_case: a #GTestCase + * + * Adds @test_case to @suite. + * + * Since: 2.16 + */ +void +g_test_suite_add (GTestSuite *suite, + GTestCase *test_case) +{ + g_return_if_fail (suite != NULL); + g_return_if_fail (test_case != NULL); + + suite->cases = g_slist_prepend (suite->cases, test_case); +} + +/** + * g_test_suite_add_suite: + * @suite: a #GTestSuite + * @nestedsuite: another #GTestSuite + * + * Adds @nestedsuite to @suite. + * + * Since: 2.16 + */ +void +g_test_suite_add_suite (GTestSuite *suite, + GTestSuite *nestedsuite) +{ + g_return_if_fail (suite != NULL); + g_return_if_fail (nestedsuite != NULL); + + suite->suites = g_slist_prepend (suite->suites, nestedsuite); +} + +/** + * g_test_queue_free: + * @gfree_pointer: the pointer to be stored. + * + * Enqueue a pointer to be released with g_free() during the next + * teardown phase. This is equivalent to calling g_test_queue_destroy() + * with a destroy callback of g_free(). + * + * Since: 2.16 + */ +void +g_test_queue_free (gpointer gfree_pointer) +{ + if (gfree_pointer) + g_test_queue_destroy (g_free, gfree_pointer); +} + +/** + * g_test_queue_destroy: + * @destroy_func: Destroy callback for teardown phase. + * @destroy_data: Destroy callback data. + * + * This function enqueus a callback @destroy_func to be executed + * during the next test case teardown phase. This is most useful + * to auto destruct allocted test resources at the end of a test run. + * Resources are released in reverse queue order, that means enqueueing + * callback A before callback B will cause B() to be called before + * A() during teardown. + * + * Since: 2.16 + */ +void +g_test_queue_destroy (GDestroyNotify destroy_func, + gpointer destroy_data) +{ + DestroyEntry *dentry; + + g_return_if_fail (destroy_func != NULL); + + dentry = g_slice_new0 (DestroyEntry); + dentry->destroy_func = destroy_func; + dentry->destroy_data = destroy_data; + dentry->next = test_destroy_queue; + test_destroy_queue = dentry; +} + +static gboolean +test_case_run (GTestCase *tc) +{ + gchar *old_name = test_run_name, *old_base = g_strdup (test_uri_base); + gboolean success = TRUE; + + test_run_name = g_strconcat (old_name, "/", tc->name, NULL); + if (++test_run_count <= test_skip_count) + g_test_log (G_TEST_LOG_SKIP_CASE, test_run_name, NULL, 0, NULL); + else if (test_run_list) + { + g_print ("%s\n", test_run_name); + g_test_log (G_TEST_LOG_LIST_CASE, test_run_name, NULL, 0, NULL); + } + else + { + GTimer *test_run_timer = g_timer_new(); + long double largs[3]; + void *fixture; + g_test_log (G_TEST_LOG_START_CASE, test_run_name, NULL, 0, NULL); + test_run_forks = 0; + test_run_success = TRUE; + g_test_log_set_fatal_handler (NULL, NULL); + g_timer_start (test_run_timer); + fixture = tc->fixture_size ? g_malloc0 (tc->fixture_size) : tc->test_data; + test_run_seed (test_run_seedstr); + if (tc->fixture_setup) + tc->fixture_setup (fixture, tc->test_data); + tc->fixture_test (fixture, tc->test_data); + test_trap_clear(); + while (test_destroy_queue) + { + DestroyEntry *dentry = test_destroy_queue; + test_destroy_queue = dentry->next; + dentry->destroy_func (dentry->destroy_data); + g_slice_free (DestroyEntry, dentry); + } + if (tc->fixture_teardown) + tc->fixture_teardown (fixture, tc->test_data); + if (tc->fixture_size) + g_free (fixture); + g_timer_stop (test_run_timer); + success = test_run_success; + test_run_success = FALSE; + largs[0] = success ? 0 : 1; /* OK */ + largs[1] = test_run_forks; + largs[2] = g_timer_elapsed (test_run_timer, NULL); + g_test_log (G_TEST_LOG_STOP_CASE, NULL, NULL, G_N_ELEMENTS (largs), largs); + g_timer_destroy (test_run_timer); + } + g_free (test_run_name); + test_run_name = old_name; + g_free (test_uri_base); + test_uri_base = old_base; + + return success; +} + +static int +g_test_run_suite_internal (GTestSuite *suite, + const char *path) +{ + guint n_bad = 0, l; + gchar *rest, *old_name = test_run_name; + GSList *slist, *reversed; + + g_return_val_if_fail (suite != NULL, -1); + + while (path[0] == '/') + path++; + l = strlen (path); + rest = strchr (path, '/'); + l = rest ? MIN (l, rest - path) : l; + test_run_name = suite->name[0] == 0 ? g_strdup (test_run_name) : g_strconcat (old_name, "/", suite->name, NULL); + reversed = g_slist_reverse (g_slist_copy (suite->cases)); + for (slist = reversed; slist; slist = slist->next) + { + GTestCase *tc = slist->data; + guint n = l ? strlen (tc->name) : 0; + if (l == n && strncmp (path, tc->name, n) == 0) + { + if (!test_case_run (tc)) + n_bad++; + } + } + g_slist_free (reversed); + reversed = g_slist_reverse (g_slist_copy (suite->suites)); + for (slist = reversed; slist; slist = slist->next) + { + GTestSuite *ts = slist->data; + guint n = l ? strlen (ts->name) : 0; + if (l == n && strncmp (path, ts->name, n) == 0) + n_bad += g_test_run_suite_internal (ts, rest ? rest : ""); + } + g_slist_free (reversed); + g_free (test_run_name); + test_run_name = old_name; + + return n_bad; +} + +/** + * g_test_run_suite: + * @suite: a #GTestSuite + * + * Execute the tests within @suite and all nested #GTestSuites. + * The test suites to be executed are filtered according to + * test path arguments (-p testpath) + * as parsed by g_test_init(). + * g_test_run_suite() or g_test_run() may only be called once + * in a program. + * + * Returns: 0 on success + * + * Since: 2.16 + */ +int +g_test_run_suite (GTestSuite *suite) +{ + guint n_bad = 0; + + g_return_val_if_fail (g_test_config_vars->test_initialized, -1); + g_return_val_if_fail (g_test_run_once == TRUE, -1); + + g_test_run_once = FALSE; + + if (!test_paths) + test_paths = g_slist_prepend (test_paths, ""); + while (test_paths) + { + const char *rest, *path = test_paths->data; + guint l, n = strlen (suite->name); + test_paths = g_slist_delete_link (test_paths, test_paths); + while (path[0] == '/') + path++; + if (!n) /* root suite, run unconditionally */ + { + n_bad += g_test_run_suite_internal (suite, path); + continue; + } + /* regular suite, match path */ + rest = strchr (path, '/'); + l = strlen (path); + l = rest ? MIN (l, rest - path) : l; + if ((!l || l == n) && strncmp (path, suite->name, n) == 0) + n_bad += g_test_run_suite_internal (suite, rest ? rest : ""); + } + + return n_bad; +} + +static void +gtest_default_log_handler (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer unused_data) +{ + const gchar *strv[16]; + gboolean fatal = FALSE; + gchar *msg; + guint i = 0; + + if (log_domain) + { + strv[i++] = log_domain; + strv[i++] = "-"; + } + if (log_level & G_LOG_FLAG_FATAL) + { + strv[i++] = "FATAL-"; + fatal = TRUE; + } + if (log_level & G_LOG_FLAG_RECURSION) + strv[i++] = "RECURSIVE-"; + if (log_level & G_LOG_LEVEL_ERROR) + strv[i++] = "ERROR"; + if (log_level & G_LOG_LEVEL_CRITICAL) + strv[i++] = "CRITICAL"; + if (log_level & G_LOG_LEVEL_WARNING) + strv[i++] = "WARNING"; + if (log_level & G_LOG_LEVEL_MESSAGE) + strv[i++] = "MESSAGE"; + if (log_level & G_LOG_LEVEL_INFO) + strv[i++] = "INFO"; + if (log_level & G_LOG_LEVEL_DEBUG) + strv[i++] = "DEBUG"; + strv[i++] = ": "; + strv[i++] = message; + strv[i++] = NULL; + + msg = g_strjoinv ("", (gchar**) strv); + g_test_log (fatal ? G_TEST_LOG_ERROR : G_TEST_LOG_MESSAGE, msg, NULL, 0, NULL); + g_log_default_handler (log_domain, log_level, message, unused_data); + + g_free (msg); +} + +void +g_assertion_message (const char *domain, + const char *file, + int line, + const char *func, + const char *message) +{ + char lstr[32]; + char *s; + + if (!message) + message = "code should not be reached"; + g_snprintf (lstr, 32, "%d", line); + s = g_strconcat (domain ? domain : "", domain && domain[0] ? ":" : "", + "ERROR:", file, ":", lstr, ":", + func, func[0] ? ":" : "", + " ", message, NULL); + g_printerr ("**\n%s\n", s); + + /* store assertion message in global variable, so that it can be found in a + * core dump */ + if (__glib_assert_msg != NULL) + /* free the old one */ + free (__glib_assert_msg); + __glib_assert_msg = (char*) malloc (strlen (s) + 1); + strcpy (__glib_assert_msg, s); + + g_test_log (G_TEST_LOG_ERROR, s, NULL, 0, NULL); + g_free (s); + abort(); +} + +void +g_assertion_message_expr (const char *domain, + const char *file, + int line, + const char *func, + const char *expr) +{ + char *s = g_strconcat ("assertion failed: (", expr, ")", NULL); + g_assertion_message (domain, file, line, func, s); + g_free (s); +} + +void +g_assertion_message_cmpnum (const char *domain, + const char *file, + int line, + const char *func, + const char *expr, + long double arg1, + const char *cmp, + long double arg2, + char numtype) +{ + char *s = NULL; + switch (numtype) + { + case 'i': s = g_strdup_printf ("assertion failed (%s): (%.0Lf %s %.0Lf)", expr, arg1, cmp, arg2); break; + case 'x': s = g_strdup_printf ("assertion failed (%s): (0x%08" G_GINT64_MODIFIER "x %s 0x%08" G_GINT64_MODIFIER "x)", expr, (guint64) arg1, cmp, (guint64) arg2); break; + case 'f': s = g_strdup_printf ("assertion failed (%s): (%.9Lg %s %.9Lg)", expr, arg1, cmp, arg2); break; + /* ideally use: floats=%.7g double=%.17g */ + } + g_assertion_message (domain, file, line, func, s); + g_free (s); +} + +void +g_assertion_message_cmpstr (const char *domain, + const char *file, + int line, + const char *func, + const char *expr, + const char *arg1, + const char *cmp, + const char *arg2) +{ + char *a1, *a2, *s, *t1 = NULL, *t2 = NULL; + a1 = arg1 ? g_strconcat ("\"", t1 = g_strescape (arg1, NULL), "\"", NULL) : g_strdup ("NULL"); + a2 = arg2 ? g_strconcat ("\"", t2 = g_strescape (arg2, NULL), "\"", NULL) : g_strdup ("NULL"); + g_free (t1); + g_free (t2); + s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2); + g_free (a1); + g_free (a2); + g_assertion_message (domain, file, line, func, s); + g_free (s); +} + +void +g_assertion_message_error (const char *domain, + const char *file, + int line, + const char *func, + const char *expr, + const GError *error, + GQuark error_domain, + int error_code) +{ + GString *gstring; + + /* This is used by both g_assert_error() and g_assert_no_error(), so there + * are three cases: expected an error but got the wrong error, expected + * an error but got no error, and expected no error but got an error. + */ + + gstring = g_string_new ("assertion failed "); + if (error_domain) + g_string_append_printf (gstring, "(%s == (%s, %d)): ", expr, + g_quark_to_string (error_domain), error_code); + else + g_string_append_printf (gstring, "(%s == NULL): ", expr); + + if (error) + g_string_append_printf (gstring, "%s (%s, %d)", error->message, + g_quark_to_string (error->domain), error->code); + else + g_string_append_printf (gstring, "%s is NULL", expr); + + g_assertion_message (domain, file, line, func, gstring->str); + g_string_free (gstring, TRUE); +} + +/** + * g_strcmp0: + * @str1: a C string or %NULL + * @str2: another C string or %NULL + * + * Compares @str1 and @str2 like strcmp(). Handles %NULL + * gracefully by sorting it before non-%NULL strings. + * Comparing two %NULL pointers returns 0. + * + * Returns: -1, 0 or 1, if @str1 is <, == or > than @str2. + * + * Since: 2.16 + */ +int +g_strcmp0 (const char *str1, + const char *str2) +{ + if (!str1) + return -(str1 != str2); + if (!str2) + return str1 != str2; + return strcmp (str1, str2); +} + +#ifdef G_OS_UNIX +static int /* 0 on success */ +kill_child (int pid, + int *status, + int patience) +{ + int wr; + if (patience >= 3) /* try graceful reap */ + { + if (waitpid (pid, status, WNOHANG) > 0) + return 0; + } + if (patience >= 2) /* try SIGHUP */ + { + kill (pid, SIGHUP); + if (waitpid (pid, status, WNOHANG) > 0) + return 0; + g_usleep (20 * 1000); /* give it some scheduling/shutdown time */ + if (waitpid (pid, status, WNOHANG) > 0) + return 0; + g_usleep (50 * 1000); /* give it some scheduling/shutdown time */ + if (waitpid (pid, status, WNOHANG) > 0) + return 0; + g_usleep (100 * 1000); /* give it some scheduling/shutdown time */ + if (waitpid (pid, status, WNOHANG) > 0) + return 0; + } + if (patience >= 1) /* try SIGTERM */ + { + kill (pid, SIGTERM); + if (waitpid (pid, status, WNOHANG) > 0) + return 0; + g_usleep (200 * 1000); /* give it some scheduling/shutdown time */ + if (waitpid (pid, status, WNOHANG) > 0) + return 0; + g_usleep (400 * 1000); /* give it some scheduling/shutdown time */ + if (waitpid (pid, status, WNOHANG) > 0) + return 0; + } + /* finish it off */ + kill (pid, SIGKILL); + do + wr = waitpid (pid, status, 0); + while (wr < 0 && errno == EINTR); + return wr; +} +#endif + +static inline int +g_string_must_read (GString *gstring, + int fd) +{ +#define STRING_BUFFER_SIZE 4096 + char buf[STRING_BUFFER_SIZE]; + gssize bytes; + again: + bytes = read (fd, buf, sizeof (buf)); + if (bytes == 0) + return 0; /* EOF, calling this function assumes data is available */ + else if (bytes > 0) + { + g_string_append_len (gstring, buf, bytes); + return 1; + } + else if (bytes < 0 && errno == EINTR) + goto again; + else /* bytes < 0 */ + { + g_warning ("failed to read() from child process (%d): %s", test_trap_last_pid, g_strerror (errno)); + return 1; /* ignore error after warning */ + } +} + +static inline void +g_string_write_out (GString *gstring, + int outfd, + int *stringpos) +{ + if (*stringpos < gstring->len) + { + int r; + do + r = write (outfd, gstring->str + *stringpos, gstring->len - *stringpos); + while (r < 0 && errno == EINTR); + *stringpos += MAX (r, 0); + } +} + +static void +test_trap_clear (void) +{ + test_trap_last_status = 0; + test_trap_last_pid = 0; + g_free (test_trap_last_stdout); + test_trap_last_stdout = NULL; + g_free (test_trap_last_stderr); + test_trap_last_stderr = NULL; +} + +#ifdef G_OS_UNIX + +static int +sane_dup2 (int fd1, + int fd2) +{ + int ret; + do + ret = dup2 (fd1, fd2); + while (ret < 0 && errno == EINTR); + return ret; +} + +static guint64 +test_time_stamp (void) +{ + GTimeVal tv; + guint64 stamp; + g_get_current_time (&tv); + stamp = tv.tv_sec; + stamp = stamp * 1000000 + tv.tv_usec; + return stamp; +} + +#endif + +/** + * g_test_trap_fork: + * @usec_timeout: Timeout for the forked test in micro seconds. + * @test_trap_flags: Flags to modify forking behaviour. + * + * Fork the current test program to execute a test case that might + * not return or that might abort. The forked test case is aborted + * and considered failing if its run time exceeds @usec_timeout. + * + * The forking behavior can be configured with the #GTestTrapFlags flags. + * + * In the following example, the test code forks, the forked child + * process produces some sample output and exits successfully. + * The forking parent process then asserts successful child program + * termination and validates child program outputs. + * + * |[ + * static void + * test_fork_patterns (void) + * { + * if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR)) + * { + * g_print ("some stdout text: somagic17\n"); + * g_printerr ("some stderr text: semagic43\n"); + * exit (0); /* successful test run */ + * } + * g_test_trap_assert_passed(); + * g_test_trap_assert_stdout ("*somagic17*"); + * g_test_trap_assert_stderr ("*semagic43*"); + * } + * ]| + * + * This function is implemented only on Unix platforms. + * + * Returns: %TRUE for the forked child and %FALSE for the executing parent process. + * + * Since: 2.16 + */ +gboolean +g_test_trap_fork (guint64 usec_timeout, + GTestTrapFlags test_trap_flags) +{ +#ifdef G_OS_UNIX + gboolean pass_on_forked_log = FALSE; + int stdout_pipe[2] = { -1, -1 }; + int stderr_pipe[2] = { -1, -1 }; + int stdtst_pipe[2] = { -1, -1 }; + test_trap_clear(); + if (pipe (stdout_pipe) < 0 || pipe (stderr_pipe) < 0 || pipe (stdtst_pipe) < 0) + g_error ("failed to create pipes to fork test program: %s", g_strerror (errno)); + signal (SIGCHLD, SIG_DFL); + test_trap_last_pid = fork (); + if (test_trap_last_pid < 0) + g_error ("failed to fork test program: %s", g_strerror (errno)); + if (test_trap_last_pid == 0) /* child */ + { + int fd0 = -1; + close (stdout_pipe[0]); + close (stderr_pipe[0]); + close (stdtst_pipe[0]); + if (!(test_trap_flags & G_TEST_TRAP_INHERIT_STDIN)) + fd0 = open ("/dev/null", O_RDONLY); + if (sane_dup2 (stdout_pipe[1], 1) < 0 || sane_dup2 (stderr_pipe[1], 2) < 0 || (fd0 >= 0 && sane_dup2 (fd0, 0) < 0)) + g_error ("failed to dup2() in forked test program: %s", g_strerror (errno)); + if (fd0 >= 3) + close (fd0); + if (stdout_pipe[1] >= 3) + close (stdout_pipe[1]); + if (stderr_pipe[1] >= 3) + close (stderr_pipe[1]); + test_log_fd = stdtst_pipe[1]; + return TRUE; + } + else /* parent */ + { + GString *sout = g_string_new (NULL); + GString *serr = g_string_new (NULL); + guint64 sstamp; + int soutpos = 0, serrpos = 0, wr, need_wait = TRUE; + test_run_forks++; + close (stdout_pipe[1]); + close (stderr_pipe[1]); + close (stdtst_pipe[1]); + sstamp = test_time_stamp(); + /* read data until we get EOF on all pipes */ + while (stdout_pipe[0] >= 0 || stderr_pipe[0] >= 0 || stdtst_pipe[0] > 0) + { + fd_set fds; + struct timeval tv; + int ret; + FD_ZERO (&fds); + if (stdout_pipe[0] >= 0) + FD_SET (stdout_pipe[0], &fds); + if (stderr_pipe[0] >= 0) + FD_SET (stderr_pipe[0], &fds); + if (stdtst_pipe[0] >= 0) + FD_SET (stdtst_pipe[0], &fds); + tv.tv_sec = 0; + tv.tv_usec = MIN (usec_timeout ? usec_timeout : 1000000, 100 * 1000); /* sleep at most 0.5 seconds to catch clock skews, etc. */ + ret = select (MAX (MAX (stdout_pipe[0], stderr_pipe[0]), stdtst_pipe[0]) + 1, &fds, NULL, NULL, &tv); + if (ret < 0 && errno != EINTR) + { + g_warning ("Unexpected error in select() while reading from child process (%d): %s", test_trap_last_pid, g_strerror (errno)); + break; + } + if (stdout_pipe[0] >= 0 && FD_ISSET (stdout_pipe[0], &fds) && + g_string_must_read (sout, stdout_pipe[0]) == 0) + { + close (stdout_pipe[0]); + stdout_pipe[0] = -1; + } + if (stderr_pipe[0] >= 0 && FD_ISSET (stderr_pipe[0], &fds) && + g_string_must_read (serr, stderr_pipe[0]) == 0) + { + close (stderr_pipe[0]); + stderr_pipe[0] = -1; + } + if (stdtst_pipe[0] >= 0 && FD_ISSET (stdtst_pipe[0], &fds)) + { + guint8 buffer[4096]; + gint l, r = read (stdtst_pipe[0], buffer, sizeof (buffer)); + if (r > 0 && test_log_fd > 0) + do + l = write (pass_on_forked_log ? test_log_fd : -1, buffer, r); + while (l < 0 && errno == EINTR); + if (r == 0 || (r < 0 && errno != EINTR && errno != EAGAIN)) + { + close (stdtst_pipe[0]); + stdtst_pipe[0] = -1; + } + } + if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDOUT)) + g_string_write_out (sout, 1, &soutpos); + if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDERR)) + g_string_write_out (serr, 2, &serrpos); + if (usec_timeout) + { + guint64 nstamp = test_time_stamp(); + int status = 0; + sstamp = MIN (sstamp, nstamp); /* guard against backwards clock skews */ + if (usec_timeout < nstamp - sstamp) + { + /* timeout reached, need to abort the child now */ + kill_child (test_trap_last_pid, &status, 3); + test_trap_last_status = 1024; /* timeout */ + if (0 && WIFSIGNALED (status)) + g_printerr ("%s: child timed out and received: %s\n", G_STRFUNC, g_strsignal (WTERMSIG (status))); + need_wait = FALSE; + break; + } + } + } + if (stdout_pipe[0] != -1) + close (stdout_pipe[0]); + if (stderr_pipe[0] != -1) + close (stderr_pipe[0]); + if (stdtst_pipe[0] != -1) + close (stdtst_pipe[0]); + if (need_wait) + { + int status = 0; + do + wr = waitpid (test_trap_last_pid, &status, 0); + while (wr < 0 && errno == EINTR); + if (WIFEXITED (status)) /* normal exit */ + test_trap_last_status = WEXITSTATUS (status); /* 0..255 */ + else if (WIFSIGNALED (status)) + test_trap_last_status = (WTERMSIG (status) << 12); /* signalled */ + else /* WCOREDUMP (status) */ + test_trap_last_status = 512; /* coredump */ + } + test_trap_last_stdout = g_string_free (sout, FALSE); + test_trap_last_stderr = g_string_free (serr, FALSE); + return FALSE; + } +#else + g_message ("Not implemented: g_test_trap_fork"); + + return FALSE; +#endif +} + +/** + * g_test_trap_has_passed: + * + * Check the result of the last g_test_trap_fork() call. + * + * Returns: %TRUE if the last forked child terminated successfully. + * + * Since: 2.16 + */ +gboolean +g_test_trap_has_passed (void) +{ + return test_trap_last_status == 0; /* exit_status == 0 && !signal && !coredump */ +} + +/** + * g_test_trap_reached_timeout: + * + * Check the result of the last g_test_trap_fork() call. + * + * Returns: %TRUE if the last forked child got killed due to a fork timeout. + * + * Since: 2.16 + */ +gboolean +g_test_trap_reached_timeout (void) +{ + return 0 != (test_trap_last_status & 1024); /* timeout flag */ +} + +void +g_test_trap_assertions (const char *domain, + const char *file, + int line, + const char *func, + guint64 assertion_flags, /* 0-pass, 1-fail, 2-outpattern, 4-errpattern */ + const char *pattern) +{ +#ifdef G_OS_UNIX + gboolean must_pass = assertion_flags == 0; + gboolean must_fail = assertion_flags == 1; + gboolean match_result = 0 == (assertion_flags & 1); + const char *stdout_pattern = (assertion_flags & 2) ? pattern : NULL; + const char *stderr_pattern = (assertion_flags & 4) ? pattern : NULL; + const char *match_error = match_result ? "failed to match" : "contains invalid match"; + if (test_trap_last_pid == 0) + g_error ("child process failed to exit after g_test_trap_fork() and before g_test_trap_assert*()"); + if (must_pass && !g_test_trap_has_passed()) + { + char *msg = g_strdup_printf ("child process (%d) of test trap failed unexpectedly", test_trap_last_pid); + g_assertion_message (domain, file, line, func, msg); + g_free (msg); + } + if (must_fail && g_test_trap_has_passed()) + { + char *msg = g_strdup_printf ("child process (%d) did not fail as expected", test_trap_last_pid); + g_assertion_message (domain, file, line, func, msg); + g_free (msg); + } + if (stdout_pattern && match_result == !g_pattern_match_simple (stdout_pattern, test_trap_last_stdout)) + { + char *msg = g_strdup_printf ("stdout of child process (%d) %s: %s", test_trap_last_pid, match_error, stdout_pattern); + g_assertion_message (domain, file, line, func, msg); + g_free (msg); + } + if (stderr_pattern && match_result == !g_pattern_match_simple (stderr_pattern, test_trap_last_stderr)) + { + char *msg = g_strdup_printf ("stderr of child process (%d) %s: %s", test_trap_last_pid, match_error, stderr_pattern); + g_assertion_message (domain, file, line, func, msg); + g_free (msg); + } +#endif +} + +static void +gstring_overwrite_int (GString *gstring, + guint pos, + guint32 vuint) +{ + vuint = g_htonl (vuint); + g_string_overwrite_len (gstring, pos, (const gchar*) &vuint, 4); +} + +static void +gstring_append_int (GString *gstring, + guint32 vuint) +{ + vuint = g_htonl (vuint); + g_string_append_len (gstring, (const gchar*) &vuint, 4); +} + +static void +gstring_append_double (GString *gstring, + double vdouble) +{ + union { double vdouble; guint64 vuint64; } u; + u.vdouble = vdouble; + u.vuint64 = GUINT64_TO_BE (u.vuint64); + g_string_append_len (gstring, (const gchar*) &u.vuint64, 8); +} + +static guint8* +g_test_log_dump (GTestLogMsg *msg, + guint *len) +{ + GString *gstring = g_string_sized_new (1024); + guint ui; + gstring_append_int (gstring, 0); /* message length */ + gstring_append_int (gstring, msg->log_type); + gstring_append_int (gstring, msg->n_strings); + gstring_append_int (gstring, msg->n_nums); + gstring_append_int (gstring, 0); /* reserved */ + for (ui = 0; ui < msg->n_strings; ui++) + { + guint l = strlen (msg->strings[ui]); + gstring_append_int (gstring, l); + g_string_append_len (gstring, msg->strings[ui], l); + } + for (ui = 0; ui < msg->n_nums; ui++) + gstring_append_double (gstring, msg->nums[ui]); + *len = gstring->len; + gstring_overwrite_int (gstring, 0, *len); /* message length */ + return (guint8*) g_string_free (gstring, FALSE); +} + +static inline long double +net_double (const gchar **ipointer) +{ + union { guint64 vuint64; double vdouble; } u; + guint64 aligned_int64; + memcpy (&aligned_int64, *ipointer, 8); + *ipointer += 8; + u.vuint64 = GUINT64_FROM_BE (aligned_int64); + return u.vdouble; +} + +static inline guint32 +net_int (const gchar **ipointer) +{ + guint32 aligned_int; + memcpy (&aligned_int, *ipointer, 4); + *ipointer += 4; + return g_ntohl (aligned_int); +} + +static gboolean +g_test_log_extract (GTestLogBuffer *tbuffer) +{ + const gchar *p = tbuffer->data->str; + GTestLogMsg msg; + guint mlength; + if (tbuffer->data->len < 4 * 5) + return FALSE; + mlength = net_int (&p); + if (tbuffer->data->len < mlength) + return FALSE; + msg.log_type = net_int (&p); + msg.n_strings = net_int (&p); + msg.n_nums = net_int (&p); + if (net_int (&p) == 0) + { + guint ui; + msg.strings = g_new0 (gchar*, msg.n_strings + 1); + msg.nums = g_new0 (long double, msg.n_nums); + for (ui = 0; ui < msg.n_strings; ui++) + { + guint sl = net_int (&p); + msg.strings[ui] = g_strndup (p, sl); + p += sl; + } + for (ui = 0; ui < msg.n_nums; ui++) + msg.nums[ui] = net_double (&p); + if (p <= tbuffer->data->str + mlength) + { + g_string_erase (tbuffer->data, 0, mlength); + tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg))); + return TRUE; + } + } + g_free (msg.nums); + g_strfreev (msg.strings); + g_error ("corrupt log stream from test program"); + return FALSE; +} + +/** + * g_test_log_buffer_new: + * + * Internal function for gtester to decode test log messages, no ABI guarantees provided. + */ +GTestLogBuffer* +g_test_log_buffer_new (void) +{ + GTestLogBuffer *tb = g_new0 (GTestLogBuffer, 1); + tb->data = g_string_sized_new (1024); + return tb; +} + +/** + * g_test_log_buffer_free + * + * Internal function for gtester to free test log messages, no ABI guarantees provided. + */ +void +g_test_log_buffer_free (GTestLogBuffer *tbuffer) +{ + g_return_if_fail (tbuffer != NULL); + while (tbuffer->msgs) + g_test_log_msg_free (g_test_log_buffer_pop (tbuffer)); + g_string_free (tbuffer->data, TRUE); + g_free (tbuffer); +} + +/** + * g_test_log_buffer_push + * + * Internal function for gtester to decode test log messages, no ABI guarantees provided. + */ +void +g_test_log_buffer_push (GTestLogBuffer *tbuffer, + guint n_bytes, + const guint8 *bytes) +{ + g_return_if_fail (tbuffer != NULL); + if (n_bytes) + { + gboolean more_messages; + g_return_if_fail (bytes != NULL); + g_string_append_len (tbuffer->data, (const gchar*) bytes, n_bytes); + do + more_messages = g_test_log_extract (tbuffer); + while (more_messages); + } +} + +/** + * g_test_log_buffer_pop: + * + * Internal function for gtester to retrieve test log messages, no ABI guarantees provided. + */ +GTestLogMsg* +g_test_log_buffer_pop (GTestLogBuffer *tbuffer) +{ + GTestLogMsg *msg = NULL; + g_return_val_if_fail (tbuffer != NULL, NULL); + if (tbuffer->msgs) + { + GSList *slist = g_slist_last (tbuffer->msgs); + msg = slist->data; + tbuffer->msgs = g_slist_delete_link (tbuffer->msgs, slist); + } + return msg; +} + +/** + * g_test_log_msg_free: + * + * Internal function for gtester to free test log messages, no ABI guarantees provided. + */ +void +g_test_log_msg_free (GTestLogMsg *tmsg) +{ + g_return_if_fail (tmsg != NULL); + g_strfreev (tmsg->strings); + g_free (tmsg->nums); + g_free (tmsg); +} + +/* --- macros docs START --- */ +/** + * g_test_add: + * @testpath: The test path for a new test case. + * @Fixture: The type of a fixture data structure. + * @tdata: Data argument for the test functions. + * @fsetup: The function to set up the fixture data. + * @ftest: The actual test function. + * @fteardown: The function to tear down the fixture data. + * + * Hook up a new test case at @testpath, similar to g_test_add_func(). + * A fixture data structure with setup and teardown function may be provided + * though, similar to g_test_create_case(). + * g_test_add() is implemented as a macro, so that the fsetup(), ftest() and + * fteardown() callbacks can expect a @Fixture pointer as first argument in + * a type safe manner. + * + * Since: 2.16 + **/ +/* --- macros docs END --- */ diff --git a/glib/glib/gtestutils.h b/glib/glib/gtestutils.h new file mode 100644 index 0000000..3cd173c --- /dev/null +++ b/glib/glib/gtestutils.h @@ -0,0 +1,301 @@ +/* GLib testing utilities + * Copyright (C) 2007 Imendio AB + * Authors: Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_TEST_UTILS_H__ +#define __G_TEST_UTILS_H__ + +#include +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct GTestCase GTestCase; +typedef struct GTestSuite GTestSuite; +typedef void (*GTestFunc) (void); +typedef void (*GTestDataFunc) (gconstpointer user_data); +typedef void (*GTestFixtureFunc) (gpointer fixture, + gconstpointer user_data); + +/* assertion API */ +#define g_assert_cmpstr(s1, cmp, s2) do { const char *__s1 = (s1), *__s2 = (s2); \ + if (g_strcmp0 (__s1, __s2) cmp 0) ; else \ + g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #s1 " " #cmp " " #s2, __s1, #cmp, __s2); } while (0) +#define g_assert_cmpint(n1, cmp, n2) do { gint64 __n1 = (n1), __n2 = (n2); \ + if (__n1 cmp __n2) ; else \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); } while (0) +#define g_assert_cmpuint(n1, cmp, n2) do { guint64 __n1 = (n1), __n2 = (n2); \ + if (__n1 cmp __n2) ; else \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); } while (0) +#define g_assert_cmphex(n1, cmp, n2) do { guint64 __n1 = (n1), __n2 = (n2); \ + if (__n1 cmp __n2) ; else \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'x'); } while (0) +#define g_assert_cmpfloat(n1,cmp,n2) do { long double __n1 = (n1), __n2 = (n2); \ + if (__n1 cmp __n2) ; else \ + g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'f'); } while (0) +#define g_assert_no_error(err) do { if (err) \ + g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #err, err, 0, 0); } while (0) +#define g_assert_error(err, dom, c) do { if (!err || (err)->domain != dom || (err)->code != c) \ + g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #err, err, dom, c); } while (0) +#ifdef G_DISABLE_ASSERT +#define g_assert_not_reached() do { (void) 0; } while (0) +#define g_assert(expr) do { (void) 0; } while (0) +#else /* !G_DISABLE_ASSERT */ +#define g_assert_not_reached() do { g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, NULL); } while (0) +#define g_assert(expr) do { if G_LIKELY (expr) ; else \ + g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \ + #expr); } while (0) +#endif /* !G_DISABLE_ASSERT */ + +int g_strcmp0 (const char *str1, + const char *str2); + +/* report performance results */ +void g_test_minimized_result (double minimized_quantity, + const char *format, + ...) G_GNUC_PRINTF (2, 3); +void g_test_maximized_result (double maximized_quantity, + const char *format, + ...) G_GNUC_PRINTF (2, 3); + +/* initialize testing framework */ +void g_test_init (int *argc, + char ***argv, + ...); +/* query testing framework config */ +#define g_test_quick() (g_test_config_vars->test_quick) +#define g_test_slow() (!g_test_config_vars->test_quick) +#define g_test_thorough() (!g_test_config_vars->test_quick) +#define g_test_perf() (g_test_config_vars->test_perf) +#define g_test_verbose() (g_test_config_vars->test_verbose) +#define g_test_quiet() (g_test_config_vars->test_quiet) +#define g_test_undefined() (g_test_config_vars->test_undefined) +/* run all tests under toplevel suite (path: /) */ +int g_test_run (void); +/* hook up a test functions under test path */ +void g_test_add_func (const char *testpath, + GTestFunc test_func); + +void g_test_add_data_func (const char *testpath, + gconstpointer test_data, + GTestDataFunc test_func); +/* tell about failure */ +void g_test_fail (void); + +/* hook up a test with fixture under test path */ +#define g_test_add(testpath, Fixture, tdata, fsetup, ftest, fteardown) \ + G_STMT_START { \ + void (*add_vtable) (const char*, \ + gsize, \ + gconstpointer, \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer), \ + void (*) (Fixture*, gconstpointer)) = (void (*) (const gchar *, gsize, gconstpointer, void (*) (Fixture*, gconstpointer), void (*) (Fixture*, gconstpointer), void (*) (Fixture*, gconstpointer))) g_test_add_vtable; \ + add_vtable \ + (testpath, sizeof (Fixture), tdata, fsetup, ftest, fteardown); \ + } G_STMT_END + +/* add test messages to the test report */ +void g_test_message (const char *format, + ...) G_GNUC_PRINTF (1, 2); +void g_test_bug_base (const char *uri_pattern); +void g_test_bug (const char *bug_uri_snippet); +/* measure test timings */ +void g_test_timer_start (void); +double g_test_timer_elapsed (void); /* elapsed seconds */ +double g_test_timer_last (void); /* repeat last elapsed() result */ + +/* automatically g_free or g_object_unref upon teardown */ +void g_test_queue_free (gpointer gfree_pointer); +void g_test_queue_destroy (GDestroyNotify destroy_func, + gpointer destroy_data); +#define g_test_queue_unref(gobject) g_test_queue_destroy (g_object_unref, gobject) + +/* test traps are guards used around forked tests */ +typedef enum { + G_TEST_TRAP_SILENCE_STDOUT = 1 << 7, + G_TEST_TRAP_SILENCE_STDERR = 1 << 8, + G_TEST_TRAP_INHERIT_STDIN = 1 << 9 +} GTestTrapFlags; +gboolean g_test_trap_fork (guint64 usec_timeout, + GTestTrapFlags test_trap_flags); +gboolean g_test_trap_has_passed (void); +gboolean g_test_trap_reached_timeout (void); +#define g_test_trap_assert_passed() g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 0, 0) +#define g_test_trap_assert_failed() g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 1, 0) +#define g_test_trap_assert_stdout(soutpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 2, soutpattern) +#define g_test_trap_assert_stdout_unmatched(soutpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 3, soutpattern) +#define g_test_trap_assert_stderr(serrpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 4, serrpattern) +#define g_test_trap_assert_stderr_unmatched(serrpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 5, serrpattern) + +/* provide seed-able random numbers for tests */ +#define g_test_rand_bit() (0 != (g_test_rand_int() & (1 << 15))) +gint32 g_test_rand_int (void); +gint32 g_test_rand_int_range (gint32 begin, + gint32 end); +double g_test_rand_double (void); +double g_test_rand_double_range (double range_start, + double range_end); + +/* semi-internal API */ +GTestCase* g_test_create_case (const char *test_name, + gsize data_size, + gconstpointer test_data, + GTestFixtureFunc data_setup, + GTestFixtureFunc data_test, + GTestFixtureFunc data_teardown); +GTestSuite* g_test_create_suite (const char *suite_name); +GTestSuite* g_test_get_root (void); +void g_test_suite_add (GTestSuite *suite, + GTestCase *test_case); +void g_test_suite_add_suite (GTestSuite *suite, + GTestSuite *nestedsuite); +int g_test_run_suite (GTestSuite *suite); + +/* internal ABI */ +void g_test_trap_assertions (const char *domain, + const char *file, + int line, + const char *func, + guint64 assertion_flags, /* 0-pass, 1-fail, 2-outpattern, 4-errpattern */ + const char *pattern); +void g_assertion_message (const char *domain, + const char *file, + int line, + const char *func, + const char *message) G_GNUC_NORETURN; +void g_assertion_message_expr (const char *domain, + const char *file, + int line, + const char *func, + const char *expr) G_GNUC_NORETURN; +void g_assertion_message_cmpstr (const char *domain, + const char *file, + int line, + const char *func, + const char *expr, + const char *arg1, + const char *cmp, + const char *arg2) G_GNUC_NORETURN; +void g_assertion_message_cmpnum (const char *domain, + const char *file, + int line, + const char *func, + const char *expr, + long double arg1, + const char *cmp, + long double arg2, + char numtype) G_GNUC_NORETURN; +void g_assertion_message_error (const char *domain, + const char *file, + int line, + const char *func, + const char *expr, + const GError *error, + GQuark error_domain, + int error_code) G_GNUC_NORETURN; +void g_test_add_vtable (const char *testpath, + gsize data_size, + gconstpointer test_data, + GTestFixtureFunc data_setup, + GTestFixtureFunc data_test, + GTestFixtureFunc data_teardown); +typedef struct { + gboolean test_initialized; + gboolean test_quick; /* disable thorough tests */ + gboolean test_perf; /* run performance tests */ + gboolean test_verbose; /* extra info */ + gboolean test_quiet; /* reduce output */ + gboolean test_undefined; /* run tests that are meant to assert */ +} GTestConfig; +GLIB_VAR const GTestConfig * const g_test_config_vars; + +/* internal logging API */ +typedef enum { + G_TEST_LOG_NONE, + G_TEST_LOG_ERROR, /* s:msg */ + G_TEST_LOG_START_BINARY, /* s:binaryname s:seed */ + G_TEST_LOG_LIST_CASE, /* s:testpath */ + G_TEST_LOG_SKIP_CASE, /* s:testpath */ + G_TEST_LOG_START_CASE, /* s:testpath */ + G_TEST_LOG_STOP_CASE, /* d:status d:nforks d:elapsed */ + G_TEST_LOG_MIN_RESULT, /* s:blurb d:result */ + G_TEST_LOG_MAX_RESULT, /* s:blurb d:result */ + G_TEST_LOG_MESSAGE /* s:blurb */ +} GTestLogType; + +typedef struct { + GTestLogType log_type; + guint n_strings; + gchar **strings; /* NULL terminated */ + guint n_nums; + long double *nums; +} GTestLogMsg; +typedef struct { + /*< private >*/ + GString *data; + GSList *msgs; +} GTestLogBuffer; + +const char* g_test_log_type_name (GTestLogType log_type); +GTestLogBuffer* g_test_log_buffer_new (void); +void g_test_log_buffer_free (GTestLogBuffer *tbuffer); +void g_test_log_buffer_push (GTestLogBuffer *tbuffer, + guint n_bytes, + const guint8 *bytes); +GTestLogMsg* g_test_log_buffer_pop (GTestLogBuffer *tbuffer); +void g_test_log_msg_free (GTestLogMsg *tmsg); + +/** + * GTestLogFatalFunc: + * @log_domain: the log domain of the message + * @log_level: the log level of the message (including the fatal and recursion flags) + * @message: the message to process + * @user_data: user data, set in g_test_log_set_fatal_handler() + * + * Specifies the prototype of fatal log handler functions. + * + * Return value: %TRUE if the program should abort, %FALSE otherwise + * + * Since: 2.22 + */ +typedef gboolean (*GTestLogFatalFunc) (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data); +void +g_test_log_set_fatal_handler (GTestLogFatalFunc log_func, + gpointer user_data); + +G_END_DECLS + +#endif /* __G_TEST_UTILS_H__ */ diff --git a/glib/glib/gthread-posix.c b/glib/glib/gthread-posix.c new file mode 100644 index 0000000..9500709 --- /dev/null +++ b/glib/glib/gthread-posix.c @@ -0,0 +1,1180 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: posix thread system implementation + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* The GMutex, GCond and GPrivate implementations in this file are some + * of the lowest-level code in GLib. All other parts of GLib (messages, + * memory, slices, etc) assume that they can freely use these facilities + * without risking recursion. + * + * As such, these functions are NOT permitted to call any other part of + * GLib. + * + * The thread manipulation functions (create, exit, join, etc.) have + * more freedom -- they can do as they please. + */ + +#include "config.h" + +#include "gthread.h" + +#include "gthreadprivate.h" +#include "gslice.h" +#include "gmessages.h" +#include "gstrfuncs.h" + +#include +#include +#include +#include +#include + +#ifdef HAVE_SYS_TIME_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SCHED_H +#include +#endif +#ifdef HAVE_SYS_PRCTL_H +#include +#endif + +static void +g_thread_abort (gint status, + const gchar *function) +{ + fprintf (stderr, "GLib (gthread-posix.c): Unexpected error from C library during '%s': %s. Aborting.\n", + function, strerror (status)); + abort (); +} + +/* {{{1 GMutex */ + +static pthread_mutex_t * +g_mutex_impl_new (void) +{ + pthread_mutexattr_t *pattr = NULL; + pthread_mutex_t *mutex; + gint status; + + mutex = malloc (sizeof (pthread_mutex_t)); + if G_UNLIKELY (mutex == NULL) + g_thread_abort (errno, "malloc"); + +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP + pthread_mutexattr_t attr; + pthread_mutexattr_init (&attr); + pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + pattr = &attr; +#endif + + if G_UNLIKELY ((status = pthread_mutex_init (mutex, pattr)) != 0) + g_thread_abort (status, "pthread_mutex_init"); + +#ifdef PTHREAD_ADAPTIVE_MUTEX_NP + pthread_mutexattr_destroy (&attr); +#endif + + return mutex; +} + +static void +g_mutex_impl_free (pthread_mutex_t *mutex) +{ + pthread_mutex_destroy (mutex); + free (mutex); +} + +static pthread_mutex_t * +g_mutex_get_impl (GMutex *mutex) +{ + pthread_mutex_t *impl = mutex->p; + + if G_UNLIKELY (impl == NULL) + { + impl = g_mutex_impl_new (); + if (!g_atomic_pointer_compare_and_exchange (&mutex->p, NULL, impl)) + g_mutex_impl_free (impl); + impl = mutex->p; + } + + return impl; +} + + +/** + * g_mutex_init: + * @mutex: an uninitialized #GMutex + * + * Initializes a #GMutex so that it can be used. + * + * This function is useful to initialize a mutex that has been + * allocated on the stack, or as part of a larger structure. + * It is not necessary to initialize a mutex that has been + * created that has been statically allocated. + * + * |[ + * typedef struct { + * GMutex m; + * ... + * } Blob; + * + * Blob *b; + * + * b = g_new (Blob, 1); + * g_mutex_init (&b->m); + * ]| + * + * To undo the effect of g_mutex_init() when a mutex is no longer + * needed, use g_mutex_clear(). + * + * Calling g_mutex_init() on an already initialized #GMutex leads + * to undefined behaviour. + * + * Since: 2.32 + */ +void +g_mutex_init (GMutex *mutex) +{ + mutex->p = g_mutex_impl_new (); +} + +/** + * g_mutex_clear: + * @mutex: an initialized #GMutex + * + * Frees the resources allocated to a mutex with g_mutex_init(). + * + * This function should not be used with a #GMutex that has been + * statically allocated. + * + * Calling g_mutex_clear() on a locked mutex leads to undefined + * behaviour. + * + * Sine: 2.32 + */ +void +g_mutex_clear (GMutex *mutex) +{ + g_mutex_impl_free (mutex->p); +} + +/** + * g_mutex_lock: + * @mutex: a #GMutex + * + * Locks @mutex. If @mutex is already locked by another thread, the + * current thread will block until @mutex is unlocked by the other + * thread. + * + * #GMutex is neither guaranteed to be recursive nor to be + * non-recursive. As such, calling g_mutex_lock() on a #GMutex that has + * already been locked by the same thread results in undefined behaviour + * (including but not limited to deadlocks). + */ +void +g_mutex_lock (GMutex *mutex) +{ + gint status; + + if G_UNLIKELY ((status = pthread_mutex_lock (g_mutex_get_impl (mutex))) != 0) + g_thread_abort (status, "pthread_mutex_lock"); +} + +/** + * g_mutex_unlock: + * @mutex: a #GMutex + * + * Unlocks @mutex. If another thread is blocked in a g_mutex_lock() + * call for @mutex, it will become unblocked and can lock @mutex itself. + * + * Calling g_mutex_unlock() on a mutex that is not locked by the + * current thread leads to undefined behaviour. + */ +void +g_mutex_unlock (GMutex *mutex) +{ + gint status; + + if G_UNLIKELY ((status = pthread_mutex_unlock (g_mutex_get_impl (mutex))) != 0) + g_thread_abort (status, "pthread_mutex_lock"); +} + +/** + * g_mutex_trylock: + * @mutex: a #GMutex + * + * Tries to lock @mutex. If @mutex is already locked by another thread, + * it immediately returns %FALSE. Otherwise it locks @mutex and returns + * %TRUE. + * + * #GMutex is neither guaranteed to be recursive nor to be + * non-recursive. As such, calling g_mutex_lock() on a #GMutex that has + * already been locked by the same thread results in undefined behaviour + * (including but not limited to deadlocks or arbitrary return values). + * + + * Returns: %TRUE if @mutex could be locked + */ +gboolean +g_mutex_trylock (GMutex *mutex) +{ + gint status; + + if G_LIKELY ((status = pthread_mutex_trylock (g_mutex_get_impl (mutex))) == 0) + return TRUE; + + if G_UNLIKELY (status != EBUSY) + g_thread_abort (status, "pthread_mutex_trylock"); + + return FALSE; +} + +/* {{{1 GRecMutex */ + +static pthread_mutex_t * +g_rec_mutex_impl_new (void) +{ + pthread_mutexattr_t attr; + pthread_mutex_t *mutex; + + mutex = g_slice_new (pthread_mutex_t); + pthread_mutexattr_init (&attr); + pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init (mutex, &attr); + pthread_mutexattr_destroy (&attr); + + return mutex; +} + +static void +g_rec_mutex_impl_free (pthread_mutex_t *mutex) +{ + pthread_mutex_destroy (mutex); + g_slice_free (pthread_mutex_t, mutex); +} + +static pthread_mutex_t * +g_rec_mutex_get_impl (GRecMutex *rec_mutex) +{ + pthread_mutex_t *impl = rec_mutex->p; + + if G_UNLIKELY (impl == NULL) + { + impl = g_rec_mutex_impl_new (); + if (!g_atomic_pointer_compare_and_exchange (&rec_mutex->p, NULL, impl)) + g_rec_mutex_impl_free (impl); + impl = rec_mutex->p; + } + + return impl; +} + +/** + * g_rec_mutex_init: + * @rec_mutex: an uninitialized #GRecMutex + * + * Initializes a #GRecMutex so that it can be used. + * + * This function is useful to initialize a recursive mutex + * that has been allocated on the stack, or as part of a larger + * structure. + * + * It is not necessary to initialise a recursive mutex that has been + * statically allocated. + * + * |[ + * typedef struct { + * GRecMutex m; + * ... + * } Blob; + * + * Blob *b; + * + * b = g_new (Blob, 1); + * g_rec_mutex_init (&b->m); + * ]| + * + * Calling g_rec_mutex_init() on an already initialized #GRecMutex + * leads to undefined behaviour. + * + * To undo the effect of g_rec_mutex_init() when a recursive mutex + * is no longer needed, use g_rec_mutex_clear(). + * + * Since: 2.32 + */ +void +g_rec_mutex_init (GRecMutex *rec_mutex) +{ + rec_mutex->p = g_rec_mutex_impl_new (); +} + +/** + * g_rec_mutex_clear: + * @rec_mutex: an initialized #GRecMutex + * + * Frees the resources allocated to a recursive mutex with + * g_rec_mutex_init(). + * + * This function should not be used with a #GRecMutex that has been + * statically allocated. + * + * Calling g_rec_mutex_clear() on a locked recursive mutex leads + * to undefined behaviour. + * + * Sine: 2.32 + */ +void +g_rec_mutex_clear (GRecMutex *rec_mutex) +{ + g_rec_mutex_impl_free (rec_mutex->p); +} + +/** + * g_rec_mutex_lock: + * @rec_mutex: a #GRecMutex + * + * Locks @rec_mutex. If @rec_mutex is already locked by another + * thread, the current thread will block until @rec_mutex is + * unlocked by the other thread. If @rec_mutex is already locked + * by the current thread, the 'lock count' of @rec_mutex is increased. + * The mutex will only become available again when it is unlocked + * as many times as it has been locked. + * + * Since: 2.32 + */ +void +g_rec_mutex_lock (GRecMutex *mutex) +{ + pthread_mutex_lock (g_rec_mutex_get_impl (mutex)); +} + +/** + * g_rec_mutex_unlock: + * @rec_mutex: a #GRecMutex + * + * Unlocks @rec_mutex. If another thread is blocked in a + * g_rec_mutex_lock() call for @rec_mutex, it will become unblocked + * and can lock @rec_mutex itself. + * + * Calling g_rec_mutex_unlock() on a recursive mutex that is not + * locked by the current thread leads to undefined behaviour. + * + * Since: 2.32 + */ +void +g_rec_mutex_unlock (GRecMutex *rec_mutex) +{ + pthread_mutex_unlock (rec_mutex->p); +} + +/** + * g_rec_mutex_trylock: + * @rec_mutex: a #GRecMutex + * + * Tries to lock @rec_mutex. If @rec_mutex is already locked + * by another thread, it immediately returns %FALSE. Otherwise + * it locks @rec_mutex and returns %TRUE. + * + * Returns: %TRUE if @rec_mutex could be locked + * + * Since: 2.32 + */ +gboolean +g_rec_mutex_trylock (GRecMutex *rec_mutex) +{ + if (pthread_mutex_trylock (g_rec_mutex_get_impl (rec_mutex)) != 0) + return FALSE; + + return TRUE; +} + +/* {{{1 GRWLock */ + +static pthread_rwlock_t * +g_rw_lock_impl_new (void) +{ + pthread_rwlock_t *rwlock; + gint status; + + rwlock = malloc (sizeof (pthread_rwlock_t)); + if G_UNLIKELY (rwlock == NULL) + g_thread_abort (errno, "malloc"); + + if G_UNLIKELY ((status = pthread_rwlock_init (rwlock, NULL)) != 0) + g_thread_abort (status, "pthread_rwlock_init"); + + return rwlock; +} + +static void +g_rw_lock_impl_free (pthread_rwlock_t *rwlock) +{ + pthread_rwlock_destroy (rwlock); + free (rwlock); +} + +static pthread_rwlock_t * +g_rw_lock_get_impl (GRWLock *lock) +{ + pthread_rwlock_t *impl = lock->p; + + if G_UNLIKELY (impl == NULL) + { + impl = g_rw_lock_impl_new (); + if (!g_atomic_pointer_compare_and_exchange (&lock->p, NULL, impl)) + g_rw_lock_impl_free (impl); + impl = lock->p; + } + + return impl; +} + +/** + * g_rw_lock_init: + * @rw_lock: an uninitialized #GRWLock + * + * Initializes a #GRWLock so that it can be used. + * + * This function is useful to initialize a lock that has been + * allocated on the stack, or as part of a larger structure. It is not + * necessary to initialise a reader-writer lock that has been statically + * allocated. + * + * |[ + * typedef struct { + * GRWLock l; + * ... + * } Blob; + * + * Blob *b; + * + * b = g_new (Blob, 1); + * g_rw_lock_init (&b->l); + * ]| + * + * To undo the effect of g_rw_lock_init() when a lock is no longer + * needed, use g_rw_lock_clear(). + * + * Calling g_rw_lock_init() on an already initialized #GRWLock leads + * to undefined behaviour. + * + * Since: 2.32 + */ +void +g_rw_lock_init (GRWLock *rw_lock) +{ + rw_lock->p = g_rw_lock_impl_new (); +} + +/** + * g_rw_lock_clear: + * @rw_lock: an initialized #GRWLock + * + * Frees the resources allocated to a lock with g_rw_lock_init(). + * + * This function should not be used with a #GRWLock that has been + * statically allocated. + * + * Calling g_rw_lock_clear() when any thread holds the lock + * leads to undefined behaviour. + * + * Sine: 2.32 + */ +void +g_rw_lock_clear (GRWLock *rw_lock) +{ + g_rw_lock_impl_free (rw_lock->p); +} + +/** + * g_rw_lock_writer_lock: + * @rw_lock: a #GRWLock + * + * Obtain a write lock on @rw_lock. If any thread already holds + * a read or write lock on @rw_lock, the current thread will block + * until all other threads have dropped their locks on @rw_lock. + * + * Since: 2.32 + */ +void +g_rw_lock_writer_lock (GRWLock *rw_lock) +{ + pthread_rwlock_wrlock (g_rw_lock_get_impl (rw_lock)); +} + +/** + * g_rw_lock_writer_trylock: + * @rw_lock: a #GRWLock + * + * Tries to obtain a write lock on @rw_lock. If any other thread holds + * a read or write lock on @rw_lock, it immediately returns %FALSE. + * Otherwise it locks @rw_lock and returns %TRUE. + * + * Returns: %TRUE if @rw_lock could be locked + * + * Since: 2.32 + */ +gboolean +g_rw_lock_writer_trylock (GRWLock *rw_lock) +{ + if (pthread_rwlock_trywrlock (g_rw_lock_get_impl (rw_lock)) != 0) + return FALSE; + + return TRUE; +} + +/** + * g_rw_lock_writer_unlock: + * @rw_lock: a #GRWLock + * + * Release a write lock on @rw_lock. + * + * Calling g_rw_lock_writer_unlock() on a lock that is not held + * by the current thread leads to undefined behaviour. + * + * Since: 2.32 + */ +void +g_rw_lock_writer_unlock (GRWLock *rw_lock) +{ + pthread_rwlock_unlock (g_rw_lock_get_impl (rw_lock)); +} + +/** + * g_rw_lock_reader_lock: + * @rw_lock: a #GRWLock + * + * Obtain a read lock on @rw_lock. If another thread currently holds + * the write lock on @rw_lock or blocks waiting for it, the current + * thread will block. Read locks can be taken recursively. + * + * It is implementation-defined how many threads are allowed to + * hold read locks on the same lock simultaneously. + * + * Since: 2.32 + */ +void +g_rw_lock_reader_lock (GRWLock *rw_lock) +{ + pthread_rwlock_rdlock (g_rw_lock_get_impl (rw_lock)); +} + +/** + * g_rw_lock_reader_trylock: + * @rw_lock: a #GRWLock + * + * Tries to obtain a read lock on @rw_lock and returns %TRUE if + * the read lock was successfully obtained. Otherwise it + * returns %FALSE. + * + * Returns: %TRUE if @rw_lock could be locked + * + * Since: 2.32 + */ +gboolean +g_rw_lock_reader_trylock (GRWLock *rw_lock) +{ + if (pthread_rwlock_tryrdlock (g_rw_lock_get_impl (rw_lock)) != 0) + return FALSE; + + return TRUE; +} + +/** + * g_rw_lock_reader_unlock: + * @rw_lock: a #GRWLock + * + * Release a read lock on @rw_lock. + * + * Calling g_rw_lock_reader_unlock() on a lock that is not held + * by the current thread leads to undefined behaviour. + * + * Since: 2.32 + */ +void +g_rw_lock_reader_unlock (GRWLock *rw_lock) +{ + pthread_rwlock_unlock (g_rw_lock_get_impl (rw_lock)); +} + +/* {{{1 GCond */ + +static pthread_cond_t * +g_cond_impl_new (void) +{ + pthread_condattr_t attr; + pthread_cond_t *cond; + gint status; + + pthread_condattr_init (&attr); +#if defined (HAVE_PTHREAD_CONDATTR_SETCLOCK) && defined (CLOCK_MONOTONIC) + pthread_condattr_setclock (&attr, CLOCK_MONOTONIC); +#endif + + cond = malloc (sizeof (pthread_cond_t)); + if G_UNLIKELY (cond == NULL) + g_thread_abort (errno, "malloc"); + + if G_UNLIKELY ((status = pthread_cond_init (cond, &attr)) != 0) + g_thread_abort (status, "pthread_cond_init"); + + pthread_condattr_destroy (&attr); + + return cond; +} + +static void +g_cond_impl_free (pthread_cond_t *cond) +{ + pthread_cond_destroy (cond); + free (cond); +} + +static pthread_cond_t * +g_cond_get_impl (GCond *cond) +{ + pthread_cond_t *impl = cond->p; + + if G_UNLIKELY (impl == NULL) + { + impl = g_cond_impl_new (); + if (!g_atomic_pointer_compare_and_exchange (&cond->p, NULL, impl)) + g_cond_impl_free (impl); + impl = cond->p; + } + + return impl; +} + +/** + * g_cond_init: + * @cond: an uninitialized #GCond + * + * Initialises a #GCond so that it can be used. + * + * This function is useful to initialise a #GCond that has been + * allocated as part of a larger structure. It is not necessary to + * initialise a #GCond that has been statically allocated. + * + * To undo the effect of g_cond_init() when a #GCond is no longer + * needed, use g_cond_clear(). + * + * Calling g_cond_init() on an already-initialised #GCond leads + * to undefined behaviour. + * + * Since: 2.32 + */ +void +g_cond_init (GCond *cond) +{ + cond->p = g_cond_impl_new (); +} + +/** + * g_cond_clear: + * @cond: an initialised #GCond + * + * Frees the resources allocated to a #GCond with g_cond_init(). + * + * This function should not be used with a #GCond that has been + * statically allocated. + * + * Calling g_cond_clear() for a #GCond on which threads are + * blocking leads to undefined behaviour. + * + * Since: 2.32 + */ +void +g_cond_clear (GCond *cond) +{ + g_cond_impl_free (cond->p); +} + +/** + * g_cond_wait: + * @cond: a #GCond + * @mutex: a #GMutex that is currently locked + * + * Atomically releases @mutex and waits until @cond is signalled. + * + * When using condition variables, it is possible that a spurious wakeup + * may occur (ie: g_cond_wait() returns even though g_cond_signal() was + * not called). It's also possible that a stolen wakeup may occur. + * This is when g_cond_signal() is called, but another thread acquires + * @mutex before this thread and modifies the state of the program in + * such a way that when g_cond_wait() is able to return, the expected + * condition is no longer met. + * + * For this reason, g_cond_wait() must always be used in a loop. See + * the documentation for #GCond for a complete example. + **/ +void +g_cond_wait (GCond *cond, + GMutex *mutex) +{ + gint status; + + if G_UNLIKELY ((status = pthread_cond_wait (g_cond_get_impl (cond), g_mutex_get_impl (mutex))) != 0) + g_thread_abort (status, "pthread_cond_wait"); +} + +/** + * g_cond_signal: + * @cond: a #GCond + * + * If threads are waiting for @cond, at least one of them is unblocked. + * If no threads are waiting for @cond, this function has no effect. + * It is good practice to hold the same lock as the waiting thread + * while calling this function, though not required. + */ +void +g_cond_signal (GCond *cond) +{ + gint status; + + if G_UNLIKELY ((status = pthread_cond_signal (g_cond_get_impl (cond))) != 0) + g_thread_abort (status, "pthread_cond_signal"); +} + +/** + * g_cond_broadcast: + * @cond: a #GCond + * + * If threads are waiting for @cond, all of them are unblocked. + * If no threads are waiting for @cond, this function has no effect. + * It is good practice to lock the same mutex as the waiting threads + * while calling this function, though not required. + */ +void +g_cond_broadcast (GCond *cond) +{ + gint status; + + if G_UNLIKELY ((status = pthread_cond_broadcast (g_cond_get_impl (cond))) != 0) + g_thread_abort (status, "pthread_cond_broadcast"); +} + +/** + * g_cond_wait_until: + * @cond: a #GCond + * @mutex: a #GMutex that is currently locked + * @end_time: the monotonic time to wait until + * + * Waits until either @cond is signalled or @end_time has passed. + * + * As with g_cond_wait() it is possible that a spurious or stolen wakeup + * could occur. For that reason, waiting on a condition variable should + * always be in a loop, based on an explicitly-checked predicate. + * + * %TRUE is returned if the condition variable was signalled (or in the + * case of a spurious wakeup). %FALSE is returned if @end_time has + * passed. + * + * The following code shows how to correctly perform a timed wait on a + * condition variable (extended the example presented in the + * documentation for #GCond): + * + * |[ + * gpointer + * pop_data_timed (void) + * { + * gint64 end_time; + * gpointer data; + * + * g_mutex_lock (&data_mutex); + * + * end_time = g_get_monotonic_time () + 5 * G_TIME_SPAN_SECOND; + * while (!current_data) + * if (!g_cond_wait_until (&data_cond, &data_mutex, end_time)) + * { + * // timeout has passed. + * g_mutex_unlock (&data_mutex); + * return NULL; + * } + * + * // there is data for us + * data = current_data; + * current_data = NULL; + * + * g_mutex_unlock (&data_mutex); + * + * return data; + * } + * ]| + * + * Notice that the end time is calculated once, before entering the + * loop and reused. This is the motivation behind the use of absolute + * time on this API -- if a relative time of 5 seconds were passed + * directly to the call and a spurious wakeup occurred, the program would + * have to start over waiting again (which would lead to a total wait + * time of more than 5 seconds). + * + * Returns: %TRUE on a signal, %FALSE on a timeout + * Since: 2.32 + **/ +gboolean +g_cond_wait_until (GCond *cond, + GMutex *mutex, + gint64 end_time) +{ + struct timespec ts; + gint status; + + ts.tv_sec = end_time / 1000000; + ts.tv_nsec = (end_time % 1000000) * 1000; + + if ((status = pthread_cond_timedwait (g_cond_get_impl (cond), g_mutex_get_impl (mutex), &ts)) == 0) + return TRUE; + + if G_UNLIKELY (status != ETIMEDOUT) + g_thread_abort (status, "pthread_cond_timedwait"); + + return FALSE; +} + +/* {{{1 GPrivate */ + +/** + * GPrivate: + * + * The #GPrivate struct is an opaque data structure to represent a + * thread-local data key. It is approximately equivalent to the + * pthread_setspecific()/pthread_getspecific() APIs on POSIX and to + * TlsSetValue()/TlsGetValue() on Windows. + * + * If you don't already know why you might want this functionality, + * then you probably don't need it. + * + * #GPrivate is a very limited resource (as far as 128 per program, + * shared between all libraries). It is also not possible to destroy a + * #GPrivate after it has been used. As such, it is only ever acceptable + * to use #GPrivate in static scope, and even then sparingly so. + * + * See G_PRIVATE_INIT() for a couple of examples. + * + * The #GPrivate structure should be considered opaque. It should only + * be accessed via the g_private_ functions. + */ + +/** + * G_PRIVATE_INIT: + * @notify: a #GDestroyNotify + * + * A macro to assist with the static initialisation of a #GPrivate. + * + * This macro is useful for the case that a #GDestroyNotify function + * should be associated the key. This is needed when the key will be + * used to point at memory that should be deallocated when the thread + * exits. + * + * Additionally, the #GDestroyNotify will also be called on the previous + * value stored in the key when g_private_replace() is used. + * + * If no #GDestroyNotify is needed, then use of this macro is not + * required -- if the #GPrivate is declared in static scope then it will + * be properly initialised by default (ie: to all zeros). See the + * examples below. + * + * |[ + * static GPrivate name_key = G_PRIVATE_INIT (g_free); + * + * // return value should not be freed + * const gchar * + * get_local_name (void) + * { + * return g_private_get (&name_key); + * } + * + * void + * set_local_name (const gchar *name) + * { + * g_private_replace (&name_key, g_strdup (name)); + * } + * + * + * static GPrivate count_key; // no free function + * + * gint + * get_local_count (void) + * { + * return GPOINTER_TO_INT (g_private_get (&count_key)); + * } + * + * void + * set_local_count (gint count) + * { + * g_private_set (&count_key, GINT_TO_POINTER (count)); + * } + * ]| + * + * Since: 2.32 + **/ + +static pthread_key_t * +g_private_impl_new (GDestroyNotify notify) +{ + pthread_key_t *key; + gint status; + + key = malloc (sizeof (pthread_key_t)); + if G_UNLIKELY (key == NULL) + g_thread_abort (errno, "malloc"); + status = pthread_key_create (key, notify); + if G_UNLIKELY (status != 0) + g_thread_abort (status, "pthread_key_create"); + + return key; +} + +static void +g_private_impl_free (pthread_key_t *key) +{ + gint status; + + status = pthread_key_delete (*key); + if G_UNLIKELY (status != 0) + g_thread_abort (status, "pthread_key_delete"); + free (key); +} + +static pthread_key_t * +g_private_get_impl (GPrivate *key) +{ + pthread_key_t *impl = key->p; + + if G_UNLIKELY (impl == NULL) + { + impl = g_private_impl_new (key->notify); + if (!g_atomic_pointer_compare_and_exchange (&key->p, NULL, impl)) + { + g_private_impl_free (impl); + impl = key->p; + } + } + + return impl; +} + +/** + * g_private_get: + * @key: a #GPrivate + * + * Returns the current value of the thread local variable @key. + * + * If the value has not yet been set in this thread, %NULL is returned. + * Values are never copied between threads (when a new thread is + * created, for example). + * + * Returns: the thread-local value + */ +gpointer +g_private_get (GPrivate *key) +{ + /* quote POSIX: No errors are returned from pthread_getspecific(). */ + return pthread_getspecific (*g_private_get_impl (key)); +} + +/** + * g_private_set: + * @key: a #GPrivate + * @value: the new value + * + * Sets the thread local variable @key to have the value @value in the + * current thread. + * + * This function differs from g_private_replace() in the following way: + * the #GDestroyNotify for @key is not called on the old value. + */ +void +g_private_set (GPrivate *key, + gpointer value) +{ + gint status; + + if G_UNLIKELY ((status = pthread_setspecific (*g_private_get_impl (key), value)) != 0) + g_thread_abort (status, "pthread_setspecific"); +} + +/** + * g_private_replace: + * @key: a #GPrivate + * @value: the new value + * + * Sets the thread local variable @key to have the value @value in the + * current thread. + * + * This function differs from g_private_set() in the following way: if + * the previous value was non-%NULL then the #GDestroyNotify handler for + * @key is run on it. + * + * Since: 2.32 + **/ +void +g_private_replace (GPrivate *key, + gpointer value) +{ + pthread_key_t *impl = g_private_get_impl (key); + gpointer old; + gint status; + + old = pthread_getspecific (*impl); + if (old && key->notify) + key->notify (old); + + if G_UNLIKELY ((status = pthread_setspecific (*impl, value)) != 0) + g_thread_abort (status, "pthread_setspecific"); +} + +/* {{{1 GThread */ + +#define posix_check_err(err, name) G_STMT_START{ \ + int error = (err); \ + if (error) \ + g_error ("file %s: line %d (%s): error '%s' during '%s'", \ + __FILE__, __LINE__, G_STRFUNC, \ + g_strerror (error), name); \ + }G_STMT_END + +#define posix_check_cmd(cmd) posix_check_err (cmd, #cmd) + +typedef struct +{ + GRealThread thread; + + pthread_t system_thread; + gboolean joined; + GMutex lock; +} GThreadPosix; + +void +g_system_thread_free (GRealThread *thread) +{ + GThreadPosix *pt = (GThreadPosix *) thread; + + if (!pt->joined) + pthread_detach (pt->system_thread); + + g_mutex_clear (&pt->lock); + + g_slice_free (GThreadPosix, pt); +} + +GRealThread * +g_system_thread_new (GThreadFunc thread_func, + gulong stack_size, + GError **error) +{ + GThreadPosix *thread; + pthread_attr_t attr; + gint ret; + + thread = g_slice_new0 (GThreadPosix); + + posix_check_cmd (pthread_attr_init (&attr)); + +#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE + if (stack_size) + { +#ifdef _SC_THREAD_STACK_MIN + stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), stack_size); +#endif /* _SC_THREAD_STACK_MIN */ + /* No error check here, because some systems can't do it and + * we simply don't want threads to fail because of that. */ + pthread_attr_setstacksize (&attr, stack_size); + } +#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */ + + ret = pthread_create (&thread->system_thread, &attr, (void* (*)(void*))thread_func, thread); + + posix_check_cmd (pthread_attr_destroy (&attr)); + + if (ret == EAGAIN) + { + g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, + "Error creating thread: %s", g_strerror (ret)); + g_slice_free (GThreadPosix, thread); + return NULL; + } + + posix_check_err (ret, "pthread_create"); + + g_mutex_init (&thread->lock); + + return (GRealThread *) thread; +} + +/** + * g_thread_yield: + * + * Causes the calling thread to voluntarily relinquish the CPU, so + * that other threads can run. + * + * This function is often used as a method to make busy wait less evil. + */ +void +g_thread_yield (void) +{ + sched_yield (); +} + +void +g_system_thread_wait (GRealThread *thread) +{ + GThreadPosix *pt = (GThreadPosix *) thread; + + g_mutex_lock (&pt->lock); + + if (!pt->joined) + { + posix_check_cmd (pthread_join (pt->system_thread, NULL)); + pt->joined = TRUE; + } + + g_mutex_unlock (&pt->lock); +} + +void +g_system_thread_exit (void) +{ + pthread_exit (NULL); +} + +void +g_system_thread_set_name (const gchar *name) +{ +#ifdef HAVE_SYS_PRCTL_H + prctl (PR_SET_NAME, name, 0, 0, 0, 0); +#endif +} + +/* {{{1 Epilogue */ +/* vim:set foldmethod=marker: */ diff --git a/glib/glib/gthread-win32.c b/glib/glib/gthread-win32.c new file mode 100644 index 0000000..5a9ac97 --- /dev/null +++ b/glib/glib/gthread-win32.c @@ -0,0 +1,1032 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: solaris thread system implementation + * Copyright 1998-2001 Sebastian Wilhelmi; University of Karlsruhe + * Copyright 2001 Hans Breuer + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* The GMutex and GCond implementations in this file are some of the + * lowest-level code in GLib. All other parts of GLib (messages, + * memory, slices, etc) assume that they can freely use these facilities + * without risking recursion. + * + * As such, these functions are NOT permitted to call any other part of + * GLib. + * + * The thread manipulation functions (create, exit, join, etc.) have + * more freedom -- they can do as they please. + */ + +#include "config.h" + +#include "glib.h" +#include "gthread.h" +#include "gthreadprivate.h" +#include "gslice.h" + +#include + +#include +#include +#include + +static void +g_thread_abort (gint status, + const gchar *function) +{ + fprintf (stderr, "GLib (gthread-win32.c): Unexpected error from C library during '%s': %s. Aborting.\n", + strerror (status), function); + abort (); +} + +/* Starting with Vista and Windows 2008, we have access to the + * CONDITION_VARIABLE and SRWLock primatives on Windows, which are + * pretty reasonable approximations of the primatives specified in + * POSIX 2001 (pthread_cond_t and pthread_mutex_t respectively). + * + * Both of these types are structs containing a single pointer. That + * pointer is used as an atomic bitfield to support user-space mutexes + * that only get the kernel involved in cases of contention (similar + * to how futex()-based mutexes work on Linux). The biggest advantage + * of these new types is that they can be statically initialised to + * zero. That means that they are completely ABI compatible with our + * GMutex and GCond APIs. + * + * Unfortunately, Windows XP lacks these facilities and GLib still + * needs to support Windows XP. Our approach here is as follows: + * + * - avoid depending on structure declarations at compile-time by + * declaring our own GMutex and GCond strutures to be + * ABI-compatible with SRWLock and CONDITION_VARIABLE and using + * those instead + * + * - avoid a hard dependency on the symbols used to manipulate these + * structures by doing a dynamic lookup of those symbols at + * runtime + * + * - if the symbols are not available, emulate them using other + * primatives + * + * Using this approach also allows us to easily build a GLib that lacks + * support for Windows XP or to remove this code entirely when XP is no + * longer supported (end of line is currently April 8, 2014). + */ +typedef struct +{ + void (__stdcall * CallThisOnThreadExit) (void); /* fake */ + + void (__stdcall * InitializeSRWLock) (gpointer lock); + void (__stdcall * DeleteSRWLock) (gpointer lock); /* fake */ + void (__stdcall * AcquireSRWLockExclusive) (gpointer lock); + BOOLEAN (__stdcall * TryAcquireSRWLockExclusive) (gpointer lock); + void (__stdcall * ReleaseSRWLockExclusive) (gpointer lock); + void (__stdcall * AcquireSRWLockShared) (gpointer lock); + BOOLEAN (__stdcall * TryAcquireSRWLockShared) (gpointer lock); + void (__stdcall * ReleaseSRWLockShared) (gpointer lock); + + void (__stdcall * InitializeConditionVariable) (gpointer cond); + void (__stdcall * DeleteConditionVariable) (gpointer cond); /* fake */ + BOOL (__stdcall * SleepConditionVariableSRW) (gpointer cond, + gpointer lock, + DWORD timeout, + ULONG flags); + void (__stdcall * WakeAllConditionVariable) (gpointer cond); + void (__stdcall * WakeConditionVariable) (gpointer cond); +} GThreadImplVtable; + +static GThreadImplVtable g_thread_impl_vtable; + +/* {{{1 GMutex */ +void +g_mutex_init (GMutex *mutex) +{ + g_thread_impl_vtable.InitializeSRWLock (mutex); +} + +void +g_mutex_clear (GMutex *mutex) +{ + if (g_thread_impl_vtable.DeleteSRWLock != NULL) + g_thread_impl_vtable.DeleteSRWLock (mutex); +} + +void +g_mutex_lock (GMutex *mutex) +{ + g_thread_impl_vtable.AcquireSRWLockExclusive (mutex); +} + +gboolean +g_mutex_trylock (GMutex *mutex) +{ + return g_thread_impl_vtable.TryAcquireSRWLockExclusive (mutex); +} + +void +g_mutex_unlock (GMutex *mutex) +{ + g_thread_impl_vtable.ReleaseSRWLockExclusive (mutex); +} + +/* {{{1 GRecMutex */ + +static CRITICAL_SECTION * +g_rec_mutex_impl_new (void) +{ + CRITICAL_SECTION *cs; + + cs = g_slice_new (CRITICAL_SECTION); + InitializeCriticalSection (cs); + + return cs; +} + +static void +g_rec_mutex_impl_free (CRITICAL_SECTION *cs) +{ + DeleteCriticalSection (cs); + g_slice_free (CRITICAL_SECTION, cs); +} + +static CRITICAL_SECTION * +g_rec_mutex_get_impl (GRecMutex *mutex) +{ + CRITICAL_SECTION *impl = mutex->p; + + if G_UNLIKELY (mutex->p == NULL) + { + impl = g_rec_mutex_impl_new (); + if (InterlockedCompareExchangePointer (&mutex->p, impl, NULL) != NULL) + g_rec_mutex_impl_free (impl); + impl = mutex->p; + } + + return impl; +} + +void +g_rec_mutex_init (GRecMutex *mutex) +{ + mutex->p = g_rec_mutex_impl_new (); +} + +void +g_rec_mutex_clear (GRecMutex *mutex) +{ + g_rec_mutex_impl_free (mutex->p); +} + +void +g_rec_mutex_lock (GRecMutex *mutex) +{ + EnterCriticalSection (g_rec_mutex_get_impl (mutex)); +} + +void +g_rec_mutex_unlock (GRecMutex *mutex) +{ + LeaveCriticalSection (mutex->p); +} + +gboolean +g_rec_mutex_trylock (GRecMutex *mutex) +{ + return TryEnterCriticalSection (g_rec_mutex_get_impl (mutex)); +} + +/* {{{1 GRWLock */ + +void +g_rw_lock_init (GRWLock *lock) +{ + g_thread_impl_vtable.InitializeSRWLock (lock); +} + +void +g_rw_lock_clear (GRWLock *lock) +{ + if (g_thread_impl_vtable.DeleteSRWLock != NULL) + g_thread_impl_vtable.DeleteSRWLock (lock); +} + +void +g_rw_lock_writer_lock (GRWLock *lock) +{ + g_thread_impl_vtable.AcquireSRWLockExclusive (lock); +} + +gboolean +g_rw_lock_writer_trylock (GRWLock *lock) +{ + return g_thread_impl_vtable.TryAcquireSRWLockExclusive (lock); +} + +void +g_rw_lock_writer_unlock (GRWLock *lock) +{ + g_thread_impl_vtable.ReleaseSRWLockExclusive (lock); +} + +void +g_rw_lock_reader_lock (GRWLock *lock) +{ + g_thread_impl_vtable.AcquireSRWLockShared (lock); +} + +gboolean +g_rw_lock_reader_trylock (GRWLock *lock) +{ + return g_thread_impl_vtable.TryAcquireSRWLockShared (lock); +} + +void +g_rw_lock_reader_unlock (GRWLock *lock) +{ + g_thread_impl_vtable.ReleaseSRWLockShared (lock); +} + +/* {{{1 GCond */ +void +g_cond_init (GCond *cond) +{ + g_thread_impl_vtable.InitializeConditionVariable (cond); +} + +void +g_cond_clear (GCond *cond) +{ + if (g_thread_impl_vtable.DeleteConditionVariable) + g_thread_impl_vtable.DeleteConditionVariable (cond); +} + +void +g_cond_signal (GCond *cond) +{ + g_thread_impl_vtable.WakeConditionVariable (cond); +} + +void +g_cond_broadcast (GCond *cond) +{ + g_thread_impl_vtable.WakeAllConditionVariable (cond); +} + +void +g_cond_wait (GCond *cond, + GMutex *entered_mutex) +{ + g_thread_impl_vtable.SleepConditionVariableSRW (cond, entered_mutex, INFINITE, 0); +} + +gboolean +g_cond_wait_until (GCond *cond, + GMutex *entered_mutex, + gint64 end_time) +{ + gint64 span; + + span = end_time - g_get_monotonic_time (); + + if G_UNLIKELY (span < 0) + span = 0; + + if G_UNLIKELY (span > G_GINT64_CONSTANT (1000) * G_MAXINT32) + span = INFINITE; + + return g_thread_impl_vtable.SleepConditionVariableSRW (cond, entered_mutex, span / 1000, 0); +} + +/* {{{1 GPrivate */ + +typedef struct _GPrivateDestructor GPrivateDestructor; + +struct _GPrivateDestructor +{ + DWORD index; + GDestroyNotify notify; + GPrivateDestructor *next; +}; + +static GPrivateDestructor * volatile g_private_destructors; +static CRITICAL_SECTION g_private_lock; + +static DWORD +g_private_get_impl (GPrivate *key) +{ + DWORD impl = (DWORD) key->p; + + if G_UNLIKELY (impl == 0) + { + EnterCriticalSection (&g_private_lock); + impl = (DWORD) key->p; + if (impl == 0) + { + GPrivateDestructor *destructor; + + impl = TlsAlloc (); + + if (impl == TLS_OUT_OF_INDEXES) + g_thread_abort (0, "TlsAlloc"); + + if (key->notify != NULL) + { + destructor = malloc (sizeof (GPrivateDestructor)); + if G_UNLIKELY (destructor == NULL) + g_thread_abort (errno, "malloc"); + destructor->index = impl; + destructor->notify = key->notify; + destructor->next = g_private_destructors; + + /* We need to do an atomic store due to the unlocked + * access to the destructor list from the thread exit + * function. + * + * It can double as a sanity check... + */ + if (InterlockedCompareExchangePointer (&g_private_destructors, destructor, + destructor->next) != destructor->next) + g_thread_abort (0, "g_private_get_impl(1)"); + } + + /* Ditto, due to the unlocked access on the fast path */ + if (InterlockedCompareExchangePointer (&key->p, impl, NULL) != NULL) + g_thread_abort (0, "g_private_get_impl(2)"); + } + LeaveCriticalSection (&g_private_lock); + } + + return impl; +} + +gpointer +g_private_get (GPrivate *key) +{ + return TlsGetValue (g_private_get_impl (key)); +} + +void +g_private_set (GPrivate *key, + gpointer value) +{ + TlsSetValue (g_private_get_impl (key), value); +} + +void +g_private_replace (GPrivate *key, + gpointer value) +{ + DWORD impl = g_private_get_impl (key); + gpointer old; + + old = TlsGetValue (impl); + if (old && key->notify) + key->notify (old); + TlsSetValue (impl, value); +} + +/* {{{1 GThread */ + +#define win32_check_for_error(what) G_STMT_START{ \ + if (!(what)) \ + g_error ("file %s: line %d (%s): error %s during %s", \ + __FILE__, __LINE__, G_STRFUNC, \ + g_win32_error_message (GetLastError ()), #what); \ + }G_STMT_END + +#define G_MUTEX_SIZE (sizeof (gpointer)) + +typedef BOOL (__stdcall *GTryEnterCriticalSectionFunc) (CRITICAL_SECTION *); + +typedef struct +{ + GRealThread thread; + + GThreadFunc proxy; + HANDLE handle; +} GThreadWin32; + +void +g_system_thread_free (GRealThread *thread) +{ + GThreadWin32 *wt = (GThreadWin32 *) thread; + + win32_check_for_error (CloseHandle (wt->handle)); + g_slice_free (GThreadWin32, wt); +} + +void +g_system_thread_exit (void) +{ + _endthreadex (0); +} + +static guint __stdcall +g_thread_win32_proxy (gpointer data) +{ + GThreadWin32 *self = data; + + self->proxy (self); + + g_system_thread_exit (); + + g_assert_not_reached (); + + return 0; +} + +GRealThread * +g_system_thread_new (GThreadFunc func, + gulong stack_size, + GError **error) +{ + GThreadWin32 *thread; + guint ignore; + + thread = g_slice_new0 (GThreadWin32); + thread->proxy = func; + + thread->handle = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_win32_proxy, thread, 0, &ignore); + + if (thread->handle == NULL) + { + gchar *win_error = g_win32_error_message (GetLastError ()); + g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, + "Error creating thread: %s", win_error); + g_free (win_error); + g_slice_free (GThreadWin32, thread); + return NULL; + } + + return (GRealThread *) thread; +} + +void +g_thread_yield (void) +{ + Sleep(0); +} + +void +g_system_thread_wait (GRealThread *thread) +{ + GThreadWin32 *wt = (GThreadWin32 *) thread; + + win32_check_for_error (WAIT_FAILED != WaitForSingleObject (wt->handle, INFINITE)); +} + +void +g_system_thread_set_name (const gchar *name) +{ + /* FIXME: implement */ +} + +/* {{{1 SRWLock and CONDITION_VARIABLE emulation (for Windows XP) */ + +static CRITICAL_SECTION g_thread_xp_lock; +static DWORD g_thread_xp_waiter_tls; + +/* {{{2 GThreadWaiter utility class for CONDITION_VARIABLE emulation */ +typedef struct _GThreadXpWaiter GThreadXpWaiter; +struct _GThreadXpWaiter +{ + HANDLE event; + volatile GThreadXpWaiter *next; + volatile GThreadXpWaiter **my_owner; +}; + +static GThreadXpWaiter * +g_thread_xp_waiter_get (void) +{ + GThreadXpWaiter *waiter; + + waiter = TlsGetValue (g_thread_xp_waiter_tls); + + if G_UNLIKELY (waiter == NULL) + { + waiter = malloc (sizeof (GThreadXpWaiter)); + if (waiter == NULL) + g_thread_abort (GetLastError (), "malloc"); + waiter->event = CreateEvent (0, FALSE, FALSE, NULL); + if (waiter->event == NULL) + g_thread_abort (GetLastError (), "CreateEvent"); + waiter->my_owner = NULL; + + TlsSetValue (g_thread_xp_waiter_tls, waiter); + } + + return waiter; +} + +static void __stdcall +g_thread_xp_CallThisOnThreadExit (void) +{ + GThreadXpWaiter *waiter; + + waiter = TlsGetValue (g_thread_xp_waiter_tls); + + if (waiter != NULL) + { + TlsSetValue (g_thread_xp_waiter_tls, NULL); + CloseHandle (waiter->event); + free (waiter); + } +} + +/* {{{2 SRWLock emulation */ +typedef struct +{ + CRITICAL_SECTION writer_lock; + gboolean ever_shared; /* protected by writer_lock */ + gboolean writer_locked; /* protected by writer_lock */ + + /* below is only ever touched if ever_shared becomes true */ + CRITICAL_SECTION atomicity; + GThreadXpWaiter *queued_writer; /* protected by atomicity lock */ + gint num_readers; /* protected by atomicity lock */ +} GThreadSRWLock; + +static void __stdcall +g_thread_xp_InitializeSRWLock (gpointer mutex) +{ + *(GThreadSRWLock * volatile *) mutex = NULL; +} + +static void __stdcall +g_thread_xp_DeleteSRWLock (gpointer mutex) +{ + GThreadSRWLock *lock = *(GThreadSRWLock * volatile *) mutex; + + if (lock) + { + if (lock->ever_shared) + DeleteCriticalSection (&lock->atomicity); + + DeleteCriticalSection (&lock->writer_lock); + free (lock); + } +} + +static GThreadSRWLock * __stdcall +g_thread_xp_get_srwlock (GThreadSRWLock * volatile *lock) +{ + GThreadSRWLock *result; + + /* It looks like we're missing some barriers here, but this code only + * ever runs on Windows XP, which in turn only ever runs on hardware + * with a relatively rigid memory model. The 'volatile' will take + * care of the compiler. + */ + result = *lock; + + if G_UNLIKELY (result == NULL) + { + EnterCriticalSection (&g_thread_xp_lock); + + /* Check again */ + result = *lock; + if (result == NULL) + { + result = malloc (sizeof (GThreadSRWLock)); + + if (result == NULL) + g_thread_abort (errno, "malloc"); + + InitializeCriticalSection (&result->writer_lock); + result->writer_locked = FALSE; + result->ever_shared = FALSE; + *lock = result; + } + + LeaveCriticalSection (&g_thread_xp_lock); + } + + return result; +} + +static void __stdcall +g_thread_xp_AcquireSRWLockExclusive (gpointer mutex) +{ + GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); + + EnterCriticalSection (&lock->writer_lock); + + /* CRITICAL_SECTION is reentrant, but SRWLock is not. + * Detect the deadlock that would occur on later Windows version. + */ + g_assert (!lock->writer_locked); + lock->writer_locked = TRUE; + + if (lock->ever_shared) + { + GThreadXpWaiter *waiter = NULL; + + EnterCriticalSection (&lock->atomicity); + if (lock->num_readers > 0) + lock->queued_writer = waiter = g_thread_xp_waiter_get (); + LeaveCriticalSection (&lock->atomicity); + + if (waiter != NULL) + WaitForSingleObject (waiter->event, INFINITE); + + lock->queued_writer = NULL; + } +} + +static BOOLEAN __stdcall +g_thread_xp_TryAcquireSRWLockExclusive (gpointer mutex) +{ + GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); + + if (!TryEnterCriticalSection (&lock->writer_lock)) + return FALSE; + + /* CRITICAL_SECTION is reentrant, but SRWLock is not. + * Ensure that this properly returns FALSE (as SRWLock would). + */ + if G_UNLIKELY (lock->writer_locked) + { + LeaveCriticalSection (&lock->writer_lock); + return FALSE; + } + + lock->writer_locked = TRUE; + + if (lock->ever_shared) + { + gboolean available; + + EnterCriticalSection (&lock->atomicity); + available = lock->num_readers == 0; + LeaveCriticalSection (&lock->atomicity); + + if (!available) + { + LeaveCriticalSection (&lock->writer_lock); + return FALSE; + } + } + + return TRUE; +} + +static void __stdcall +g_thread_xp_ReleaseSRWLockExclusive (gpointer mutex) +{ + GThreadSRWLock *lock = *(GThreadSRWLock * volatile *) mutex; + + lock->writer_locked = FALSE; + + /* We need this until we fix some weird parts of GLib that try to + * unlock freshly-allocated mutexes. + */ + if (lock != NULL) + LeaveCriticalSection (&lock->writer_lock); +} + +static void +g_thread_xp_srwlock_become_reader (GThreadSRWLock *lock) +{ + if G_UNLIKELY (!lock->ever_shared) + { + InitializeCriticalSection (&lock->atomicity); + lock->queued_writer = NULL; + lock->num_readers = 0; + + lock->ever_shared = TRUE; + } + + EnterCriticalSection (&lock->atomicity); + lock->num_readers++; + LeaveCriticalSection (&lock->atomicity); +} + +static void __stdcall +g_thread_xp_AcquireSRWLockShared (gpointer mutex) +{ + GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); + + EnterCriticalSection (&lock->writer_lock); + + /* See g_thread_xp_AcquireSRWLockExclusive */ + g_assert (!lock->writer_locked); + + g_thread_xp_srwlock_become_reader (lock); + + LeaveCriticalSection (&lock->writer_lock); +} + +static BOOLEAN __stdcall +g_thread_xp_TryAcquireSRWLockShared (gpointer mutex) +{ + GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); + + if (!TryEnterCriticalSection (&lock->writer_lock)) + return FALSE; + + /* See g_thread_xp_AcquireSRWLockExclusive */ + if G_UNLIKELY (lock->writer_locked) + { + LeaveCriticalSection (&lock->writer_lock); + return FALSE; + } + + g_thread_xp_srwlock_become_reader (lock); + + LeaveCriticalSection (&lock->writer_lock); + + return TRUE; +} + +static void __stdcall +g_thread_xp_ReleaseSRWLockShared (gpointer mutex) +{ + GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex); + + EnterCriticalSection (&lock->atomicity); + + lock->num_readers--; + + if (lock->num_readers == 0 && lock->queued_writer) + SetEvent (lock->queued_writer->event); + + LeaveCriticalSection (&lock->atomicity); +} + +/* {{{2 CONDITION_VARIABLE emulation */ +typedef struct +{ + volatile GThreadXpWaiter *first; + volatile GThreadXpWaiter **last_ptr; +} GThreadXpCONDITION_VARIABLE; + +static void __stdcall +g_thread_xp_InitializeConditionVariable (gpointer cond) +{ + *(GThreadXpCONDITION_VARIABLE * volatile *) cond = NULL; +} + +static void __stdcall +g_thread_xp_DeleteConditionVariable (gpointer cond) +{ + GThreadXpCONDITION_VARIABLE *cv = *(GThreadXpCONDITION_VARIABLE * volatile *) cond; + + if (cv) + free (cv); +} + +static GThreadXpCONDITION_VARIABLE * __stdcall +g_thread_xp_get_condition_variable (GThreadXpCONDITION_VARIABLE * volatile *cond) +{ + GThreadXpCONDITION_VARIABLE *result; + + /* It looks like we're missing some barriers here, but this code only + * ever runs on Windows XP, which in turn only ever runs on hardware + * with a relatively rigid memory model. The 'volatile' will take + * care of the compiler. + */ + result = *cond; + + if G_UNLIKELY (result == NULL) + { + result = malloc (sizeof (GThreadXpCONDITION_VARIABLE)); + + if (result == NULL) + g_thread_abort (errno, "malloc"); + + result->first = NULL; + result->last_ptr = &result->first; + + if (InterlockedCompareExchangePointer (cond, result, NULL) != NULL) + { + free (result); + result = *cond; + } + } + + return result; +} + +static BOOL __stdcall +g_thread_xp_SleepConditionVariableSRW (gpointer cond, + gpointer mutex, + DWORD timeout, + ULONG flags) +{ + GThreadXpCONDITION_VARIABLE *cv = g_thread_xp_get_condition_variable (cond); + GThreadXpWaiter *waiter = g_thread_xp_waiter_get (); + DWORD status; + + waiter->next = NULL; + + EnterCriticalSection (&g_thread_xp_lock); + waiter->my_owner = cv->last_ptr; + *cv->last_ptr = waiter; + cv->last_ptr = &waiter->next; + LeaveCriticalSection (&g_thread_xp_lock); + + g_mutex_unlock (mutex); + status = WaitForSingleObject (waiter->event, timeout); + + if (status != WAIT_TIMEOUT && status != WAIT_OBJECT_0) + g_thread_abort (GetLastError (), "WaitForSingleObject"); + g_mutex_lock (mutex); + + if (status == WAIT_TIMEOUT) + { + EnterCriticalSection (&g_thread_xp_lock); + if (waiter->my_owner) + { + if (waiter->next) + waiter->next->my_owner = waiter->my_owner; + else + cv->last_ptr = waiter->my_owner; + *waiter->my_owner = waiter->next; + waiter->my_owner = NULL; + } + LeaveCriticalSection (&g_thread_xp_lock); + } + + return status == WAIT_OBJECT_0; +} + +static void __stdcall +g_thread_xp_WakeConditionVariable (gpointer cond) +{ + GThreadXpCONDITION_VARIABLE *cv = g_thread_xp_get_condition_variable (cond); + volatile GThreadXpWaiter *waiter; + + EnterCriticalSection (&g_thread_xp_lock); + + waiter = cv->first; + if (waiter != NULL) + { + waiter->my_owner = NULL; + cv->first = waiter->next; + if (cv->first != NULL) + cv->first->my_owner = &cv->first; + else + cv->last_ptr = &cv->first; + } + + if (waiter != NULL) + SetEvent (waiter->event); + + LeaveCriticalSection (&g_thread_xp_lock); +} + +static void __stdcall +g_thread_xp_WakeAllConditionVariable (gpointer cond) +{ + GThreadXpCONDITION_VARIABLE *cv = g_thread_xp_get_condition_variable (cond); + volatile GThreadXpWaiter *waiter; + + EnterCriticalSection (&g_thread_xp_lock); + + waiter = cv->first; + cv->first = NULL; + cv->last_ptr = &cv->first; + + while (waiter != NULL) + { + volatile GThreadXpWaiter *next; + + next = waiter->next; + SetEvent (waiter->event); + waiter->my_owner = NULL; + waiter = next; + } + + LeaveCriticalSection (&g_thread_xp_lock); +} + +/* {{{2 XP Setup */ +static void +g_thread_xp_init (void) +{ + static const GThreadImplVtable g_thread_xp_impl_vtable = { + g_thread_xp_CallThisOnThreadExit, + g_thread_xp_InitializeSRWLock, + g_thread_xp_DeleteSRWLock, + g_thread_xp_AcquireSRWLockExclusive, + g_thread_xp_TryAcquireSRWLockExclusive, + g_thread_xp_ReleaseSRWLockExclusive, + g_thread_xp_AcquireSRWLockShared, + g_thread_xp_TryAcquireSRWLockShared, + g_thread_xp_ReleaseSRWLockShared, + g_thread_xp_InitializeConditionVariable, + g_thread_xp_DeleteConditionVariable, + g_thread_xp_SleepConditionVariableSRW, + g_thread_xp_WakeAllConditionVariable, + g_thread_xp_WakeConditionVariable + }; + + InitializeCriticalSection (&g_thread_xp_lock); + g_thread_xp_waiter_tls = TlsAlloc (); + + g_thread_impl_vtable = g_thread_xp_impl_vtable; +} + +/* {{{1 Epilogue */ + +static gboolean +g_thread_lookup_native_funcs (void) +{ + GThreadImplVtable native_vtable = { 0, }; + HMODULE kernel32; + + kernel32 = GetModuleHandle ("KERNEL32.DLL"); + + if (kernel32 == NULL) + return FALSE; + +#define GET_FUNC(name) if ((native_vtable.name = (void *) GetProcAddress (kernel32, #name)) == NULL) return FALSE + GET_FUNC(InitializeSRWLock); + GET_FUNC(AcquireSRWLockExclusive); + GET_FUNC(TryAcquireSRWLockExclusive); + GET_FUNC(ReleaseSRWLockExclusive); + GET_FUNC(AcquireSRWLockShared); + GET_FUNC(TryAcquireSRWLockShared); + GET_FUNC(ReleaseSRWLockShared); + + GET_FUNC(InitializeConditionVariable); + GET_FUNC(SleepConditionVariableSRW); + GET_FUNC(WakeAllConditionVariable); + GET_FUNC(WakeConditionVariable); +#undef GET_FUNC + + g_thread_impl_vtable = native_vtable; + + return TRUE; +} + +G_GNUC_INTERNAL void +g_thread_win32_init (void) +{ + if (!g_thread_lookup_native_funcs ()) + g_thread_xp_init (); + + InitializeCriticalSection (&g_private_lock); +} + +G_GNUC_INTERNAL void +g_thread_win32_thread_detach (void) +{ + gboolean dtors_called; + + do + { + GPrivateDestructor *dtor; + + /* We go by the POSIX book on this one. + * + * If we call a destructor then there is a chance that some new + * TLS variables got set by code called in that destructor. + * + * Loop until nothing is left. + */ + dtors_called = FALSE; + + for (dtor = g_private_destructors; dtor; dtor = dtor->next) + { + gpointer value; + + value = TlsGetValue (dtor->index); + if (value != NULL && dtor->notify != NULL) + { + /* POSIX says to clear this before the call */ + TlsSetValue (dtor->index, NULL); + dtor->notify (value); + dtors_called = TRUE; + } + } + } + while (dtors_called); + + if (g_thread_impl_vtable.CallThisOnThreadExit) + g_thread_impl_vtable.CallThisOnThreadExit (); +} + +/* vim:set foldmethod=marker: */ diff --git a/glib/glib/gthread.c b/glib/glib/gthread.c new file mode 100644 index 0000000..c1d06ec --- /dev/null +++ b/glib/glib/gthread.c @@ -0,0 +1,1014 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * gthread.c: MT safety related functions + * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe + * Owen Taylor + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* Prelude {{{1 ----------------------------------------------------------- */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +/* implement gthread.h's inline functions */ +#define G_IMPLEMENT_INLINES 1 +#define __G_THREAD_C__ + +#include "config.h" + +#include "gthread.h" +#include "gthreadprivate.h" + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif + +#ifndef G_OS_WIN32 +#include +#include +#else +#include +#endif /* G_OS_WIN32 */ + +#include "gslice.h" +#include "gstrfuncs.h" +#include "gtestutils.h" + +/** + * SECTION:threads + * @title: Threads + * @short_description: portable support for threads, mutexes, locks, + * conditions and thread private data + * @see_also: #GThreadPool, #GAsyncQueue + * + * Threads act almost like processes, but unlike processes all threads + * of one process share the same memory. This is good, as it provides + * easy communication between the involved threads via this shared + * memory, and it is bad, because strange things (so called + * "Heisenbugs") might happen if the program is not carefully designed. + * In particular, due to the concurrent nature of threads, no + * assumptions on the order of execution of code running in different + * threads can be made, unless order is explicitly forced by the + * programmer through synchronization primitives. + * + * The aim of the thread-related functions in GLib is to provide a + * portable means for writing multi-threaded software. There are + * primitives for mutexes to protect the access to portions of memory + * (#GMutex, #GRecMutex and #GRWLock). There is a facility to use + * individual bits for locks (g_bit_lock()). There are primitives + * for condition variables to allow synchronization of threads (#GCond). + * There are primitives for thread-private data - data that every + * thread has a private instance of (#GPrivate). There are facilities + * for one-time initialization (#GOnce, g_once_init_enter()). Finally, + * there are primitives to create and manage threads (#GThread). + * + * The GLib threading system used to be initialized with g_thread_init(). + * This is no longer necessary. Since version 2.32, the GLib threading + * system is automatically initialized at the start of your program, + * and all thread-creation functions and synchronization primitives + * are available right away. + * + * Note that it is not safe to assume that your program has no threads + * even if you don't call g_thread_new() yourself. GLib and GIO can + * and will create threads for their own purposes in some cases, such + * as when using g_unix_signal_source_new() or when using GDBus. + * + * Originally, UNIX did not have threads, and therefore some traditional + * UNIX APIs are problematic in threaded programs. Some notable examples + * are + * + * + * C library functions that return data in statically allocated + * buffers, such as strtok() or strerror(). For many of these, + * there are thread-safe variants with a _r suffix, or you can + * look at corresponding GLib APIs (like g_strsplit() or g_strerror()). + * + * + * setenv() and unsetenv() manipulate the process environment in + * a not thread-safe way, and may interfere with getenv() calls + * in other threads. Note that getenv() calls may be + * hidden behind other APIs. For example, GNU gettext() + * calls getenv() under the covers. In general, it is best to treat + * the environment as readonly. If you absolutely have to modify the + * environment, do it early in main(), when no other threads are around yet. + * + * + * setlocale() changes the locale for the entire process, affecting + * all threads. Temporary changes to the locale are often made to + * change the behavior of string scanning or formatting functions + * like scanf() or printf(). GLib offers a number of string APIs + * (like g_ascii_formatd() or g_ascii_strtod()) that can often be + * used as an alternative. Or you can use the uselocale() function + * to change the locale only for the current thread. + * + * + * fork() only takes the calling thread into the child's copy of the + * process image. If other threads were executing in critical + * sections they could have left mutexes locked which could easily + * cause deadlocks in the new child. For this reason, you should + * call exit() or exec() as soon as possible in the child and only + * make signal-safe library calls before that. + * + * + * daemon() uses fork() in a way contrary to what is described + * above. It should not be used with GLib programs. + * + * + * + * GLib itself is internally completely thread-safe (all global data is + * automatically locked), but individual data structure instances are + * not automatically locked for performance reasons. For example, + * you must coordinate accesses to the same #GHashTable from multiple + * threads. The two notable exceptions from this rule are #GMainLoop + * and #GAsyncQueue, which are thread-safe and + * need no further application-level locking to be accessed from + * multiple threads. Most refcounting functions such as g_object_ref() + * are also thread-safe. + */ + +/* G_LOCK Documentation {{{1 ---------------------------------------------- */ + +/** + * G_LOCK_DEFINE: + * @name: the name of the lock + * + * The G_LOCK_* macros provide a convenient interface to #GMutex. + * #G_LOCK_DEFINE defines a lock. It can appear in any place where + * variable definitions may appear in programs, i.e. in the first block + * of a function or outside of functions. The @name parameter will be + * mangled to get the name of the #GMutex. This means that you + * can use names of existing variables as the parameter - e.g. the name + * of the variable you intend to protect with the lock. Look at our + * give_me_next_number() example using the + * G_LOCK_* macros: + * + * + * Using the <literal>G_LOCK_*</literal> convenience macros + * + * G_LOCK_DEFINE (current_number); + * + * int + * give_me_next_number (void) + * { + * static int current_number = 0; + * int ret_val; + * + * G_LOCK (current_number); + * ret_val = current_number = calc_next_number (current_number); + * G_UNLOCK (current_number); + * + * return ret_val; + * } + * + * + */ + +/** + * G_LOCK_DEFINE_STATIC: + * @name: the name of the lock + * + * This works like #G_LOCK_DEFINE, but it creates a static object. + */ + +/** + * G_LOCK_EXTERN: + * @name: the name of the lock + * + * This declares a lock, that is defined with #G_LOCK_DEFINE in another + * module. + */ + +/** + * G_LOCK: + * @name: the name of the lock + * + * Works like g_mutex_lock(), but for a lock defined with + * #G_LOCK_DEFINE. + */ + +/** + * G_TRYLOCK: + * @name: the name of the lock + * @Returns: %TRUE, if the lock could be locked. + * + * Works like g_mutex_trylock(), but for a lock defined with + * #G_LOCK_DEFINE. + */ + +/** + * G_UNLOCK: + * @name: the name of the lock + * + * Works like g_mutex_unlock(), but for a lock defined with + * #G_LOCK_DEFINE. + */ + +/* GMutex Documentation {{{1 ------------------------------------------ */ + +/** + * GMutex: + * + * The #GMutex struct is an opaque data structure to represent a mutex + * (mutual exclusion). It can be used to protect data against shared + * access. Take for example the following function: + * + * + * A function which will not work in a threaded environment + * + * int + * give_me_next_number (void) + * { + * static int current_number = 0; + * + * /* now do a very complicated calculation to calculate the new + * * number, this might for example be a random number generator + * */ + * current_number = calc_next_number (current_number); + * + * return current_number; + * } + * + * + * + * It is easy to see that this won't work in a multi-threaded + * application. There current_number must be protected against shared + * access. A #GMutex can be used as a solution to this problem: + * + * + * Using GMutex to protected a shared variable + * + * int + * give_me_next_number (void) + * { + * static GMutex mutex; + * static int current_number = 0; + * int ret_val; + * + * g_mutex_lock (&mutex); + * ret_val = current_number = calc_next_number (current_number); + * g_mutex_unlock (&mutex); + * + * return ret_val; + * } + * + * + * + * Notice that the #GMutex is not initialised to any particular value. + * Its placement in static storage ensures that it will be initialised + * to all-zeros, which is appropriate. + * + * If a #GMutex is placed in other contexts (eg: embedded in a struct) + * then it must be explicitly initialised using g_mutex_init(). + * + * A #GMutex should only be accessed via g_mutex_ + * functions. + */ + +/* GRecMutex Documentation {{{1 -------------------------------------- */ + +/** + * GRecMutex: + * + * The GRecMutex struct is an opaque data structure to represent a + * recursive mutex. It is similar to a #GMutex with the difference + * that it is possible to lock a GRecMutex multiple times in the same + * thread without deadlock. When doing so, care has to be taken to + * unlock the recursive mutex as often as it has been locked. + * + * If a #GRecMutex is allocated in static storage then it can be used + * without initialisation. Otherwise, you should call + * g_rec_mutex_init() on it and g_rec_mutex_clear() when done. + * + * A GRecMutex should only be accessed with the + * g_rec_mutex_ functions. + * + * Since: 2.32 + */ + +/* GRWLock Documentation {{{1 ---------------------------------------- */ + +/** + * GRWLock: + * + * The GRWLock struct is an opaque data structure to represent a + * reader-writer lock. It is similar to a #GMutex in that it allows + * multiple threads to coordinate access to a shared resource. + * + * The difference to a mutex is that a reader-writer lock discriminates + * between read-only ('reader') and full ('writer') access. While only + * one thread at a time is allowed write access (by holding the 'writer' + * lock via g_rw_lock_writer_lock()), multiple threads can gain + * simultaneous read-only access (by holding the 'reader' lock via + * g_rw_lock_reader_lock()). + * + * + * An array with access functions + * + * GRWLock lock; + * GPtrArray *array; + * + * gpointer + * my_array_get (guint index) + * { + * gpointer retval = NULL; + * + * if (!array) + * return NULL; + * + * g_rw_lock_reader_lock (&lock); + * if (index < array->len) + * retval = g_ptr_array_index (array, index); + * g_rw_lock_reader_unlock (&lock); + * + * return retval; + * } + * + * void + * my_array_set (guint index, gpointer data) + * { + * g_rw_lock_writer_lock (&lock); + * + * if (!array) + * array = g_ptr_array_new (); + * + * if (index >= array->len) + * g_ptr_array_set_size (array, index+1); + * g_ptr_array_index (array, index) = data; + * + * g_rw_lock_writer_unlock (&lock); + * } + * + * + * This example shows an array which can be accessed by many readers + * (the my_array_get() function) simultaneously, + * whereas the writers (the my_array_set() + * function) will only be allowed once at a time and only if no readers + * currently access the array. This is because of the potentially + * dangerous resizing of the array. Using these functions is fully + * multi-thread safe now. + * + * + * + * If a #GRWLock is allocated in static storage then it can be used + * without initialisation. Otherwise, you should call + * g_rw_lock_init() on it and g_rw_lock_clear() when done. + * + * A GRWLock should only be accessed with the + * g_rw_lock_ functions. + * + * Since: 2.32 + */ + +/* GCond Documentation {{{1 ------------------------------------------ */ + +/** + * GCond: + * + * The #GCond struct is an opaque data structure that represents a + * condition. Threads can block on a #GCond if they find a certain + * condition to be false. If other threads change the state of this + * condition they signal the #GCond, and that causes the waiting + * threads to be woken up. + * + * Consider the following example of a shared variable. One or more + * threads can wait for data to be published to the variable and when + * another thread publishes the data, it can signal one of the waiting + * threads to wake up to collect the data. + * + * + * + * Using GCond to block a thread until a condition is satisfied + * + * + * gpointer current_data = NULL; + * GMutex data_mutex; + * GCond data_cond; + * + * void + * push_data (gpointer data) + * { + * g_mutex_lock (&data_mutex); + * current_data = data; + * g_cond_signal (&data_cond); + * g_mutex_unlock (&data_mutex); + * } + * + * gpointer + * pop_data (void) + * { + * gpointer data; + * + * g_mutex_lock (&data_mutex); + * while (!current_data) + * g_cond_wait (&data_cond, &data_mutex); + * data = current_data; + * current_data = NULL; + * g_mutex_unlock (&data_mutex); + * + * return data; + * } + * + * + * + * Whenever a thread calls pop_data() now, it will wait until + * current_data is non-%NULL, i.e. until some other thread + * has called push_data(). + * + * The example shows that use of a condition variable must always be + * paired with a mutex. Without the use of a mutex, there would be a + * race between the check of current_data by the + * while loop in pop_data and waiting. + * Specifically, another thread could set pop_data + * after the check, and signal the cond (with nobody waiting on it) + * before the first thread goes to sleep. #GCond is specifically useful + * for its ability to release the mutex and go to sleep atomically. + * + * It is also important to use the g_cond_wait() and g_cond_wait_until() + * functions only inside a loop which checks for the condition to be + * true. See g_cond_wait() for an explanation of why the condition may + * not be true even after it returns. + * + * If a #GCond is allocated in static storage then it can be used + * without initialisation. Otherwise, you should call g_cond_init() on + * it and g_cond_clear() when done. + * + * A #GCond should only be accessed via the g_cond_ + * functions. + */ + +/* GThread Documentation {{{1 ---------------------------------------- */ + +/** + * GThread: + * + * The #GThread struct represents a running thread. This struct + * is returned by g_thread_new() or g_thread_try_new(). You can + * obtain the #GThread struct representing the current thead by + * calling g_thread_self(). + * + * GThread is refcounted, see g_thread_ref() and g_thread_unref(). + * The thread represented by it holds a reference while it is running, + * and g_thread_join() consumes the reference that it is given, so + * it is normally not necessary to manage GThread references + * explicitly. + * + * The structure is opaque -- none of its fields may be directly + * accessed. + */ + +/** + * GThreadFunc: + * @data: data passed to the thread + * + * Specifies the type of the @func functions passed to g_thread_new() + * or g_thread_try_new(). + * + * Returns: the return value of the thread + */ + +/** + * g_thread_supported: + * + * This macro returns %TRUE if the thread system is initialized, + * and %FALSE if it is not. + * + * For language bindings, g_thread_get_initialized() provides + * the same functionality as a function. + * + * Returns: %TRUE, if the thread system is initialized + */ + +/* GThreadError {{{1 ------------------------------------------------------- */ +/** + * GThreadError: + * @G_THREAD_ERROR_AGAIN: a thread couldn't be created due to resource + * shortage. Try again later. + * + * Possible errors of thread related functions. + **/ + +/** + * G_THREAD_ERROR: + * + * The error domain of the GLib thread subsystem. + **/ +GQuark +g_thread_error_quark (void) +{ + return g_quark_from_static_string ("g_thread_error"); +} + +/* Local Data {{{1 -------------------------------------------------------- */ + +static GMutex g_once_mutex; +static GCond g_once_cond; +static GSList *g_once_init_list = NULL; + +static void g_thread_cleanup (gpointer data); +static GPrivate g_thread_specific_private = G_PRIVATE_INIT (g_thread_cleanup); + +G_LOCK_DEFINE_STATIC (g_thread_new); + +/* GOnce {{{1 ------------------------------------------------------------- */ + +/** + * GOnce: + * @status: the status of the #GOnce + * @retval: the value returned by the call to the function, if @status + * is %G_ONCE_STATUS_READY + * + * A #GOnce struct controls a one-time initialization function. Any + * one-time initialization function must have its own unique #GOnce + * struct. + * + * Since: 2.4 + */ + +/** + * G_ONCE_INIT: + * + * A #GOnce must be initialized with this macro before it can be used. + * + * |[ + * GOnce my_once = G_ONCE_INIT; + * ]| + * + * Since: 2.4 + */ + +/** + * GOnceStatus: + * @G_ONCE_STATUS_NOTCALLED: the function has not been called yet. + * @G_ONCE_STATUS_PROGRESS: the function call is currently in progress. + * @G_ONCE_STATUS_READY: the function has been called. + * + * The possible statuses of a one-time initialization function + * controlled by a #GOnce struct. + * + * Since: 2.4 + */ + +/** + * g_once: + * @once: a #GOnce structure + * @func: the #GThreadFunc function associated to @once. This function + * is called only once, regardless of the number of times it and + * its associated #GOnce struct are passed to g_once(). + * @arg: data to be passed to @func + * + * The first call to this routine by a process with a given #GOnce + * struct calls @func with the given argument. Thereafter, subsequent + * calls to g_once() with the same #GOnce struct do not call @func + * again, but return the stored result of the first call. On return + * from g_once(), the status of @once will be %G_ONCE_STATUS_READY. + * + * For example, a mutex or a thread-specific data key must be created + * exactly once. In a threaded environment, calling g_once() ensures + * that the initialization is serialized across multiple threads. + * + * Calling g_once() recursively on the same #GOnce struct in + * @func will lead to a deadlock. + * + * |[ + * gpointer + * get_debug_flags (void) + * { + * static GOnce my_once = G_ONCE_INIT; + * + * g_once (&my_once, parse_debug_flags, NULL); + * + * return my_once.retval; + * } + * ]| + * + * Since: 2.4 + */ +gpointer +g_once_impl (GOnce *once, + GThreadFunc func, + gpointer arg) +{ + g_mutex_lock (&g_once_mutex); + + while (once->status == G_ONCE_STATUS_PROGRESS) + g_cond_wait (&g_once_cond, &g_once_mutex); + + if (once->status != G_ONCE_STATUS_READY) + { + once->status = G_ONCE_STATUS_PROGRESS; + g_mutex_unlock (&g_once_mutex); + + once->retval = func (arg); + + g_mutex_lock (&g_once_mutex); + once->status = G_ONCE_STATUS_READY; + g_cond_broadcast (&g_once_cond); + } + + g_mutex_unlock (&g_once_mutex); + + return once->retval; +} + +/** + * g_once_init_enter: + * @location: location of a static initializable variable containing 0 + * + * Function to be called when starting a critical initialization + * section. The argument @location must point to a static + * 0-initialized variable that will be set to a value other than 0 at + * the end of the initialization section. In combination with + * g_once_init_leave() and the unique address @value_location, it can + * be ensured that an initialization section will be executed only once + * during a program's life time, and that concurrent threads are + * blocked until initialization completed. To be used in constructs + * like this: + * + * |[ + * static gsize initialization_value = 0; + * + * if (g_once_init_enter (&initialization_value)) + * { + * gsize setup_value = 42; /** initialization code here **/ + * + * g_once_init_leave (&initialization_value, setup_value); + * } + * + * /** use initialization_value here **/ + * ]| + * + * Returns: %TRUE if the initialization section should be entered, + * %FALSE and blocks otherwise + * + * Since: 2.14 + */ +gboolean +(g_once_init_enter) (volatile void *location) +{ + volatile gsize *value_location = location; + gboolean need_init = FALSE; + g_mutex_lock (&g_once_mutex); + if (g_atomic_pointer_get (value_location) == NULL) + { + if (!g_slist_find (g_once_init_list, (void*) value_location)) + { + need_init = TRUE; + g_once_init_list = g_slist_prepend (g_once_init_list, (void*) value_location); + } + else + do + g_cond_wait (&g_once_cond, &g_once_mutex); + while (g_slist_find (g_once_init_list, (void*) value_location)); + } + g_mutex_unlock (&g_once_mutex); + return need_init; +} + +/** + * g_once_init_leave: + * @location: location of a static initializable variable containing 0 + * @result: new non-0 value for *@value_location + * + * Counterpart to g_once_init_enter(). Expects a location of a static + * 0-initialized initialization variable, and an initialization value + * other than 0. Sets the variable to the initialization value, and + * releases concurrent threads blocking in g_once_init_enter() on this + * initialization variable. + * + * Since: 2.14 + */ +void +(g_once_init_leave) (volatile void *location, + gsize result) +{ + volatile gsize *value_location = location; + + g_return_if_fail (g_atomic_pointer_get (value_location) == NULL); + g_return_if_fail (result != 0); + g_return_if_fail (g_once_init_list != NULL); + + g_atomic_pointer_set (value_location, result); + g_mutex_lock (&g_once_mutex); + g_once_init_list = g_slist_remove (g_once_init_list, (void*) value_location); + g_cond_broadcast (&g_once_cond); + g_mutex_unlock (&g_once_mutex); +} + +/* GThread {{{1 -------------------------------------------------------- */ + +/** + * g_thread_ref: + * @thread: a #GThread + * + * Increase the reference count on @thread. + * + * Returns: a new reference to @thread + * + * Since: 2.32 + */ +GThread * +g_thread_ref (GThread *thread) +{ + GRealThread *real = (GRealThread *) thread; + + g_atomic_int_inc (&real->ref_count); + + return thread; +} + +/** + * g_thread_unref: + * @thread: a #GThread + * + * Decrease the reference count on @thread, possibly freeing all + * resources associated with it. + * + * Note that each thread holds a reference to its #GThread while + * it is running, so it is safe to drop your own reference to it + * if you don't need it anymore. + * + * Since: 2.32 + */ +void +g_thread_unref (GThread *thread) +{ + GRealThread *real = (GRealThread *) thread; + + if (g_atomic_int_dec_and_test (&real->ref_count)) + { + if (real->ours) + g_system_thread_free (real); + else + g_slice_free (GRealThread, real); + } +} + +static void +g_thread_cleanup (gpointer data) +{ + g_thread_unref (data); +} + +gpointer +g_thread_proxy (gpointer data) +{ + GRealThread* thread = data; + + g_assert (data); + + /* This has to happen before G_LOCK, as that might call g_thread_self */ + g_private_set (&g_thread_specific_private, data); + + /* The lock makes sure that g_thread_new_internal() has a chance to + * setup 'func' and 'data' before we make the call. + */ + G_LOCK (g_thread_new); + G_UNLOCK (g_thread_new); + + if (thread->name) + { + g_system_thread_set_name (thread->name); + g_free (thread->name); + thread->name = NULL; + } + + thread->retval = thread->thread.func (thread->thread.data); + + return NULL; +} + +/** + * g_thread_new: + * @name: a name for the new thread + * @func: a function to execute in the new thread + * @data: an argument to supply to the new thread + * + * This function creates a new thread. The new thread starts by invoking + * @func with the argument data. The thread will run until @func returns + * or until g_thread_exit() is called from the new thread. The return value + * of @func becomes the return value of the thread, which can be obtained + * with g_thread_join(). + * + * The @name can be useful for discriminating threads in a debugger. + * Some systems restrict the length of @name to 16 bytes. + * + * If the thread can not be created the program aborts. See + * g_thread_try_new() if you want to attempt to deal with failures. + * + * To free the struct returned by this function, use g_thread_unref(). + * Note that g_thread_join() implicitly unrefs the #GThread as well. + * + * Returns: the new #GThread + * + * Since: 2.32 + */ +GThread * +g_thread_new (const gchar *name, + GThreadFunc func, + gpointer data) +{ + GError *error = NULL; + GThread *thread; + + thread = g_thread_new_internal (name, g_thread_proxy, func, data, 0, &error); + + if G_UNLIKELY (thread == NULL) + g_error ("creating thread '%s': %s", name ? name : "", error->message); + + return thread; +} + +/** + * g_thread_try_new: + * @name: a name for the new thread + * @func: a function to execute in the new thread + * @data: an argument to supply to the new thread + * @error: return location for error, or %NULL + * + * This function is the same as g_thread_new() except that + * it allows for the possibility of failure. + * + * If a thread can not be created (due to resource limits), + * @error is set and %NULL is returned. + * + * Returns: the new #GThread, or %NULL if an error occurred + * + * Since: 2.32 + */ +GThread * +g_thread_try_new (const gchar *name, + GThreadFunc func, + gpointer data, + GError **error) +{ + return g_thread_new_internal (name, g_thread_proxy, func, data, 0, error); +} + +GThread * +g_thread_new_internal (const gchar *name, + GThreadFunc proxy, + GThreadFunc func, + gpointer data, + gsize stack_size, + GError **error) +{ + GRealThread *thread; + + g_return_val_if_fail (func != NULL, NULL); + + G_LOCK (g_thread_new); + thread = g_system_thread_new (proxy, stack_size, error); + if (thread) + { + thread->ref_count = 2; + thread->ours = TRUE; + thread->thread.joinable = TRUE; + thread->thread.func = func; + thread->thread.data = data; + thread->name = g_strdup (name); + } + G_UNLOCK (g_thread_new); + + return (GThread*) thread; +} + +/** + * g_thread_exit: + * @retval: the return value of this thread + * + * Terminates the current thread. + * + * If another thread is waiting for us using g_thread_join() then the + * waiting thread will be woken up and get @retval as the return value + * of g_thread_join(). + * + * Calling g_thread_exit (retval) is equivalent to + * returning @retval from the function @func, as given to g_thread_new(). + * + * + * You must only call g_thread_exit() from a thread that you created + * yourself with g_thread_new() or related APIs. You must not call + * this function from a thread created with another threading library + * or or from within a #GThreadPool. + * + */ +void +g_thread_exit (gpointer retval) +{ + GRealThread* real = (GRealThread*) g_thread_self (); + + if G_UNLIKELY (!real->ours) + g_error ("attempt to g_thread_exit() a thread not created by GLib"); + + real->retval = retval; + + g_system_thread_exit (); +} + +/** + * g_thread_join: + * @thread: a #GThread + * + * Waits until @thread finishes, i.e. the function @func, as + * given to g_thread_new(), returns or g_thread_exit() is called. + * If @thread has already terminated, then g_thread_join() + * returns immediately. + * + * Any thread can wait for any other thread by calling g_thread_join(), + * not just its 'creator'. Calling g_thread_join() from multiple threads + * for the same @thread leads to undefined behaviour. + * + * The value returned by @func or given to g_thread_exit() is + * returned by this function. + * + * g_thread_join() consumes the reference to the passed-in @thread. + * This will usually cause the #GThread struct and associated resources + * to be freed. Use g_thread_ref() to obtain an extra reference if you + * want to keep the GThread alive beyond the g_thread_join() call. + * + * Returns: the return value of the thread + */ +gpointer +g_thread_join (GThread *thread) +{ + GRealThread *real = (GRealThread*) thread; + gpointer retval; + + g_return_val_if_fail (thread, NULL); + g_return_val_if_fail (real->ours, NULL); + + g_system_thread_wait (real); + + retval = real->retval; + + /* Just to make sure, this isn't used any more */ + thread->joinable = 0; + + g_thread_unref (thread); + + return retval; +} + +/** + * g_thread_self: + * + * This functions returns the #GThread corresponding to the + * current thread. Note that this function does not increase + * the reference count of the returned struct. + * + * This function will return a #GThread even for threads that + * were not created by GLib (i.e. those created by other threading + * APIs). This may be useful for thread identification purposes + * (i.e. comparisons) but you must not use GLib functions (such + * as g_thread_join()) on these threads. + * + * Returns: the #GThread representing the current thread + */ +GThread* +g_thread_self (void) +{ + GRealThread* thread = g_private_get (&g_thread_specific_private); + + if (!thread) + { + /* If no thread data is available, provide and set one. + * This can happen for the main thread and for threads + * that are not created by GLib. + */ + thread = g_slice_new0 (GRealThread); + thread->ref_count = 1; + + g_private_set (&g_thread_specific_private, thread); + } + + return (GThread*) thread; +} + +/* Epilogue {{{1 */ +/* vim: set foldmethod=marker: */ diff --git a/glib/glib/gthread.h b/glib/glib/gthread.h new file mode 100644 index 0000000..fc927da --- /dev/null +++ b/glib/glib/gthread.h @@ -0,0 +1,231 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_THREAD_H__ +#define __G_THREAD_H__ + +#include +#include + +G_BEGIN_DECLS + +#define G_THREAD_ERROR g_thread_error_quark () +GQuark g_thread_error_quark (void); + +typedef enum +{ + G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */ +} GThreadError; + +typedef gpointer (*GThreadFunc) (gpointer data); + +typedef struct _GThread GThread; + +typedef union _GMutex GMutex; +typedef struct _GRecMutex GRecMutex; +typedef struct _GRWLock GRWLock; +typedef struct _GCond GCond; +typedef struct _GPrivate GPrivate; +typedef struct _GOnce GOnce; + +union _GMutex +{ + /*< private >*/ + gpointer p; + guint i[2]; +}; + +struct _GRWLock +{ + /*< private >*/ + gpointer p; + guint i[2]; +}; + +struct _GCond +{ + /*< private >*/ + gpointer p; + guint i[2]; +}; + +struct _GRecMutex +{ + /*< private >*/ + gpointer p; + guint i[2]; +}; + +#define G_PRIVATE_INIT(notify) { NULL, (notify), { NULL, NULL } } +struct _GPrivate +{ + /*< private >*/ + gpointer p; + GDestroyNotify notify; + gpointer future[2]; +}; + +typedef enum +{ + G_ONCE_STATUS_NOTCALLED, + G_ONCE_STATUS_PROGRESS, + G_ONCE_STATUS_READY +} GOnceStatus; + +#define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL } +struct _GOnce +{ + volatile GOnceStatus status; + volatile gpointer retval; +}; + +#define G_LOCK_NAME(name) g__ ## name ## _lock +#define G_LOCK_DEFINE_STATIC(name) static G_LOCK_DEFINE (name) +#define G_LOCK_DEFINE(name) GMutex G_LOCK_NAME (name) +#define G_LOCK_EXTERN(name) extern GMutex G_LOCK_NAME (name) + +#ifdef G_DEBUG_LOCKS +# define G_LOCK(name) G_STMT_START{ \ + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \ + "file %s: line %d (%s): locking: %s ", \ + __FILE__, __LINE__, G_STRFUNC, \ + #name); \ + g_mutex_lock (&G_LOCK_NAME (name)); \ + }G_STMT_END +# define G_UNLOCK(name) G_STMT_START{ \ + g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \ + "file %s: line %d (%s): unlocking: %s ", \ + __FILE__, __LINE__, G_STRFUNC, \ + #name); \ + g_mutex_unlock (&G_LOCK_NAME (name)); \ + }G_STMT_END +# define G_TRYLOCK(name) \ + (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, \ + "file %s: line %d (%s): try locking: %s ", \ + __FILE__, __LINE__, G_STRFUNC, \ + #name), g_mutex_trylock (&G_LOCK_NAME (name))) +#else /* !G_DEBUG_LOCKS */ +# define G_LOCK(name) g_mutex_lock (&G_LOCK_NAME (name)) +# define G_UNLOCK(name) g_mutex_unlock (&G_LOCK_NAME (name)) +# define G_TRYLOCK(name) g_mutex_trylock (&G_LOCK_NAME (name)) +#endif /* !G_DEBUG_LOCKS */ + +GThread * g_thread_ref (GThread *thread); +void g_thread_unref (GThread *thread); +GThread * g_thread_new (const gchar *name, + GThreadFunc func, + gpointer data); +GThread * g_thread_try_new (const gchar *name, + GThreadFunc func, + gpointer data, + GError **error); +GThread * g_thread_self (void); +void g_thread_exit (gpointer retval); +gpointer g_thread_join (GThread *thread); +void g_thread_yield (void); + + +void g_mutex_init (GMutex *mutex); +void g_mutex_clear (GMutex *mutex); +void g_mutex_lock (GMutex *mutex); +gboolean g_mutex_trylock (GMutex *mutex); +void g_mutex_unlock (GMutex *mutex); + +void g_rw_lock_init (GRWLock *rw_lock); +void g_rw_lock_clear (GRWLock *rw_lock); +void g_rw_lock_writer_lock (GRWLock *rw_lock); +gboolean g_rw_lock_writer_trylock (GRWLock *rw_lock); +void g_rw_lock_writer_unlock (GRWLock *rw_lock); +void g_rw_lock_reader_lock (GRWLock *rw_lock); +gboolean g_rw_lock_reader_trylock (GRWLock *rw_lock); +void g_rw_lock_reader_unlock (GRWLock *rw_lock); + +void g_rec_mutex_init (GRecMutex *rec_mutex); +void g_rec_mutex_clear (GRecMutex *rec_mutex); +void g_rec_mutex_lock (GRecMutex *rec_mutex); +gboolean g_rec_mutex_trylock (GRecMutex *rec_mutex); +void g_rec_mutex_unlock (GRecMutex *rec_mutex); + +void g_cond_init (GCond *cond); +void g_cond_clear (GCond *cond); +void g_cond_wait (GCond *cond, + GMutex *mutex); +void g_cond_signal (GCond *cond); +void g_cond_broadcast (GCond *cond); +gboolean g_cond_wait_until (GCond *cond, + GMutex *mutex, + gint64 end_time); + +gpointer g_private_get (GPrivate *key); +void g_private_set (GPrivate *key, + gpointer value); +void g_private_replace (GPrivate *key, + gpointer value); + +gpointer g_once_impl (GOnce *once, + GThreadFunc func, + gpointer arg); +gboolean g_once_init_enter (volatile void *location); +void g_once_init_leave (volatile void *location, + gsize result); + +#ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED +# define g_once(once, func, arg) g_once_impl ((once), (func), (arg)) +#else /* !G_ATOMIC_OP_MEMORY_BARRIER_NEEDED*/ +# define g_once(once, func, arg) \ + (((once)->status == G_ONCE_STATUS_READY) ? \ + (once)->retval : \ + g_once_impl ((once), (func), (arg))) +#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */ + +#ifdef __GNUC__ +# define g_once_init_enter(location) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(location) : 0); \ + (!g_atomic_pointer_get (location) && \ + g_once_init_enter (location)); \ + })) +# define g_once_init_leave(location, result) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(location) == sizeof (gpointer)); \ + (void) (0 ? *(location) = (result) : 0); \ + g_once_init_leave ((location), (gsize) (result)); \ + })) +#else +# define g_once_init_enter(location) \ + (g_once_init_enter((location))) +# define g_once_init_leave(location, result) \ + (g_once_init_leave((location), (gsize) (result))) +#endif + +G_END_DECLS + +#endif /* __G_THREAD_H__ */ diff --git a/glib/glib/gthreadpool.c b/glib/glib/gthreadpool.c new file mode 100644 index 0000000..de5b9de --- /dev/null +++ b/glib/glib/gthreadpool.c @@ -0,0 +1,1016 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * GThreadPool: thread pool implementation. + * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "gthreadpool.h" + +#include "gasyncqueue.h" +#include "gasyncqueueprivate.h" +#include "gmain.h" +#include "gtestutils.h" +#include "gtimer.h" + +/** + * SECTION:thread_pools + * @title: Thread Pools + * @short_description: pools of threads to execute work concurrently + * @see_also: #GThread + * + * Sometimes you wish to asynchronously fork out the execution of work + * and continue working in your own thread. If that will happen often, + * the overhead of starting and destroying a thread each time might be + * too high. In such cases reusing already started threads seems like a + * good idea. And it indeed is, but implementing this can be tedious + * and error-prone. + * + * Therefore GLib provides thread pools for your convenience. An added + * advantage is, that the threads can be shared between the different + * subsystems of your program, when they are using GLib. + * + * To create a new thread pool, you use g_thread_pool_new(). + * It is destroyed by g_thread_pool_free(). + * + * If you want to execute a certain task within a thread pool, + * you call g_thread_pool_push(). + * + * To get the current number of running threads you call + * g_thread_pool_get_num_threads(). To get the number of still + * unprocessed tasks you call g_thread_pool_unprocessed(). To control + * the maximal number of threads for a thread pool, you use + * g_thread_pool_get_max_threads() and g_thread_pool_set_max_threads(). + * + * Finally you can control the number of unused threads, that are kept + * alive by GLib for future use. The current number can be fetched with + * g_thread_pool_get_num_unused_threads(). The maximal number can be + * controlled by g_thread_pool_get_max_unused_threads() and + * g_thread_pool_set_max_unused_threads(). All currently unused threads + * can be stopped by calling g_thread_pool_stop_unused_threads(). + */ + +#define DEBUG_MSG(x) +/* #define DEBUG_MSG(args) g_printerr args ; g_printerr ("\n"); */ + +typedef struct _GRealThreadPool GRealThreadPool; + +/** + * GThreadPool: + * @func: the function to execute in the threads of this pool + * @user_data: the user data for the threads of this pool + * @exclusive: are all threads exclusive to this pool + * + * The #GThreadPool struct represents a thread pool. It has three + * public read-only members, but the underlying struct is bigger, + * so you must not copy this struct. + */ +struct _GRealThreadPool +{ + GThreadPool pool; + GAsyncQueue *queue; + GCond cond; + gint max_threads; + gint num_threads; + gboolean running; + gboolean immediate; + gboolean waiting; + GCompareDataFunc sort_func; + gpointer sort_user_data; +}; + +/* The following is just an address to mark the wakeup order for a + * thread, it could be any address (as long, as it isn't a valid + * GThreadPool address) + */ +static const gpointer wakeup_thread_marker = (gpointer) &g_thread_pool_new; +static gint wakeup_thread_serial = 0; + +/* Here all unused threads are waiting */ +static GAsyncQueue *unused_thread_queue = NULL; +static gint unused_threads = 0; +static gint max_unused_threads = 0; +static gint kill_unused_threads = 0; +static guint max_idle_time = 0; + +static void g_thread_pool_queue_push_unlocked (GRealThreadPool *pool, + gpointer data); +static void g_thread_pool_free_internal (GRealThreadPool *pool); +static gpointer g_thread_pool_thread_proxy (gpointer data); +static gboolean g_thread_pool_start_thread (GRealThreadPool *pool, + GError **error); +static void g_thread_pool_wakeup_and_stop_all (GRealThreadPool *pool); +static GRealThreadPool* g_thread_pool_wait_for_new_pool (void); +static gpointer g_thread_pool_wait_for_new_task (GRealThreadPool *pool); + +static void +g_thread_pool_queue_push_unlocked (GRealThreadPool *pool, + gpointer data) +{ + if (pool->sort_func) + g_async_queue_push_sorted_unlocked (pool->queue, + data, + pool->sort_func, + pool->sort_user_data); + else + g_async_queue_push_unlocked (pool->queue, data); +} + +static GRealThreadPool* +g_thread_pool_wait_for_new_pool (void) +{ + GRealThreadPool *pool; + gint local_wakeup_thread_serial; + guint local_max_unused_threads; + gint local_max_idle_time; + gint last_wakeup_thread_serial; + gboolean have_relayed_thread_marker = FALSE; + + local_max_unused_threads = g_atomic_int_get (&max_unused_threads); + local_max_idle_time = g_atomic_int_get (&max_idle_time); + last_wakeup_thread_serial = g_atomic_int_get (&wakeup_thread_serial); + + g_atomic_int_inc (&unused_threads); + + do + { + if (g_atomic_int_get (&unused_threads) >= local_max_unused_threads) + { + /* If this is a superfluous thread, stop it. */ + pool = NULL; + } + else if (local_max_idle_time > 0) + { + /* If a maximal idle time is given, wait for the given time. */ + DEBUG_MSG (("thread %p waiting in global pool for %f seconds.", + g_thread_self (), local_max_idle_time / 1000.0)); + + pool = g_async_queue_timeout_pop (unused_thread_queue, + local_max_idle_time * 1000); + } + else + { + /* If no maximal idle time is given, wait indefinitely. */ + DEBUG_MSG (("thread %p waiting in global pool.", g_thread_self ())); + pool = g_async_queue_pop (unused_thread_queue); + } + + if (pool == wakeup_thread_marker) + { + local_wakeup_thread_serial = g_atomic_int_get (&wakeup_thread_serial); + if (last_wakeup_thread_serial == local_wakeup_thread_serial) + { + if (!have_relayed_thread_marker) + { + /* If this wakeup marker has been received for + * the second time, relay it. + */ + DEBUG_MSG (("thread %p relaying wakeup message to " + "waiting thread with lower serial.", + g_thread_self ())); + + g_async_queue_push (unused_thread_queue, wakeup_thread_marker); + have_relayed_thread_marker = TRUE; + + /* If a wakeup marker has been relayed, this thread + * will get out of the way for 100 microseconds to + * avoid receiving this marker again. + */ + g_usleep (100); + } + } + else + { + if (g_atomic_int_add (&kill_unused_threads, -1) > 0) + { + pool = NULL; + break; + } + + DEBUG_MSG (("thread %p updating to new limits.", + g_thread_self ())); + + local_max_unused_threads = g_atomic_int_get (&max_unused_threads); + local_max_idle_time = g_atomic_int_get (&max_idle_time); + last_wakeup_thread_serial = local_wakeup_thread_serial; + + have_relayed_thread_marker = FALSE; + } + } + } + while (pool == wakeup_thread_marker); + + g_atomic_int_add (&unused_threads, -1); + + return pool; +} + +static gpointer +g_thread_pool_wait_for_new_task (GRealThreadPool *pool) +{ + gpointer task = NULL; + + if (pool->running || (!pool->immediate && + g_async_queue_length_unlocked (pool->queue) > 0)) + { + /* This thread pool is still active. */ + if (pool->num_threads > pool->max_threads && pool->max_threads != -1) + { + /* This is a superfluous thread, so it goes to the global pool. */ + DEBUG_MSG (("superfluous thread %p in pool %p.", + g_thread_self (), pool)); + } + else if (pool->pool.exclusive) + { + /* Exclusive threads stay attached to the pool. */ + task = g_async_queue_pop_unlocked (pool->queue); + + DEBUG_MSG (("thread %p in exclusive pool %p waits for task " + "(%d running, %d unprocessed).", + g_thread_self (), pool, pool->num_threads, + g_async_queue_length_unlocked (pool->queue))); + } + else + { + /* A thread will wait for new tasks for at most 1/2 + * second before going to the global pool. + */ + DEBUG_MSG (("thread %p in pool %p waits for up to a 1/2 second for task " + "(%d running, %d unprocessed).", + g_thread_self (), pool, pool->num_threads, + g_async_queue_length_unlocked (pool->queue))); + + task = g_async_queue_timeout_pop_unlocked (pool->queue, + G_USEC_PER_SEC / 2); + } + } + else + { + /* This thread pool is inactive, it will no longer process tasks. */ + DEBUG_MSG (("pool %p not active, thread %p will go to global pool " + "(running: %s, immediate: %s, len: %d).", + pool, g_thread_self (), + pool->running ? "true" : "false", + pool->immediate ? "true" : "false", + g_async_queue_length_unlocked (pool->queue))); + } + + return task; +} + + +static gpointer +g_thread_pool_thread_proxy (gpointer data) +{ + GRealThreadPool *pool; + + pool = data; + + DEBUG_MSG (("thread %p started for pool %p.", g_thread_self (), pool)); + + g_async_queue_lock (pool->queue); + + while (TRUE) + { + gpointer task; + + task = g_thread_pool_wait_for_new_task (pool); + if (task) + { + if (pool->running || !pool->immediate) + { + /* A task was received and the thread pool is active, + * so execute the function. + */ + g_async_queue_unlock (pool->queue); + DEBUG_MSG (("thread %p in pool %p calling func.", + g_thread_self (), pool)); + pool->pool.func (task, pool->pool.user_data); + g_async_queue_lock (pool->queue); + } + } + else + { + /* No task was received, so this thread goes to the global pool. */ + gboolean free_pool = FALSE; + + DEBUG_MSG (("thread %p leaving pool %p for global pool.", + g_thread_self (), pool)); + pool->num_threads--; + + if (!pool->running) + { + if (!pool->waiting) + { + if (pool->num_threads == 0) + { + /* If the pool is not running and no other + * thread is waiting for this thread pool to + * finish and this is the last thread of this + * pool, free the pool. + */ + free_pool = TRUE; + } + else + { + /* If the pool is not running and no other + * thread is waiting for this thread pool to + * finish and this is not the last thread of + * this pool and there are no tasks left in the + * queue, wakeup the remaining threads. + */ + if (g_async_queue_length_unlocked (pool->queue) == + - pool->num_threads) + g_thread_pool_wakeup_and_stop_all (pool); + } + } + else if (pool->immediate || + g_async_queue_length_unlocked (pool->queue) <= 0) + { + /* If the pool is not running and another thread is + * waiting for this thread pool to finish and there + * are either no tasks left or the pool shall stop + * immediately, inform the waiting thread of a change + * of the thread pool state. + */ + g_cond_broadcast (&pool->cond); + } + } + + g_async_queue_unlock (pool->queue); + + if (free_pool) + g_thread_pool_free_internal (pool); + + if ((pool = g_thread_pool_wait_for_new_pool ()) == NULL) + break; + + g_async_queue_lock (pool->queue); + + DEBUG_MSG (("thread %p entering pool %p from global pool.", + g_thread_self (), pool)); + + /* pool->num_threads++ is not done here, but in + * g_thread_pool_start_thread to make the new started + * thread known to the pool before itself can do it. + */ + } + } + + return NULL; +} + +static gboolean +g_thread_pool_start_thread (GRealThreadPool *pool, + GError **error) +{ + gboolean success = FALSE; + + if (pool->num_threads >= pool->max_threads && pool->max_threads != -1) + /* Enough threads are already running */ + return TRUE; + + g_async_queue_lock (unused_thread_queue); + + if (g_async_queue_length_unlocked (unused_thread_queue) < 0) + { + g_async_queue_push_unlocked (unused_thread_queue, pool); + success = TRUE; + } + + g_async_queue_unlock (unused_thread_queue); + + if (!success) + { + GThread *thread; + + /* No thread was found, we have to start a new one */ + thread = g_thread_try_new ("pool", g_thread_pool_thread_proxy, pool, error); + + if (thread == NULL) + return FALSE; + + g_thread_unref (thread); + } + + /* See comment in g_thread_pool_thread_proxy as to why this is done + * here and not there + */ + pool->num_threads++; + + return TRUE; +} + +/** + * g_thread_pool_new: + * @func: a function to execute in the threads of the new thread pool + * @user_data: user data that is handed over to @func every time it + * is called + * @max_threads: the maximal number of threads to execute concurrently + * in the new thread pool, -1 means no limit + * @exclusive: should this thread pool be exclusive? + * @error: return location for error, or %NULL + * + * This function creates a new thread pool. + * + * Whenever you call g_thread_pool_push(), either a new thread is + * created or an unused one is reused. At most @max_threads threads + * are running concurrently for this thread pool. @max_threads = -1 + * allows unlimited threads to be created for this thread pool. The + * newly created or reused thread now executes the function @func + * with the two arguments. The first one is the parameter to + * g_thread_pool_push() and the second one is @user_data. + * + * The parameter @exclusive determines whether the thread pool owns + * all threads exclusive or shares them with other thread pools. + * If @exclusive is %TRUE, @max_threads threads are started + * immediately and they will run exclusively for this thread pool + * until it is destroyed by g_thread_pool_free(). If @exclusive is + * %FALSE, threads are created when needed and shared between all + * non-exclusive thread pools. This implies that @max_threads may + * not be -1 for exclusive thread pools. + * + * @error can be %NULL to ignore errors, or non-%NULL to report + * errors. An error can only occur when @exclusive is set to %TRUE + * and not all @max_threads threads could be created. + * + * Return value: the new #GThreadPool + */ +GThreadPool * +g_thread_pool_new (GFunc func, + gpointer user_data, + gint max_threads, + gboolean exclusive, + GError **error) +{ + GRealThreadPool *retval; + G_LOCK_DEFINE_STATIC (init); + + g_return_val_if_fail (func, NULL); + g_return_val_if_fail (!exclusive || max_threads != -1, NULL); + g_return_val_if_fail (max_threads >= -1, NULL); + + retval = g_new (GRealThreadPool, 1); + + retval->pool.func = func; + retval->pool.user_data = user_data; + retval->pool.exclusive = exclusive; + retval->queue = g_async_queue_new (); + g_cond_init (&retval->cond); + retval->max_threads = max_threads; + retval->num_threads = 0; + retval->running = TRUE; + retval->immediate = FALSE; + retval->waiting = FALSE; + retval->sort_func = NULL; + retval->sort_user_data = NULL; + + G_LOCK (init); + if (!unused_thread_queue) + unused_thread_queue = g_async_queue_new (); + G_UNLOCK (init); + + if (retval->pool.exclusive) + { + g_async_queue_lock (retval->queue); + + while (retval->num_threads < retval->max_threads) + { + GError *local_error = NULL; + + if (!g_thread_pool_start_thread (retval, &local_error)) + { + g_propagate_error (error, local_error); + break; + } + } + + g_async_queue_unlock (retval->queue); + } + + return (GThreadPool*) retval; +} + +/** + * g_thread_pool_push: + * @pool: a #GThreadPool + * @data: a new task for @pool + * @error: return location for error, or %NULL + * + * Inserts @data into the list of tasks to be executed by @pool. + * + * When the number of currently running threads is lower than the + * maximal allowed number of threads, a new thread is started (or + * reused) with the properties given to g_thread_pool_new(). + * Otherwise, @data stays in the queue until a thread in this pool + * finishes its previous task and processes @data. + * + * @error can be %NULL to ignore errors, or non-%NULL to report + * errors. An error can only occur when a new thread couldn't be + * created. In that case @data is simply appended to the queue of + * work to do. + * + * Before version 2.32, this function did not return a success status. + * + * Return value: %TRUE on success, %FALSE if an error occurred + */ +gboolean +g_thread_pool_push (GThreadPool *pool, + gpointer data, + GError **error) +{ + GRealThreadPool *real; + gboolean result; + + real = (GRealThreadPool*) pool; + + g_return_val_if_fail (real, FALSE); + g_return_val_if_fail (real->running, FALSE); + + result = TRUE; + + g_async_queue_lock (real->queue); + + if (g_async_queue_length_unlocked (real->queue) >= 0) + { + /* No thread is waiting in the queue */ + GError *local_error = NULL; + + if (!g_thread_pool_start_thread (real, &local_error)) + { + g_propagate_error (error, local_error); + result = FALSE; + } + } + + g_thread_pool_queue_push_unlocked (real, data); + g_async_queue_unlock (real->queue); + + return result; +} + +/** + * g_thread_pool_set_max_threads: + * @pool: a #GThreadPool + * @max_threads: a new maximal number of threads for @pool, + * or -1 for unlimited + * @error: return location for error, or %NULL + * + * Sets the maximal allowed number of threads for @pool. + * A value of -1 means that the maximal number of threads + * is unlimited. If @pool is an exclusive thread pool, setting + * the maximal number of threads to -1 is not allowed. + * + * Setting @max_threads to 0 means stopping all work for @pool. + * It is effectively frozen until @max_threads is set to a non-zero + * value again. + * + * A thread is never terminated while calling @func, as supplied by + * g_thread_pool_new(). Instead the maximal number of threads only + * has effect for the allocation of new threads in g_thread_pool_push(). + * A new thread is allocated, whenever the number of currently + * running threads in @pool is smaller than the maximal number. + * + * @error can be %NULL to ignore errors, or non-%NULL to report + * errors. An error can only occur when a new thread couldn't be + * created. + * + * Before version 2.32, this function did not return a success status. + * + * Return value: %TRUE on success, %FALSE if an error occurred + */ +gboolean +g_thread_pool_set_max_threads (GThreadPool *pool, + gint max_threads, + GError **error) +{ + GRealThreadPool *real; + gint to_start; + gboolean result; + + real = (GRealThreadPool*) pool; + + g_return_val_if_fail (real, FALSE); + g_return_val_if_fail (real->running, FALSE); + g_return_val_if_fail (!real->pool.exclusive || max_threads != -1, FALSE); + g_return_val_if_fail (max_threads >= -1, FALSE); + + result = TRUE; + + g_async_queue_lock (real->queue); + + real->max_threads = max_threads; + + if (pool->exclusive) + to_start = real->max_threads - real->num_threads; + else + to_start = g_async_queue_length_unlocked (real->queue); + + for ( ; to_start > 0; to_start--) + { + GError *local_error = NULL; + + if (!g_thread_pool_start_thread (real, &local_error)) + { + g_propagate_error (error, local_error); + result = FALSE; + break; + } + } + + g_async_queue_unlock (real->queue); + + return result; +} + +/** + * g_thread_pool_get_max_threads: + * @pool: a #GThreadPool + * + * Returns the maximal number of threads for @pool. + * + * Return value: the maximal number of threads + */ +gint +g_thread_pool_get_max_threads (GThreadPool *pool) +{ + GRealThreadPool *real; + gint retval; + + real = (GRealThreadPool*) pool; + + g_return_val_if_fail (real, 0); + g_return_val_if_fail (real->running, 0); + + g_async_queue_lock (real->queue); + retval = real->max_threads; + g_async_queue_unlock (real->queue); + + return retval; +} + +/** + * g_thread_pool_get_num_threads: + * @pool: a #GThreadPool + * + * Returns the number of threads currently running in @pool. + * + * Return value: the number of threads currently running + */ +guint +g_thread_pool_get_num_threads (GThreadPool *pool) +{ + GRealThreadPool *real; + guint retval; + + real = (GRealThreadPool*) pool; + + g_return_val_if_fail (real, 0); + g_return_val_if_fail (real->running, 0); + + g_async_queue_lock (real->queue); + retval = real->num_threads; + g_async_queue_unlock (real->queue); + + return retval; +} + +/** + * g_thread_pool_unprocessed: + * @pool: a #GThreadPool + * + * Returns the number of tasks still unprocessed in @pool. + * + * Return value: the number of unprocessed tasks + */ +guint +g_thread_pool_unprocessed (GThreadPool *pool) +{ + GRealThreadPool *real; + gint unprocessed; + + real = (GRealThreadPool*) pool; + + g_return_val_if_fail (real, 0); + g_return_val_if_fail (real->running, 0); + + unprocessed = g_async_queue_length (real->queue); + + return MAX (unprocessed, 0); +} + +/** + * g_thread_pool_free: + * @pool: a #GThreadPool + * @immediate: should @pool shut down immediately? + * @wait_: should the function wait for all tasks to be finished? + * + * Frees all resources allocated for @pool. + * + * If @immediate is %TRUE, no new task is processed for @pool. + * Otherwise @pool is not freed before the last task is processed. + * Note however, that no thread of this pool is interrupted while + * processing a task. Instead at least all still running threads + * can finish their tasks before the @pool is freed. + * + * If @wait_ is %TRUE, the functions does not return before all + * tasks to be processed (dependent on @immediate, whether all + * or only the currently running) are ready. + * Otherwise the function returns immediately. + * + * After calling this function @pool must not be used anymore. + */ +void +g_thread_pool_free (GThreadPool *pool, + gboolean immediate, + gboolean wait_) +{ + GRealThreadPool *real; + + real = (GRealThreadPool*) pool; + + g_return_if_fail (real); + g_return_if_fail (real->running); + + /* If there's no thread allowed here, there is not much sense in + * not stopping this pool immediately, when it's not empty + */ + g_return_if_fail (immediate || + real->max_threads != 0 || + g_async_queue_length (real->queue) == 0); + + g_async_queue_lock (real->queue); + + real->running = FALSE; + real->immediate = immediate; + real->waiting = wait_; + + if (wait_) + { + while (g_async_queue_length_unlocked (real->queue) != -real->num_threads && + !(immediate && real->num_threads == 0)) + g_cond_wait (&real->cond, _g_async_queue_get_mutex (real->queue)); + } + + if (immediate || g_async_queue_length_unlocked (real->queue) == -real->num_threads) + { + /* No thread is currently doing something (and nothing is left + * to process in the queue) + */ + if (real->num_threads == 0) + { + /* No threads left, we clean up */ + g_async_queue_unlock (real->queue); + g_thread_pool_free_internal (real); + return; + } + + g_thread_pool_wakeup_and_stop_all (real); + } + + /* The last thread should cleanup the pool */ + real->waiting = FALSE; + g_async_queue_unlock (real->queue); +} + +static void +g_thread_pool_free_internal (GRealThreadPool* pool) +{ + g_return_if_fail (pool); + g_return_if_fail (pool->running == FALSE); + g_return_if_fail (pool->num_threads == 0); + + g_async_queue_unref (pool->queue); + g_cond_clear (&pool->cond); + + g_free (pool); +} + +static void +g_thread_pool_wakeup_and_stop_all (GRealThreadPool *pool) +{ + guint i; + + g_return_if_fail (pool); + g_return_if_fail (pool->running == FALSE); + g_return_if_fail (pool->num_threads != 0); + + pool->immediate = TRUE; + + for (i = 0; i < pool->num_threads; i++) + g_thread_pool_queue_push_unlocked (pool, GUINT_TO_POINTER (1)); +} + +/** + * g_thread_pool_set_max_unused_threads: + * @max_threads: maximal number of unused threads + * + * Sets the maximal number of unused threads to @max_threads. + * If @max_threads is -1, no limit is imposed on the number + * of unused threads. + */ +void +g_thread_pool_set_max_unused_threads (gint max_threads) +{ + g_return_if_fail (max_threads >= -1); + + g_atomic_int_set (&max_unused_threads, max_threads); + + if (max_threads != -1) + { + max_threads -= g_atomic_int_get (&unused_threads); + if (max_threads < 0) + { + g_atomic_int_set (&kill_unused_threads, -max_threads); + g_atomic_int_inc (&wakeup_thread_serial); + + g_async_queue_lock (unused_thread_queue); + + do + { + g_async_queue_push_unlocked (unused_thread_queue, + wakeup_thread_marker); + } + while (++max_threads); + + g_async_queue_unlock (unused_thread_queue); + } + } +} + +/** + * g_thread_pool_get_max_unused_threads: + * + * Returns the maximal allowed number of unused threads. + * + * Return value: the maximal number of unused threads + */ +gint +g_thread_pool_get_max_unused_threads (void) +{ + return g_atomic_int_get (&max_unused_threads); +} + +/** + * g_thread_pool_get_num_unused_threads: + * + * Returns the number of currently unused threads. + * + * Return value: the number of currently unused threads + */ +guint +g_thread_pool_get_num_unused_threads (void) +{ + return g_atomic_int_get (&unused_threads); +} + +/** + * g_thread_pool_stop_unused_threads: + * + * Stops all currently unused threads. This does not change the + * maximal number of unused threads. This function can be used to + * regularly stop all unused threads e.g. from g_timeout_add(). + */ +void +g_thread_pool_stop_unused_threads (void) +{ + guint oldval; + + oldval = g_thread_pool_get_max_unused_threads (); + + g_thread_pool_set_max_unused_threads (0); + g_thread_pool_set_max_unused_threads (oldval); +} + +/** + * g_thread_pool_set_sort_function: + * @pool: a #GThreadPool + * @func: the #GCompareDataFunc used to sort the list of tasks. + * This function is passed two tasks. It should return + * 0 if the order in which they are handled does not matter, + * a negative value if the first task should be processed before + * the second or a positive value if the second task should be + * processed first. + * @user_data: user data passed to @func + * + * Sets the function used to sort the list of tasks. This allows the + * tasks to be processed by a priority determined by @func, and not + * just in the order in which they were added to the pool. + * + * Note, if the maximum number of threads is more than 1, the order + * that threads are executed cannot be guaranteed 100%. Threads are + * scheduled by the operating system and are executed at random. It + * cannot be assumed that threads are executed in the order they are + * created. + * + * Since: 2.10 + */ +void +g_thread_pool_set_sort_function (GThreadPool *pool, + GCompareDataFunc func, + gpointer user_data) +{ + GRealThreadPool *real; + + real = (GRealThreadPool*) pool; + + g_return_if_fail (real); + g_return_if_fail (real->running); + + g_async_queue_lock (real->queue); + + real->sort_func = func; + real->sort_user_data = user_data; + + if (func) + g_async_queue_sort_unlocked (real->queue, + real->sort_func, + real->sort_user_data); + + g_async_queue_unlock (real->queue); +} + +/** + * g_thread_pool_set_max_idle_time: + * @interval: the maximum @interval (in milliseconds) + * a thread can be idle + * + * This function will set the maximum @interval that a thread + * waiting in the pool for new tasks can be idle for before + * being stopped. This function is similar to calling + * g_thread_pool_stop_unused_threads() on a regular timeout, + * except this is done on a per thread basis. + * + * By setting @interval to 0, idle threads will not be stopped. + * + * This function makes use of g_async_queue_timed_pop () using + * @interval. + * + * Since: 2.10 + */ +void +g_thread_pool_set_max_idle_time (guint interval) +{ + guint i; + + g_atomic_int_set (&max_idle_time, interval); + + i = g_atomic_int_get (&unused_threads); + if (i > 0) + { + g_atomic_int_inc (&wakeup_thread_serial); + g_async_queue_lock (unused_thread_queue); + + do + { + g_async_queue_push_unlocked (unused_thread_queue, + wakeup_thread_marker); + } + while (--i); + + g_async_queue_unlock (unused_thread_queue); + } +} + +/** + * g_thread_pool_get_max_idle_time: + * + * This function will return the maximum @interval that a + * thread will wait in the thread pool for new tasks before + * being stopped. + * + * If this function returns 0, threads waiting in the thread + * pool for new work are not stopped. + * + * Return value: the maximum @interval (milliseconds) to wait + * for new tasks in the thread pool before stopping the + * thread + * + * Since: 2.10 + */ +guint +g_thread_pool_get_max_idle_time (void) +{ + return g_atomic_int_get (&max_idle_time); +} diff --git a/glib/glib/gthreadpool.h b/glib/glib/gthreadpool.h new file mode 100644 index 0000000..3a1f298 --- /dev/null +++ b/glib/glib/gthreadpool.h @@ -0,0 +1,80 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_THREADPOOL_H__ +#define __G_THREADPOOL_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GThreadPool GThreadPool; + +/* Thread Pools + */ + +struct _GThreadPool +{ + GFunc func; + gpointer user_data; + gboolean exclusive; +}; + +GThreadPool * g_thread_pool_new (GFunc func, + gpointer user_data, + gint max_threads, + gboolean exclusive, + GError **error); +void g_thread_pool_free (GThreadPool *pool, + gboolean immediate, + gboolean wait_); +gboolean g_thread_pool_push (GThreadPool *pool, + gpointer data, + GError **error); +guint g_thread_pool_unprocessed (GThreadPool *pool); +void g_thread_pool_set_sort_function (GThreadPool *pool, + GCompareDataFunc func, + gpointer user_data); +gboolean g_thread_pool_set_max_threads (GThreadPool *pool, + gint max_threads, + GError **error); +gint g_thread_pool_get_max_threads (GThreadPool *pool); +guint g_thread_pool_get_num_threads (GThreadPool *pool); + +void g_thread_pool_set_max_unused_threads (gint max_threads); +gint g_thread_pool_get_max_unused_threads (void); +guint g_thread_pool_get_num_unused_threads (void); +void g_thread_pool_stop_unused_threads (void); +void g_thread_pool_set_max_idle_time (guint interval); +guint g_thread_pool_get_max_idle_time (void); + +G_END_DECLS + +#endif /* __G_THREADPOOL_H__ */ diff --git a/glib/glib/gthreadprivate.h b/glib/glib/gthreadprivate.h new file mode 100644 index 0000000..6b974de --- /dev/null +++ b/glib/glib/gthreadprivate.h @@ -0,0 +1,68 @@ +/* GLIB - Library of useful routines for C programming + * + * gthreadprivate.h - GLib internal thread system related declarations. + * + * Copyright (C) 2003 Sebastian Wilhelmi + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_THREADPRIVATE_H__ +#define __G_THREADPRIVATE_H__ + +#include "deprecated/gthread.h" + +typedef struct _GRealThread GRealThread; +struct _GRealThread +{ + GThread thread; + + gint ref_count; + gboolean ours; + gchar *name; + gpointer retval; +}; + +/* system thread implementation (gthread-posix.c, gthread-win32.c) */ +G_GNUC_INTERNAL +void g_system_thread_wait (GRealThread *thread); + +G_GNUC_INTERNAL +GRealThread * g_system_thread_new (GThreadFunc func, + gulong stack_size, + GError **error); +G_GNUC_INTERNAL +void g_system_thread_free (GRealThread *thread); + +G_GNUC_INTERNAL +void g_system_thread_exit (void); +G_GNUC_INTERNAL +void g_system_thread_set_name (const gchar *name); + + +/* gthread.c */ +G_GNUC_INTERNAL +GThread * g_thread_new_internal (const gchar *name, + GThreadFunc proxy, + GThreadFunc func, + gpointer data, + gsize stack_size, + GError **error); + +G_GNUC_INTERNAL +gpointer g_thread_proxy (gpointer thread); + +#endif /* __G_THREADPRIVATE_H__ */ diff --git a/glib/glib/gtimer.c b/glib/glib/gtimer.c new file mode 100644 index 0000000..6e962b4 --- /dev/null +++ b/glib/glib/gtimer.c @@ -0,0 +1,555 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" +#include "glibconfig.h" + +#include + +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ + +#ifdef HAVE_SYS_TIME_H +#include +#endif +#include +#ifndef G_OS_WIN32 +#include +#endif /* G_OS_WIN32 */ + +#ifdef G_OS_WIN32 +#include +#endif /* G_OS_WIN32 */ + +#include "gtimer.h" + +#include "gmem.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gmain.h" + +/** + * SECTION:timers + * @title: Timers + * @short_description: keep track of elapsed time + * + * #GTimer records a start time, and counts microseconds elapsed since + * that time. This is done somewhat differently on different platforms, + * and can be tricky to get exactly right, so #GTimer provides a + * portable/convenient interface. + **/ + +/** + * GTimer: + * + * Opaque datatype that records a start time. + **/ +struct _GTimer +{ + guint64 start; + guint64 end; + + guint active : 1; +}; + +/** + * g_timer_new: + * @Returns: a new #GTimer. + * + * Creates a new timer, and starts timing (i.e. g_timer_start() is + * implicitly called for you). + **/ +GTimer* +g_timer_new (void) +{ + GTimer *timer; + + timer = g_new (GTimer, 1); + timer->active = TRUE; + + timer->start = g_get_monotonic_time (); + + return timer; +} + +/** + * g_timer_destroy: + * @timer: a #GTimer to destroy. + * + * Destroys a timer, freeing associated resources. + **/ +void +g_timer_destroy (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + + g_free (timer); +} + +/** + * g_timer_start: + * @timer: a #GTimer. + * + * Marks a start time, so that future calls to g_timer_elapsed() will + * report the time since g_timer_start() was called. g_timer_new() + * automatically marks the start time, so no need to call + * g_timer_start() immediately after creating the timer. + **/ +void +g_timer_start (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + + timer->active = TRUE; + + timer->start = g_get_monotonic_time (); +} + +/** + * g_timer_stop: + * @timer: a #GTimer. + * + * Marks an end time, so calls to g_timer_elapsed() will return the + * difference between this end time and the start time. + **/ +void +g_timer_stop (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + + timer->active = FALSE; + + timer->end = g_get_monotonic_time (); +} + +/** + * g_timer_reset: + * @timer: a #GTimer. + * + * This function is useless; it's fine to call g_timer_start() on an + * already-started timer to reset the start time, so g_timer_reset() + * serves no purpose. + **/ +void +g_timer_reset (GTimer *timer) +{ + g_return_if_fail (timer != NULL); + + timer->start = g_get_monotonic_time (); +} + +/** + * g_timer_continue: + * @timer: a #GTimer. + * + * Resumes a timer that has previously been stopped with + * g_timer_stop(). g_timer_stop() must be called before using this + * function. + * + * Since: 2.4 + **/ +void +g_timer_continue (GTimer *timer) +{ + guint64 elapsed; + + g_return_if_fail (timer != NULL); + g_return_if_fail (timer->active == FALSE); + + /* Get elapsed time and reset timer start time + * to the current time minus the previously + * elapsed interval. + */ + + elapsed = timer->end - timer->start; + + timer->start = g_get_monotonic_time (); + + timer->start -= elapsed; + + timer->active = TRUE; +} + +/** + * g_timer_elapsed: + * @timer: a #GTimer. + * @microseconds: return location for the fractional part of seconds + * elapsed, in microseconds (that is, the total number + * of microseconds elapsed, modulo 1000000), or %NULL + * @Returns: seconds elapsed as a floating point value, including any + * fractional part. + * + * If @timer has been started but not stopped, obtains the time since + * the timer was started. If @timer has been stopped, obtains the + * elapsed time between the time it was started and the time it was + * stopped. The return value is the number of seconds elapsed, + * including any fractional part. The @microseconds out parameter is + * essentially useless. + **/ +gdouble +g_timer_elapsed (GTimer *timer, + gulong *microseconds) +{ + gdouble total; + gint64 elapsed; + + g_return_val_if_fail (timer != NULL, 0); + + if (timer->active) + timer->end = g_get_monotonic_time (); + + elapsed = timer->end - timer->start; + + total = elapsed / 1e6; + + if (microseconds) + *microseconds = elapsed % 1000000; + + return total; +} + +/** + * g_usleep: + * @microseconds: number of microseconds to pause + * + * Pauses the current thread for the given number of microseconds. + * + * There are 1 million microseconds per second (represented by the + * #G_USEC_PER_SEC macro). g_usleep() may have limited precision, + * depending on hardware and operating system; don't rely on the exact + * length of the sleep. + */ +void +g_usleep (gulong microseconds) +{ +#ifdef G_OS_WIN32 + Sleep (microseconds / 1000); +#else + struct timespec request, remaining; + request.tv_sec = microseconds / G_USEC_PER_SEC; + request.tv_nsec = 1000 * (microseconds % G_USEC_PER_SEC); + while (nanosleep (&request, &remaining) == -1 && errno == EINTR) + request = remaining; +#endif +} + +/** + * g_time_val_add: + * @time_: a #GTimeVal + * @microseconds: number of microseconds to add to @time + * + * Adds the given number of microseconds to @time_. @microseconds can + * also be negative to decrease the value of @time_. + **/ +void +g_time_val_add (GTimeVal *time_, glong microseconds) +{ + g_return_if_fail (time_->tv_usec >= 0 && time_->tv_usec < G_USEC_PER_SEC); + + if (microseconds >= 0) + { + time_->tv_usec += microseconds % G_USEC_PER_SEC; + time_->tv_sec += microseconds / G_USEC_PER_SEC; + if (time_->tv_usec >= G_USEC_PER_SEC) + { + time_->tv_usec -= G_USEC_PER_SEC; + time_->tv_sec++; + } + } + else + { + microseconds *= -1; + time_->tv_usec -= microseconds % G_USEC_PER_SEC; + time_->tv_sec -= microseconds / G_USEC_PER_SEC; + if (time_->tv_usec < 0) + { + time_->tv_usec += G_USEC_PER_SEC; + time_->tv_sec--; + } + } +} + +/* converts a broken down date representation, relative to UTC, to + * a timestamp; it uses timegm() if it's available. + */ +static time_t +mktime_utc (struct tm *tm) +{ + time_t retval; + +#ifndef HAVE_TIMEGM + static const gint days_before[] = + { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 + }; +#endif + +#ifndef HAVE_TIMEGM + if (tm->tm_mon < 0 || tm->tm_mon > 11) + return (time_t) -1; + + retval = (tm->tm_year - 70) * 365; + retval += (tm->tm_year - 68) / 4; + retval += days_before[tm->tm_mon] + tm->tm_mday - 1; + + if (tm->tm_year % 4 == 0 && tm->tm_mon < 2) + retval -= 1; + + retval = ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 + tm->tm_sec; +#else + retval = timegm (tm); +#endif /* !HAVE_TIMEGM */ + + return retval; +} + +/** + * g_time_val_from_iso8601: + * @iso_date: an ISO 8601 encoded date string + * @time_: (out): a #GTimeVal + * + * Converts a string containing an ISO 8601 encoded date and time + * to a #GTimeVal and puts it into @time_. + * + * @iso_date must include year, month, day, hours, minutes, and + * seconds. It can optionally include fractions of a second and a time + * zone indicator. (In the absence of any time zone indication, the + * timestamp is assumed to be in local time.) + * + * Return value: %TRUE if the conversion was successful. + * + * Since: 2.12 + */ +gboolean +g_time_val_from_iso8601 (const gchar *iso_date, + GTimeVal *time_) +{ + struct tm tm = {0}; + long val; + + g_return_val_if_fail (iso_date != NULL, FALSE); + g_return_val_if_fail (time_ != NULL, FALSE); + + /* Ensure that the first character is a digit, + * the first digit of the date, otherwise we don't + * have an ISO 8601 date */ + while (g_ascii_isspace (*iso_date)) + iso_date++; + + if (*iso_date == '\0') + return FALSE; + + if (!g_ascii_isdigit (*iso_date) && *iso_date != '-' && *iso_date != '+') + return FALSE; + + val = strtoul (iso_date, (char **)&iso_date, 10); + if (*iso_date == '-') + { + /* YYYY-MM-DD */ + tm.tm_year = val - 1900; + iso_date++; + tm.tm_mon = strtoul (iso_date, (char **)&iso_date, 10) - 1; + + if (*iso_date++ != '-') + return FALSE; + + tm.tm_mday = strtoul (iso_date, (char **)&iso_date, 10); + } + else + { + /* YYYYMMDD */ + tm.tm_mday = val % 100; + tm.tm_mon = (val % 10000) / 100 - 1; + tm.tm_year = val / 10000 - 1900; + } + + if (*iso_date != 'T') + { + /* Date only */ + if (*iso_date == '\0') + return TRUE; + return FALSE; + } + + iso_date++; + + /* If there is a 'T' then there has to be a time */ + if (!g_ascii_isdigit (*iso_date)) + return FALSE; + + val = strtoul (iso_date, (char **)&iso_date, 10); + if (*iso_date == ':') + { + /* hh:mm:ss */ + tm.tm_hour = val; + iso_date++; + tm.tm_min = strtoul (iso_date, (char **)&iso_date, 10); + + if (*iso_date++ != ':') + return FALSE; + + tm.tm_sec = strtoul (iso_date, (char **)&iso_date, 10); + } + else + { + /* hhmmss */ + tm.tm_sec = val % 100; + tm.tm_min = (val % 10000) / 100; + tm.tm_hour = val / 10000; + } + + time_->tv_usec = 0; + + if (*iso_date == ',' || *iso_date == '.') + { + glong mul = 100000; + + while (g_ascii_isdigit (*++iso_date)) + { + time_->tv_usec += (*iso_date - '0') * mul; + mul /= 10; + } + } + + /* Now parse the offset and convert tm to a time_t */ + if (*iso_date == 'Z') + { + iso_date++; + time_->tv_sec = mktime_utc (&tm); + } + else if (*iso_date == '+' || *iso_date == '-') + { + gint sign = (*iso_date == '+') ? -1 : 1; + + val = strtoul (iso_date + 1, (char **)&iso_date, 10); + + if (*iso_date == ':') + val = 60 * val + strtoul (iso_date + 1, (char **)&iso_date, 10); + else + val = 60 * (val / 100) + (val % 100); + + time_->tv_sec = mktime_utc (&tm) + (time_t) (60 * val * sign); + } + else + { + /* No "Z" or offset, so local time */ + tm.tm_isdst = -1; /* locale selects DST */ + time_->tv_sec = mktime (&tm); + } + + while (g_ascii_isspace (*iso_date)) + iso_date++; + + return *iso_date == '\0'; +} + +/** + * g_time_val_to_iso8601: + * @time_: a #GTimeVal + * + * Converts @time_ into an RFC 3339 encoded string, relative to the + * Coordinated Universal Time (UTC). This is one of the many formats + * allowed by ISO 8601. + * + * ISO 8601 allows a large number of date/time formats, with or without + * punctuation and optional elements. The format returned by this function + * is a complete date and time, with optional punctuation included, the + * UTC time zone represented as "Z", and the @tv_usec part included if + * and only if it is nonzero, i.e. either + * "YYYY-MM-DDTHH:MM:SSZ" or "YYYY-MM-DDTHH:MM:SS.fffffZ". + * + * This corresponds to the Internet date/time format defined by + * RFC 3339, and + * to either of the two most-precise formats defined by + * the W3C Note + * "Date and Time Formats". Both of these documents are profiles of + * ISO 8601. + * + * Use g_date_time_format() or g_strdup_printf() if a different + * variation of ISO 8601 format is required. + * + * Return value: a newly allocated string containing an ISO 8601 date + * + * Since: 2.12 + */ +gchar * +g_time_val_to_iso8601 (GTimeVal *time_) +{ + gchar *retval; + struct tm *tm; +#ifdef HAVE_GMTIME_R + struct tm tm_; +#endif + time_t secs; + + g_return_val_if_fail (time_->tv_usec >= 0 && time_->tv_usec < G_USEC_PER_SEC, NULL); + + secs = time_->tv_sec; +#ifdef _WIN32 + tm = gmtime (&secs); +#else +#ifdef HAVE_GMTIME_R + tm = gmtime_r (&secs, &tm_); +#else + tm = gmtime (&secs); +#endif +#endif + + if (time_->tv_usec != 0) + { + /* ISO 8601 date and time format, with fractionary seconds: + * YYYY-MM-DDTHH:MM:SS.MMMMMMZ + */ + retval = g_strdup_printf ("%4d-%02d-%02dT%02d:%02d:%02d.%06ldZ", + tm->tm_year + 1900, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + time_->tv_usec); + } + else + { + /* ISO 8601 date and time format: + * YYYY-MM-DDTHH:MM:SSZ + */ + retval = g_strdup_printf ("%4d-%02d-%02dT%02d:%02d:%02dZ", + tm->tm_year + 1900, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + } + + return retval; +} diff --git a/glib/glib/gtimer.h b/glib/glib/gtimer.h new file mode 100644 index 0000000..b927fc3 --- /dev/null +++ b/glib/glib/gtimer.h @@ -0,0 +1,65 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_TIMER_H__ +#define __G_TIMER_H__ + +#include + +G_BEGIN_DECLS + +/* Timer + */ + +/* microseconds per second */ +typedef struct _GTimer GTimer; + +#define G_USEC_PER_SEC 1000000 + +GTimer* g_timer_new (void); +void g_timer_destroy (GTimer *timer); +void g_timer_start (GTimer *timer); +void g_timer_stop (GTimer *timer); +void g_timer_reset (GTimer *timer); +void g_timer_continue (GTimer *timer); +gdouble g_timer_elapsed (GTimer *timer, + gulong *microseconds); + +void g_usleep (gulong microseconds); + +void g_time_val_add (GTimeVal *time_, + glong microseconds); +gboolean g_time_val_from_iso8601 (const gchar *iso_date, + GTimeVal *time_); +gchar* g_time_val_to_iso8601 (GTimeVal *time_) G_GNUC_MALLOC; + +G_END_DECLS + +#endif /* __G_TIMER_H__ */ diff --git a/glib/glib/gtimezone.c b/glib/glib/gtimezone.c new file mode 100644 index 0000000..8195106 --- /dev/null +++ b/glib/glib/gtimezone.c @@ -0,0 +1,817 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +/* Prologue {{{1 */ + +#include "gtimezone.h" + +#include +#include +#include + +#include "gmappedfile.h" +#include "gtestutils.h" +#include "gfileutils.h" +#include "gstrfuncs.h" +#include "ghash.h" +#include "gthread.h" +#include "gbytes.h" +#include "gslice.h" + +/** + * SECTION:timezone + * @title: GTimeZone + * @short_description: a structure representing a time zone + * @see_also: #GDateTime + * + * #GTimeZone is a structure that represents a time zone, at no + * particular point in time. It is refcounted and immutable. + * + * A time zone contains a number of intervals. Each interval has + * an abbreviation to describe it, an offet to UTC and a flag indicating + * if the daylight savings time is in effect during that interval. A + * time zone always has at least one interval -- interval 0. + * + * Every UTC time is contained within exactly one interval, but a given + * local time may be contained within zero, one or two intervals (due to + * incontinuities associated with daylight savings time). + * + * An interval may refer to a specific period of time (eg: the duration + * of daylight savings time during 2010) or it may refer to many periods + * of time that share the same properties (eg: all periods of daylight + * savings time). It is also possible (usually for political reasons) + * that some properties (like the abbreviation) change between intervals + * without other properties changing. + * + * #GTimeZone is available since GLib 2.26. + */ + +/** + * GTimeZone: + * + * #GDateTime is an opaque structure whose members cannot be accessed + * directly. + * + * Since: 2.26 + **/ + +/* zoneinfo file format {{{1 */ + +/* unaligned */ +typedef struct { gchar bytes[8]; } gint64_be; +typedef struct { gchar bytes[4]; } gint32_be; +typedef struct { gchar bytes[4]; } guint32_be; + +static inline gint64 gint64_from_be (const gint64_be be) { + gint64 tmp; memcpy (&tmp, &be, sizeof tmp); return GINT64_FROM_BE (tmp); +} + +static inline gint32 gint32_from_be (const gint32_be be) { + gint32 tmp; memcpy (&tmp, &be, sizeof tmp); return GINT32_FROM_BE (tmp); +} + +static inline guint32 guint32_from_be (const guint32_be be) { + guint32 tmp; memcpy (&tmp, &be, sizeof tmp); return GUINT32_FROM_BE (tmp); +} + +struct tzhead +{ + gchar tzh_magic[4]; + gchar tzh_version; + guchar tzh_reserved[15]; + + guint32_be tzh_ttisgmtcnt; + guint32_be tzh_ttisstdcnt; + guint32_be tzh_leapcnt; + guint32_be tzh_timecnt; + guint32_be tzh_typecnt; + guint32_be tzh_charcnt; +}; + +struct ttinfo +{ + gint32_be tt_gmtoff; + guint8 tt_isdst; + guint8 tt_abbrind; +}; + +/* GTimeZone structure and lifecycle {{{1 */ +struct _GTimeZone +{ + gchar *name; + + GBytes *zoneinfo; + + const struct tzhead *header; + const struct ttinfo *infos; + const gint64_be *trans; + const guint8 *indices; + const gchar *abbrs; + gint timecnt; + + gint ref_count; +}; + +G_LOCK_DEFINE_STATIC (time_zones); +static GHashTable/**/ *time_zones; + +/** + * g_time_zone_unref: + * @tz: a #GTimeZone + * + * Decreases the reference count on @tz. + * + * Since: 2.26 + **/ +void +g_time_zone_unref (GTimeZone *tz) +{ + int ref_count; + +again: + ref_count = g_atomic_int_get (&tz->ref_count); + + g_assert (ref_count > 0); + + if (ref_count == 1) + { + if (tz->name != NULL) + { + G_LOCK(time_zones); + + /* someone else might have grabbed a ref in the meantime */ + if G_UNLIKELY (g_atomic_int_get (&tz->ref_count) != 1) + { + G_UNLOCK(time_zones); + goto again; + } + + g_hash_table_remove (time_zones, tz->name); + G_UNLOCK(time_zones); + } + + if (tz->zoneinfo) + g_bytes_unref (tz->zoneinfo); + + g_free (tz->name); + + g_slice_free (GTimeZone, tz); + } + + else if G_UNLIKELY (!g_atomic_int_compare_and_exchange (&tz->ref_count, + ref_count, + ref_count - 1)) + goto again; +} + +/** + * g_time_zone_ref: + * @tz: a #GTimeZone + * + * Increases the reference count on @tz. + * + * Returns: a new reference to @tz. + * + * Since: 2.26 + **/ +GTimeZone * +g_time_zone_ref (GTimeZone *tz) +{ + g_assert (tz->ref_count > 0); + + g_atomic_int_inc (&tz->ref_count); + + return tz; +} + +/* fake zoneinfo creation (for RFC3339/ISO 8601 timezones) {{{1 */ +/* + * parses strings of the form 'hh' 'hhmm' or 'hh:mm' where: + * - hh is 00 to 23 + * - mm is 00 to 59 + */ +static gboolean +parse_time (const gchar *time_, + gint32 *offset) +{ + if (*time_ < '0' || '2' < *time_) + return FALSE; + + *offset = 10 * 60 * 60 * (*time_++ - '0'); + + if (*time_ < '0' || '9' < *time_) + return FALSE; + + *offset += 60 * 60 * (*time_++ - '0'); + + if (*offset > 23 * 60 * 60) + return FALSE; + + if (*time_ == '\0') + return TRUE; + + if (*time_ == ':') + time_++; + + if (*time_ < '0' || '5' < *time_) + return FALSE; + + *offset += 10 * 60 * (*time_++ - '0'); + + if (*time_ < '0' || '9' < *time_) + return FALSE; + + *offset += 60 * (*time_++ - '0'); + + return *time_ == '\0'; +} + +static gboolean +parse_constant_offset (const gchar *name, + gint32 *offset) +{ + switch (*name++) + { + case 'Z': + *offset = 0; + return !*name; + + case '+': + return parse_time (name, offset); + + case '-': + if (parse_time (name, offset)) + { + *offset = -*offset; + return TRUE; + } + + default: + return FALSE; + } +} + +static GBytes * +zone_for_constant_offset (const gchar *name) +{ + const gchar fake_zoneinfo_headers[] = + "TZif" "2..." "...." "...." "...." + "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" + "TZif" "2..." "...." "...." "...." + "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\1" "\0\0\0\7"; + struct { + struct tzhead headers[2]; + struct ttinfo info; + gchar abbr[8]; + } *fake; + gint32 offset; + + if (name == NULL || !parse_constant_offset (name, &offset)) + return NULL; + + offset = GINT32_TO_BE (offset); + + fake = g_malloc (sizeof *fake); + memcpy (fake, fake_zoneinfo_headers, sizeof fake_zoneinfo_headers); + memcpy (&fake->info.tt_gmtoff, &offset, sizeof offset); + fake->info.tt_isdst = FALSE; + fake->info.tt_abbrind = 0; + strcpy (fake->abbr, name); + + return g_bytes_new_take (fake, sizeof *fake); +} + +/* Construction {{{1 */ +/** + * g_time_zone_new: + * @identifier: (allow-none): a timezone identifier + * + * Creates a #GTimeZone corresponding to @identifier. + * + * @identifier can either be an RFC3339/ISO 8601 time offset or + * something that would pass as a valid value for the + * TZ environment variable (including %NULL). + * + * Valid RFC3339 time offsets are "Z" (for UTC) or + * "±hh:mm". ISO 8601 additionally specifies + * "±hhmm" and "±hh". + * + * The TZ environment variable typically corresponds + * to the name of a file in the zoneinfo database, but there are many + * other possibilities. Note that those other possibilities are not + * currently implemented, but are planned. + * + * g_time_zone_new_local() calls this function with the value of the + * TZ environment variable. This function itself is + * independent of the value of TZ, but if @identifier + * is %NULL then /etc/localtime will be consulted + * to discover the correct timezone. + * + * See RFC3339 + * §5.6 for a precise definition of valid RFC3339 time offsets + * (the time-offset expansion) and ISO 8601 for the + * full list of valid time offsets. See The + * GNU C Library manual for an explanation of the possible + * values of the TZ environment variable. + * + * You should release the return value by calling g_time_zone_unref() + * when you are done with it. + * + * Returns: the requested timezone + * + * Since: 2.26 + **/ +GTimeZone * +g_time_zone_new (const gchar *identifier) +{ + GTimeZone *tz; + GMappedFile *file; + + G_LOCK (time_zones); + if (time_zones == NULL) + time_zones = g_hash_table_new (g_str_hash, g_str_equal); + + if (identifier) + tz = g_hash_table_lookup (time_zones, identifier); + else + tz = NULL; + + if (tz == NULL) + { + tz = g_slice_new0 (GTimeZone); + tz->name = g_strdup (identifier); + tz->ref_count = 0; + + tz->zoneinfo = zone_for_constant_offset (identifier); + + if (tz->zoneinfo == NULL) + { + gchar *filename; + + /* identifier can be a relative or absolute path name; + if relative, it is interpreted starting from /usr/share/timezone + while the POSIX standard says it should start with :, + glibc allows both syntaxes, so we should too */ + if (identifier != NULL) + { + const gchar *tzdir; + + tzdir = getenv ("TZDIR"); + if (tzdir == NULL) + tzdir = "/usr/share/zoneinfo"; + + if (*identifier == ':') + identifier ++; + + if (g_path_is_absolute (identifier)) + filename = g_strdup (identifier); + else + filename = g_build_filename (tzdir, identifier, NULL); + } + else + filename = g_strdup ("/etc/localtime"); + + file = g_mapped_file_new (filename, FALSE, NULL); + if (file != NULL) + { + tz->zoneinfo = g_bytes_new_with_free_func (g_mapped_file_get_contents (file), + g_mapped_file_get_length (file), + (GDestroyNotify)g_mapped_file_unref, + g_mapped_file_ref (file)); + g_mapped_file_unref (file); + } + g_free (filename); + } + + if (tz->zoneinfo != NULL) + { + gsize size; + const struct tzhead *header = g_bytes_get_data (tz->zoneinfo, &size); + + /* we only bother to support version 2 */ + if (size < sizeof (struct tzhead) || memcmp (header, "TZif2", 5)) + { + g_bytes_unref (tz->zoneinfo); + tz->zoneinfo = NULL; + } + else + { + gint typecnt; + + /* we trust the file completely. */ + tz->header = (const struct tzhead *) + (((const gchar *) (header + 1)) + + guint32_from_be(header->tzh_ttisgmtcnt) + + guint32_from_be(header->tzh_ttisstdcnt) + + 8 * guint32_from_be(header->tzh_leapcnt) + + 5 * guint32_from_be(header->tzh_timecnt) + + 6 * guint32_from_be(header->tzh_typecnt) + + guint32_from_be(header->tzh_charcnt)); + + typecnt = guint32_from_be (tz->header->tzh_typecnt); + tz->timecnt = guint32_from_be (tz->header->tzh_timecnt); + tz->trans = (gconstpointer) (tz->header + 1); + tz->indices = (gconstpointer) (tz->trans + tz->timecnt); + tz->infos = (gconstpointer) (tz->indices + tz->timecnt); + tz->abbrs = (gconstpointer) (tz->infos + typecnt); + } + } + + if (identifier) + g_hash_table_insert (time_zones, tz->name, tz); + } + g_atomic_int_inc (&tz->ref_count); + G_UNLOCK (time_zones); + + return tz; +} + +/** + * g_time_zone_new_utc: + * + * Creates a #GTimeZone corresponding to UTC. + * + * This is equivalent to calling g_time_zone_new() with a value like + * "Z", "UTC", "+00", etc. + * + * You should release the return value by calling g_time_zone_unref() + * when you are done with it. + * + * Returns: the universal timezone + * + * Since: 2.26 + **/ +GTimeZone * +g_time_zone_new_utc (void) +{ + return g_time_zone_new ("UTC"); +} + +/** + * g_time_zone_new_local: + * + * Creates a #GTimeZone corresponding to local time. The local time + * zone may change between invocations to this function; for example, + * if the system administrator changes it. + * + * This is equivalent to calling g_time_zone_new() with the value of the + * TZ environment variable (including the possibility + * of %NULL). + * + * You should release the return value by calling g_time_zone_unref() + * when you are done with it. + * + * Returns: the local timezone + * + * Since: 2.26 + **/ +GTimeZone * +g_time_zone_new_local (void) +{ + return g_time_zone_new (getenv ("TZ")); +} + +/* Internal helpers {{{1 */ +inline static const struct ttinfo * +interval_info (GTimeZone *tz, + gint interval) +{ + if (interval) + return tz->infos + tz->indices[interval - 1]; + + return tz->infos; +} + +inline static gint64 +interval_start (GTimeZone *tz, + gint interval) +{ + if (interval) + return gint64_from_be (tz->trans[interval - 1]); + + return G_MININT64; +} + +inline static gint64 +interval_end (GTimeZone *tz, + gint interval) +{ + if (interval < tz->timecnt) + return gint64_from_be (tz->trans[interval]) - 1; + + return G_MAXINT64; +} + +inline static gint32 +interval_offset (GTimeZone *tz, + gint interval) +{ + return gint32_from_be (interval_info (tz, interval)->tt_gmtoff); +} + +inline static gboolean +interval_isdst (GTimeZone *tz, + gint interval) +{ + return interval_info (tz, interval)->tt_isdst; +} + +inline static guint8 +interval_abbrind (GTimeZone *tz, + gint interval) +{ + return interval_info (tz, interval)->tt_abbrind; +} + +inline static gint64 +interval_local_start (GTimeZone *tz, + gint interval) +{ + if (interval) + return interval_start (tz, interval) + interval_offset (tz, interval); + + return G_MININT64; +} + +inline static gint64 +interval_local_end (GTimeZone *tz, + gint interval) +{ + if (interval < tz->timecnt) + return interval_end (tz, interval) + interval_offset (tz, interval); + + return G_MAXINT64; +} + +static gboolean +interval_valid (GTimeZone *tz, + gint interval) +{ + return interval <= tz->timecnt; +} + +/* g_time_zone_find_interval() {{{1 */ + +/** + * g_time_zone_adjust_time: + * @tz: a #GTimeZone + * @type: the #GTimeType of @time_ + * @time_: a pointer to a number of seconds since January 1, 1970 + * + * Finds an interval within @tz that corresponds to the given @time_, + * possibly adjusting @time_ if required to fit into an interval. + * The meaning of @time_ depends on @type. + * + * This function is similar to g_time_zone_find_interval(), with the + * difference that it always succeeds (by making the adjustments + * described below). + * + * In any of the cases where g_time_zone_find_interval() succeeds then + * this function returns the same value, without modifying @time_. + * + * This function may, however, modify @time_ in order to deal with + * non-existent times. If the non-existent local @time_ of 02:30 were + * requested on March 13th 2010 in Toronto then this function would + * adjust @time_ to be 03:00 and return the interval containing the + * adjusted time. + * + * Returns: the interval containing @time_, never -1 + * + * Since: 2.26 + **/ +gint +g_time_zone_adjust_time (GTimeZone *tz, + GTimeType type, + gint64 *time_) +{ + gint i; + + if (tz->zoneinfo == NULL) + return 0; + + /* find the interval containing *time UTC + * TODO: this could be binary searched (or better) */ + for (i = 0; i < tz->timecnt; i++) + if (*time_ <= interval_end (tz, i)) + break; + + g_assert (interval_start (tz, i) <= *time_ && *time_ <= interval_end (tz, i)); + + if (type != G_TIME_TYPE_UNIVERSAL) + { + if (*time_ < interval_local_start (tz, i)) + /* if time came before the start of this interval... */ + { + i--; + + /* if it's not in the previous interval... */ + if (*time_ > interval_local_end (tz, i)) + { + /* it doesn't exist. fast-forward it. */ + i++; + *time_ = interval_local_start (tz, i); + } + } + + else if (*time_ > interval_local_end (tz, i)) + /* if time came after the end of this interval... */ + { + i++; + + /* if it's not in the next interval... */ + if (*time_ < interval_local_start (tz, i)) + /* it doesn't exist. fast-forward it. */ + *time_ = interval_local_start (tz, i); + } + + else if (interval_isdst (tz, i) != type) + /* it's in this interval, but dst flag doesn't match. + * check neighbours for a better fit. */ + { + if (i && *time_ <= interval_local_end (tz, i - 1)) + i--; + + else if (i < tz->timecnt && + *time_ >= interval_local_start (tz, i + 1)) + i++; + } + } + + return i; +} + +/** + * g_time_zone_find_interval: + * @tz: a #GTimeZone + * @type: the #GTimeType of @time_ + * @time_: a number of seconds since January 1, 1970 + * + * Finds an the interval within @tz that corresponds to the given @time_. + * The meaning of @time_ depends on @type. + * + * If @type is %G_TIME_TYPE_UNIVERSAL then this function will always + * succeed (since universal time is monotonic and continuous). + * + * Otherwise @time_ is treated is local time. The distinction between + * %G_TIME_TYPE_STANDARD and %G_TIME_TYPE_DAYLIGHT is ignored except in + * the case that the given @time_ is ambiguous. In Toronto, for example, + * 01:30 on November 7th 2010 occurred twice (once inside of daylight + * savings time and the next, an hour later, outside of daylight savings + * time). In this case, the different value of @type would result in a + * different interval being returned. + * + * It is still possible for this function to fail. In Toronto, for + * example, 02:00 on March 14th 2010 does not exist (due to the leap + * forward to begin daylight savings time). -1 is returned in that + * case. + * + * Returns: the interval containing @time_, or -1 in case of failure + * + * Since: 2.26 + */ +gint +g_time_zone_find_interval (GTimeZone *tz, + GTimeType type, + gint64 time_) +{ + gint i; + + if (tz->zoneinfo == NULL) + return 0; + + for (i = 0; i < tz->timecnt; i++) + if (time_ <= interval_end (tz, i)) + break; + + if (type == G_TIME_TYPE_UNIVERSAL) + return i; + + if (time_ < interval_local_start (tz, i)) + { + if (time_ > interval_local_end (tz, --i)) + return -1; + } + + else if (time_ > interval_local_end (tz, i)) + { + if (time_ < interval_local_start (tz, ++i)) + return -1; + } + + else if (interval_isdst (tz, i) != type) + { + if (i && time_ <= interval_local_end (tz, i - 1)) + i--; + + else if (i < tz->timecnt && time_ >= interval_local_start (tz, i + 1)) + i++; + } + + return i; +} + +/* Public API accessors {{{1 */ + +/** + * g_time_zone_get_abbreviation: + * @tz: a #GTimeZone + * @interval: an interval within the timezone + * + * Determines the time zone abbreviation to be used during a particular + * @interval of time in the time zone @tz. + * + * For example, in Toronto this is currently "EST" during the winter + * months and "EDT" during the summer months when daylight savings time + * is in effect. + * + * Returns: the time zone abbreviation, which belongs to @tz + * + * Since: 2.26 + **/ +const gchar * +g_time_zone_get_abbreviation (GTimeZone *tz, + gint interval) +{ + g_return_val_if_fail (interval_valid (tz, interval), NULL); + + if (tz->header == NULL) + return "UTC"; + + return tz->abbrs + interval_abbrind (tz, interval); +} + +/** + * g_time_zone_get_offset: + * @tz: a #GTimeZone + * @interval: an interval within the timezone + * + * Determines the offset to UTC in effect during a particular @interval + * of time in the time zone @tz. + * + * The offset is the number of seconds that you add to UTC time to + * arrive at local time for @tz (ie: negative numbers for time zones + * west of GMT, positive numbers for east). + * + * Returns: the number of seconds that should be added to UTC to get the + * local time in @tz + * + * Since: 2.26 + **/ +gint32 +g_time_zone_get_offset (GTimeZone *tz, + gint interval) +{ + g_return_val_if_fail (interval_valid (tz, interval), 0); + + if (tz->header == NULL) + return 0; + + return interval_offset (tz, interval); +} + +/** + * g_time_zone_is_dst: + * @tz: a #GTimeZone + * @interval: an interval within the timezone + * + * Determines if daylight savings time is in effect during a particular + * @interval of time in the time zone @tz. + * + * Returns: %TRUE if daylight savings time is in effect + * + * Since: 2.26 + **/ +gboolean +g_time_zone_is_dst (GTimeZone *tz, + gint interval) +{ + g_return_val_if_fail (interval_valid (tz, interval), FALSE); + + if (tz->header == NULL) + return FALSE; + + return interval_isdst (tz, interval); +} + +/* Epilogue {{{1 */ +/* vim:set foldmethod=marker: */ diff --git a/glib/glib/gtimezone.h b/glib/glib/gtimezone.h new file mode 100644 index 0000000..c877e8f --- /dev/null +++ b/glib/glib/gtimezone.h @@ -0,0 +1,81 @@ +/* + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + * + * Author: Ryan Lortie + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_TIME_ZONE_H__ +#define __G_TIME_ZONE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GTimeZone GTimeZone; + +/** + * GTimeType: + * @G_TIME_TYPE_STANDARD: the time is in local standard time + * @G_TIME_TYPE_DAYLIGHT: the time is in local daylight time + * @G_TIME_TYPE_UNIVERSAL: the time is in UTC + * + * Disambiguates a given time in two ways. + * + * First, specifies if the given time is in universal or local time. + * + * Second, if the time is in local time, specifies if it is local + * standard time or local daylight time. This is important for the case + * where the same local time occurs twice (during daylight savings time + * transitions, for example). + */ +typedef enum +{ + G_TIME_TYPE_STANDARD, + G_TIME_TYPE_DAYLIGHT, + G_TIME_TYPE_UNIVERSAL +} GTimeType; + +GTimeZone * g_time_zone_new (const gchar *identifier); +GTimeZone * g_time_zone_new_utc (void); +GTimeZone * g_time_zone_new_local (void); + +GTimeZone * g_time_zone_ref (GTimeZone *tz); +void g_time_zone_unref (GTimeZone *tz); + +gint g_time_zone_find_interval (GTimeZone *tz, + GTimeType type, + gint64 time_); + +gint g_time_zone_adjust_time (GTimeZone *tz, + GTimeType type, + gint64 *time_); + +const gchar * g_time_zone_get_abbreviation (GTimeZone *tz, + gint interval); +gint32 g_time_zone_get_offset (GTimeZone *tz, + gint interval); +gboolean g_time_zone_is_dst (GTimeZone *tz, + gint interval); + +G_END_DECLS + +#endif /* __G_TIME_ZONE_H__ */ diff --git a/glib/glib/gtrashstack.c b/glib/glib/gtrashstack.c new file mode 100644 index 0000000..71eca13 --- /dev/null +++ b/glib/glib/gtrashstack.c @@ -0,0 +1,94 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "config.h" + +/** + * SECTION:trash_stack + * @title: Trash Stacks + * @short_description: maintain a stack of unused allocated memory chunks + * + * A #GTrashStack is an efficient way to keep a stack of unused allocated + * memory chunks. Each memory chunk is required to be large enough to hold + * a #gpointer. This allows the stack to be maintained without any space + * overhead, since the stack pointers can be stored inside the memory chunks. + * + * There is no function to create a #GTrashStack. A %NULL #GTrashStack* + * is a perfectly valid empty stack. + */ + +/** + * GTrashStack: + * @next: pointer to the previous element of the stack, + * gets stored in the first sizeof (gpointer) + * bytes of the element + * + * Each piece of memory that is pushed onto the stack + * is cast to a GTrashStack*. + */ + +/** + * g_trash_stack_push: + * @stack_p: a #GTrashStack + * @data_p: the piece of memory to push on the stack + * + * Pushes a piece of memory onto a #GTrashStack. + */ + +/** + * g_trash_stack_pop: + * @stack_p: a #GTrashStack + * + * Pops a piece of memory off a #GTrashStack. + * + * Returns: the element at the top of the stack + */ + +/** + * g_trash_stack_peek: + * @stack_p: a #GTrashStack + * + * Returns the element at the top of a #GTrashStack + * which may be %NULL. + * + * Returns: the element at the top of the stack + */ + +/** + * g_trash_stack_height: + * @stack_p: a #GTrashStack + * + * Returns the height of a #GTrashStack. + * + * Note that execution of this function is of O(N) complexity + * where N denotes the number of items on the stack. + * + * Returns: the height of the stack + */ + +#define G_IMPLEMENT_INLINES 1 +#define __G_TRASH_STACK_C__ +#include "gtrashstack.h" diff --git a/glib/glib/gtrashstack.h b/glib/glib/gtrashstack.h new file mode 100644 index 0000000..3f226fe --- /dev/null +++ b/glib/glib/gtrashstack.h @@ -0,0 +1,103 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_TRASH_STACK_H__ +#define __G_TRASH_STACK_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GTrashStack GTrashStack; +struct _GTrashStack +{ + GTrashStack *next; +}; + +G_INLINE_FUNC void g_trash_stack_push (GTrashStack **stack_p, + gpointer data_p); +G_INLINE_FUNC gpointer g_trash_stack_pop (GTrashStack **stack_p); +G_INLINE_FUNC gpointer g_trash_stack_peek (GTrashStack **stack_p); +G_INLINE_FUNC guint g_trash_stack_height (GTrashStack **stack_p); + +#if defined (G_CAN_INLINE) || defined (__G_TRASH_STACK_C__) + +G_INLINE_FUNC void +g_trash_stack_push (GTrashStack **stack_p, + gpointer data_p) +{ + GTrashStack *data = (GTrashStack *) data_p; + + data->next = *stack_p; + *stack_p = data; +} +G_INLINE_FUNC gpointer +g_trash_stack_pop (GTrashStack **stack_p) +{ + GTrashStack *data; + + data = *stack_p; + if (data) + { + *stack_p = data->next; + /* NULLify private pointer here, most platforms store NULL as + * subsequent 0 bytes + */ + data->next = NULL; + } + + return data; +} +G_INLINE_FUNC gpointer +g_trash_stack_peek (GTrashStack **stack_p) +{ + GTrashStack *data; + + data = *stack_p; + + return data; +} +G_INLINE_FUNC guint +g_trash_stack_height (GTrashStack **stack_p) +{ + GTrashStack *data; + guint i = 0; + + for (data = *stack_p; data; data = data->next) + i++; + + return i; +} + +#endif /* G_CAN_INLINE || __G_TRASH_STACK_C__ */ + +G_END_DECLS + +#endif /* __G_UTILS_H__ */ diff --git a/glib/glib/gtree.c b/glib/glib/gtree.c new file mode 100644 index 0000000..d67629f --- /dev/null +++ b/glib/glib/gtree.c @@ -0,0 +1,1413 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe + */ + +#include "config.h" + +#include "gtree.h" + +#include "gatomic.h" +#include "gtestutils.h" +#include "gslice.h" + +/** + * SECTION:trees-binary + * @title: Balanced Binary Trees + * @short_description: a sorted collection of key/value pairs optimized + * for searching and traversing in order + * + * The #GTree structure and its associated functions provide a sorted + * collection of key/value pairs optimized for searching and traversing + * in order. + * + * To create a new #GTree use g_tree_new(). + * + * To insert a key/value pair into a #GTree use g_tree_insert(). + * + * To lookup the value corresponding to a given key, use + * g_tree_lookup() and g_tree_lookup_extended(). + * + * To find out the number of nodes in a #GTree, use g_tree_nnodes(). To + * get the height of a #GTree, use g_tree_height(). + * + * To traverse a #GTree, calling a function for each node visited in + * the traversal, use g_tree_foreach(). + * + * To remove a key/value pair use g_tree_remove(). + * + * To destroy a #GTree, use g_tree_destroy(). + **/ + +#undef G_TREE_DEBUG + +#define MAX_GTREE_HEIGHT 40 + +typedef struct _GTreeNode GTreeNode; + +/** + * GTree: + * + * The GTree struct is an opaque data + * structure representing a Balanced Binary Tree. It + * should be accessed only by using the following functions. + **/ +struct _GTree +{ + GTreeNode *root; + GCompareDataFunc key_compare; + GDestroyNotify key_destroy_func; + GDestroyNotify value_destroy_func; + gpointer key_compare_data; + guint nnodes; + gint ref_count; +}; + +struct _GTreeNode +{ + gpointer key; /* key for this node */ + gpointer value; /* value stored at this node */ + GTreeNode *left; /* left subtree */ + GTreeNode *right; /* right subtree */ + gint8 balance; /* height (right) - height (left) */ + guint8 left_child; + guint8 right_child; +}; + + +static GTreeNode* g_tree_node_new (gpointer key, + gpointer value); +static void g_tree_insert_internal (GTree *tree, + gpointer key, + gpointer value, + gboolean replace); +static gboolean g_tree_remove_internal (GTree *tree, + gconstpointer key, + gboolean steal); +static GTreeNode* g_tree_node_balance (GTreeNode *node); +static GTreeNode *g_tree_find_node (GTree *tree, + gconstpointer key); +static gint g_tree_node_pre_order (GTreeNode *node, + GTraverseFunc traverse_func, + gpointer data); +static gint g_tree_node_in_order (GTreeNode *node, + GTraverseFunc traverse_func, + gpointer data); +static gint g_tree_node_post_order (GTreeNode *node, + GTraverseFunc traverse_func, + gpointer data); +static gpointer g_tree_node_search (GTreeNode *node, + GCompareFunc search_func, + gconstpointer data); +static GTreeNode* g_tree_node_rotate_left (GTreeNode *node); +static GTreeNode* g_tree_node_rotate_right (GTreeNode *node); +#ifdef G_TREE_DEBUG +static void g_tree_node_check (GTreeNode *node); +#endif + + +static GTreeNode* +g_tree_node_new (gpointer key, + gpointer value) +{ + GTreeNode *node = g_slice_new (GTreeNode); + + node->balance = 0; + node->left = NULL; + node->right = NULL; + node->left_child = FALSE; + node->right_child = FALSE; + node->key = key; + node->value = value; + + return node; +} + +/** + * g_tree_new: + * @key_compare_func: the function used to order the nodes in the #GTree. + * It should return values similar to the standard strcmp() function - + * 0 if the two arguments are equal, a negative value if the first argument + * comes before the second, or a positive value if the first argument comes + * after the second. + * + * Creates a new #GTree. + * + * Return value: a new #GTree. + **/ +GTree* +g_tree_new (GCompareFunc key_compare_func) +{ + g_return_val_if_fail (key_compare_func != NULL, NULL); + + return g_tree_new_full ((GCompareDataFunc) key_compare_func, NULL, + NULL, NULL); +} + +/** + * g_tree_new_with_data: + * @key_compare_func: qsort()-style comparison function. + * @key_compare_data: data to pass to comparison function. + * + * Creates a new #GTree with a comparison function that accepts user data. + * See g_tree_new() for more details. + * + * Return value: a new #GTree. + **/ +GTree* +g_tree_new_with_data (GCompareDataFunc key_compare_func, + gpointer key_compare_data) +{ + g_return_val_if_fail (key_compare_func != NULL, NULL); + + return g_tree_new_full (key_compare_func, key_compare_data, + NULL, NULL); +} + +/** + * g_tree_new_full: + * @key_compare_func: qsort()-style comparison function. + * @key_compare_data: data to pass to comparison function. + * @key_destroy_func: a function to free the memory allocated for the key + * used when removing the entry from the #GTree or %NULL if you don't + * want to supply such a function. + * @value_destroy_func: a function to free the memory allocated for the + * value used when removing the entry from the #GTree or %NULL if you + * don't want to supply such a function. + * + * Creates a new #GTree like g_tree_new() and allows to specify functions + * to free the memory allocated for the key and value that get called when + * removing the entry from the #GTree. + * + * Return value: a new #GTree. + **/ +GTree* +g_tree_new_full (GCompareDataFunc key_compare_func, + gpointer key_compare_data, + GDestroyNotify key_destroy_func, + GDestroyNotify value_destroy_func) +{ + GTree *tree; + + g_return_val_if_fail (key_compare_func != NULL, NULL); + + tree = g_slice_new (GTree); + tree->root = NULL; + tree->key_compare = key_compare_func; + tree->key_destroy_func = key_destroy_func; + tree->value_destroy_func = value_destroy_func; + tree->key_compare_data = key_compare_data; + tree->nnodes = 0; + tree->ref_count = 1; + + return tree; +} + +static inline GTreeNode * +g_tree_first_node (GTree *tree) +{ + GTreeNode *tmp; + + if (!tree->root) + return NULL; + + tmp = tree->root; + + while (tmp->left_child) + tmp = tmp->left; + + return tmp; +} + +static inline GTreeNode * +g_tree_node_previous (GTreeNode *node) +{ + GTreeNode *tmp; + + tmp = node->left; + + if (node->left_child) + while (tmp->right_child) + tmp = tmp->right; + + return tmp; +} + +static inline GTreeNode * +g_tree_node_next (GTreeNode *node) +{ + GTreeNode *tmp; + + tmp = node->right; + + if (node->right_child) + while (tmp->left_child) + tmp = tmp->left; + + return tmp; +} + +static void +g_tree_remove_all (GTree *tree) +{ + GTreeNode *node; + GTreeNode *next; + + g_return_if_fail (tree != NULL); + + node = g_tree_first_node (tree); + + while (node) + { + next = g_tree_node_next (node); + + if (tree->key_destroy_func) + tree->key_destroy_func (node->key); + if (tree->value_destroy_func) + tree->value_destroy_func (node->value); + g_slice_free (GTreeNode, node); + + node = next; + } + + tree->root = NULL; + tree->nnodes = 0; +} + +/** + * g_tree_ref: + * @tree: a #GTree. + * + * Increments the reference count of @tree by one. It is safe to call + * this function from any thread. + * + * Return value: the passed in #GTree. + * + * Since: 2.22 + **/ +GTree * +g_tree_ref (GTree *tree) +{ + g_return_val_if_fail (tree != NULL, NULL); + + g_atomic_int_inc (&tree->ref_count); + + return tree; +} + +/** + * g_tree_unref: + * @tree: a #GTree. + * + * Decrements the reference count of @tree by one. If the reference count + * drops to 0, all keys and values will be destroyed (if destroy + * functions were specified) and all memory allocated by @tree will be + * released. + * + * It is safe to call this function from any thread. + * + * Since: 2.22 + **/ +void +g_tree_unref (GTree *tree) +{ + g_return_if_fail (tree != NULL); + + if (g_atomic_int_dec_and_test (&tree->ref_count)) + { + g_tree_remove_all (tree); + g_slice_free (GTree, tree); + } +} + +/** + * g_tree_destroy: + * @tree: a #GTree. + * + * Removes all keys and values from the #GTree and decreases its + * reference count by one. If keys and/or values are dynamically + * allocated, you should either free them first or create the #GTree + * using g_tree_new_full(). In the latter case the destroy functions + * you supplied will be called on all keys and values before destroying + * the #GTree. + **/ +void +g_tree_destroy (GTree *tree) +{ + g_return_if_fail (tree != NULL); + + g_tree_remove_all (tree); + g_tree_unref (tree); +} + +/** + * g_tree_insert: + * @tree: a #GTree. + * @key: the key to insert. + * @value: the value corresponding to the key. + * + * Inserts a key/value pair into a #GTree. If the given key already exists + * in the #GTree its corresponding value is set to the new value. If you + * supplied a value_destroy_func when creating the #GTree, the old value is + * freed using that function. If you supplied a @key_destroy_func when + * creating the #GTree, the passed key is freed using that function. + * + * The tree is automatically 'balanced' as new key/value pairs are added, + * so that the distance from the root to every leaf is as small as possible. + **/ +void +g_tree_insert (GTree *tree, + gpointer key, + gpointer value) +{ + g_return_if_fail (tree != NULL); + + g_tree_insert_internal (tree, key, value, FALSE); + +#ifdef G_TREE_DEBUG + g_tree_node_check (tree->root); +#endif +} + +/** + * g_tree_replace: + * @tree: a #GTree. + * @key: the key to insert. + * @value: the value corresponding to the key. + * + * Inserts a new key and value into a #GTree similar to g_tree_insert(). + * The difference is that if the key already exists in the #GTree, it gets + * replaced by the new key. If you supplied a @value_destroy_func when + * creating the #GTree, the old value is freed using that function. If you + * supplied a @key_destroy_func when creating the #GTree, the old key is + * freed using that function. + * + * The tree is automatically 'balanced' as new key/value pairs are added, + * so that the distance from the root to every leaf is as small as possible. + **/ +void +g_tree_replace (GTree *tree, + gpointer key, + gpointer value) +{ + g_return_if_fail (tree != NULL); + + g_tree_insert_internal (tree, key, value, TRUE); + +#ifdef G_TREE_DEBUG + g_tree_node_check (tree->root); +#endif +} + +/* internal insert routine */ +static void +g_tree_insert_internal (GTree *tree, + gpointer key, + gpointer value, + gboolean replace) +{ + GTreeNode *node; + GTreeNode *path[MAX_GTREE_HEIGHT]; + int idx; + + g_return_if_fail (tree != NULL); + + if (!tree->root) + { + tree->root = g_tree_node_new (key, value); + tree->nnodes++; + return; + } + + idx = 0; + path[idx++] = NULL; + node = tree->root; + + while (1) + { + int cmp = tree->key_compare (key, node->key, tree->key_compare_data); + + if (cmp == 0) + { + if (tree->value_destroy_func) + tree->value_destroy_func (node->value); + + node->value = value; + + if (replace) + { + if (tree->key_destroy_func) + tree->key_destroy_func (node->key); + + node->key = key; + } + else + { + /* free the passed key */ + if (tree->key_destroy_func) + tree->key_destroy_func (key); + } + + return; + } + else if (cmp < 0) + { + if (node->left_child) + { + path[idx++] = node; + node = node->left; + } + else + { + GTreeNode *child = g_tree_node_new (key, value); + + child->left = node->left; + child->right = node; + node->left = child; + node->left_child = TRUE; + node->balance -= 1; + + tree->nnodes++; + + break; + } + } + else + { + if (node->right_child) + { + path[idx++] = node; + node = node->right; + } + else + { + GTreeNode *child = g_tree_node_new (key, value); + + child->right = node->right; + child->left = node; + node->right = child; + node->right_child = TRUE; + node->balance += 1; + + tree->nnodes++; + + break; + } + } + } + + /* restore balance. This is the goodness of a non-recursive + implementation, when we are done with balancing we 'break' + the loop and we are done. */ + while (1) + { + GTreeNode *bparent = path[--idx]; + gboolean left_node = (bparent && node == bparent->left); + g_assert (!bparent || bparent->left == node || bparent->right == node); + + if (node->balance < -1 || node->balance > 1) + { + node = g_tree_node_balance (node); + if (bparent == NULL) + tree->root = node; + else if (left_node) + bparent->left = node; + else + bparent->right = node; + } + + if (node->balance == 0 || bparent == NULL) + break; + + if (left_node) + bparent->balance -= 1; + else + bparent->balance += 1; + + node = bparent; + } +} + +/** + * g_tree_remove: + * @tree: a #GTree. + * @key: the key to remove. + * + * Removes a key/value pair from a #GTree. + * + * If the #GTree was created using g_tree_new_full(), the key and value + * are freed using the supplied destroy functions, otherwise you have to + * make sure that any dynamically allocated values are freed yourself. + * If the key does not exist in the #GTree, the function does nothing. + * + * Returns: %TRUE if the key was found (prior to 2.8, this function returned + * nothing) + **/ +gboolean +g_tree_remove (GTree *tree, + gconstpointer key) +{ + gboolean removed; + + g_return_val_if_fail (tree != NULL, FALSE); + + removed = g_tree_remove_internal (tree, key, FALSE); + +#ifdef G_TREE_DEBUG + g_tree_node_check (tree->root); +#endif + + return removed; +} + +/** + * g_tree_steal: + * @tree: a #GTree. + * @key: the key to remove. + * + * Removes a key and its associated value from a #GTree without calling + * the key and value destroy functions. + * + * If the key does not exist in the #GTree, the function does nothing. + * + * Returns: %TRUE if the key was found (prior to 2.8, this function returned + * nothing) + **/ +gboolean +g_tree_steal (GTree *tree, + gconstpointer key) +{ + gboolean removed; + + g_return_val_if_fail (tree != NULL, FALSE); + + removed = g_tree_remove_internal (tree, key, TRUE); + +#ifdef G_TREE_DEBUG + g_tree_node_check (tree->root); +#endif + + return removed; +} + +/* internal remove routine */ +static gboolean +g_tree_remove_internal (GTree *tree, + gconstpointer key, + gboolean steal) +{ + GTreeNode *node, *parent, *balance; + GTreeNode *path[MAX_GTREE_HEIGHT]; + int idx; + gboolean left_node; + + g_return_val_if_fail (tree != NULL, FALSE); + + if (!tree->root) + return FALSE; + + idx = 0; + path[idx++] = NULL; + node = tree->root; + + while (1) + { + int cmp = tree->key_compare (key, node->key, tree->key_compare_data); + + if (cmp == 0) + break; + else if (cmp < 0) + { + if (!node->left_child) + return FALSE; + + path[idx++] = node; + node = node->left; + } + else + { + if (!node->right_child) + return FALSE; + + path[idx++] = node; + node = node->right; + } + } + + /* the following code is almost equal to g_tree_remove_node, + except that we do not have to call g_tree_node_parent. */ + balance = parent = path[--idx]; + g_assert (!parent || parent->left == node || parent->right == node); + left_node = (parent && node == parent->left); + + if (!node->left_child) + { + if (!node->right_child) + { + if (!parent) + tree->root = NULL; + else if (left_node) + { + parent->left_child = FALSE; + parent->left = node->left; + parent->balance += 1; + } + else + { + parent->right_child = FALSE; + parent->right = node->right; + parent->balance -= 1; + } + } + else /* node has a right child */ + { + GTreeNode *tmp = g_tree_node_next (node); + tmp->left = node->left; + + if (!parent) + tree->root = node->right; + else if (left_node) + { + parent->left = node->right; + parent->balance += 1; + } + else + { + parent->right = node->right; + parent->balance -= 1; + } + } + } + else /* node has a left child */ + { + if (!node->right_child) + { + GTreeNode *tmp = g_tree_node_previous (node); + tmp->right = node->right; + + if (parent == NULL) + tree->root = node->left; + else if (left_node) + { + parent->left = node->left; + parent->balance += 1; + } + else + { + parent->right = node->left; + parent->balance -= 1; + } + } + else /* node has a both children (pant, pant!) */ + { + GTreeNode *prev = node->left; + GTreeNode *next = node->right; + GTreeNode *nextp = node; + int old_idx = idx + 1; + idx++; + + /* path[idx] == parent */ + /* find the immediately next node (and its parent) */ + while (next->left_child) + { + path[++idx] = nextp = next; + next = next->left; + } + + path[old_idx] = next; + balance = path[idx]; + + /* remove 'next' from the tree */ + if (nextp != node) + { + if (next->right_child) + nextp->left = next->right; + else + nextp->left_child = FALSE; + nextp->balance += 1; + + next->right_child = TRUE; + next->right = node->right; + } + else + node->balance -= 1; + + /* set the prev to point to the right place */ + while (prev->right_child) + prev = prev->right; + prev->right = next; + + /* prepare 'next' to replace 'node' */ + next->left_child = TRUE; + next->left = node->left; + next->balance = node->balance; + + if (!parent) + tree->root = next; + else if (left_node) + parent->left = next; + else + parent->right = next; + } + } + + /* restore balance */ + if (balance) + while (1) + { + GTreeNode *bparent = path[--idx]; + g_assert (!bparent || bparent->left == balance || bparent->right == balance); + left_node = (bparent && balance == bparent->left); + + if(balance->balance < -1 || balance->balance > 1) + { + balance = g_tree_node_balance (balance); + if (!bparent) + tree->root = balance; + else if (left_node) + bparent->left = balance; + else + bparent->right = balance; + } + + if (balance->balance != 0 || !bparent) + break; + + if (left_node) + bparent->balance += 1; + else + bparent->balance -= 1; + + balance = bparent; + } + + if (!steal) + { + if (tree->key_destroy_func) + tree->key_destroy_func (node->key); + if (tree->value_destroy_func) + tree->value_destroy_func (node->value); + } + + g_slice_free (GTreeNode, node); + + tree->nnodes--; + + return TRUE; +} + +/** + * g_tree_lookup: + * @tree: a #GTree. + * @key: the key to look up. + * + * Gets the value corresponding to the given key. Since a #GTree is + * automatically balanced as key/value pairs are added, key lookup is very + * fast. + * + * Return value: the value corresponding to the key, or %NULL if the key was + * not found. + **/ +gpointer +g_tree_lookup (GTree *tree, + gconstpointer key) +{ + GTreeNode *node; + + g_return_val_if_fail (tree != NULL, NULL); + + node = g_tree_find_node (tree, key); + + return node ? node->value : NULL; +} + +/** + * g_tree_lookup_extended: + * @tree: a #GTree. + * @lookup_key: the key to look up. + * @orig_key: returns the original key. + * @value: returns the value associated with the key. + * + * Looks up a key in the #GTree, returning the original key and the + * associated value and a #gboolean which is %TRUE if the key was found. This + * is useful if you need to free the memory allocated for the original key, + * for example before calling g_tree_remove(). + * + * Return value: %TRUE if the key was found in the #GTree. + **/ +gboolean +g_tree_lookup_extended (GTree *tree, + gconstpointer lookup_key, + gpointer *orig_key, + gpointer *value) +{ + GTreeNode *node; + + g_return_val_if_fail (tree != NULL, FALSE); + + node = g_tree_find_node (tree, lookup_key); + + if (node) + { + if (orig_key) + *orig_key = node->key; + if (value) + *value = node->value; + return TRUE; + } + else + return FALSE; +} + +/** + * g_tree_foreach: + * @tree: a #GTree. + * @func: the function to call for each node visited. If this function + * returns %TRUE, the traversal is stopped. + * @user_data: user data to pass to the function. + * + * Calls the given function for each of the key/value pairs in the #GTree. + * The function is passed the key and value of each pair, and the given + * @data parameter. The tree is traversed in sorted order. + * + * The tree may not be modified while iterating over it (you can't + * add/remove items). To remove all items matching a predicate, you need + * to add each item to a list in your #GTraverseFunc as you walk over + * the tree, then walk the list and remove each item. + **/ +void +g_tree_foreach (GTree *tree, + GTraverseFunc func, + gpointer user_data) +{ + GTreeNode *node; + + g_return_if_fail (tree != NULL); + + if (!tree->root) + return; + + node = g_tree_first_node (tree); + + while (node) + { + if ((*func) (node->key, node->value, user_data)) + break; + + node = g_tree_node_next (node); + } +} + +/** + * g_tree_traverse: + * @tree: a #GTree. + * @traverse_func: the function to call for each node visited. If this + * function returns %TRUE, the traversal is stopped. + * @traverse_type: the order in which nodes are visited, one of %G_IN_ORDER, + * %G_PRE_ORDER and %G_POST_ORDER. + * @user_data: user data to pass to the function. + * + * Calls the given function for each node in the #GTree. + * + * Deprecated:2.2: The order of a balanced tree is somewhat arbitrary. If you + * just want to visit all nodes in sorted order, use g_tree_foreach() + * instead. If you really need to visit nodes in a different order, consider + * using an N-ary Tree. + **/ +/** + * GTraverseFunc: + * @key: a key of a #GTree node. + * @value: the value corresponding to the key. + * @data: user data passed to g_tree_traverse(). + * @Returns: %TRUE to stop the traversal. + * + * Specifies the type of function passed to g_tree_traverse(). It is + * passed the key and value of each node, together with the @user_data + * parameter passed to g_tree_traverse(). If the function returns + * %TRUE, the traversal is stopped. + **/ +/** + * GTraverseType: + * @G_IN_ORDER: vists a node's left child first, then the node itself, + * then its right child. This is the one to use if you + * want the output sorted according to the compare + * function. + * @G_PRE_ORDER: visits a node, then its children. + * @G_POST_ORDER: visits the node's children, then the node itself. + * @G_LEVEL_ORDER: is not implemented for Balanced Binary + * Trees. For N-ary Trees, it + * vists the root node first, then its children, then + * its grandchildren, and so on. Note that this is less + * efficient than the other orders. + * + * Specifies the type of traveral performed by g_tree_traverse(), + * g_node_traverse() and g_node_find(). + **/ +void +g_tree_traverse (GTree *tree, + GTraverseFunc traverse_func, + GTraverseType traverse_type, + gpointer user_data) +{ + g_return_if_fail (tree != NULL); + + if (!tree->root) + return; + + switch (traverse_type) + { + case G_PRE_ORDER: + g_tree_node_pre_order (tree->root, traverse_func, user_data); + break; + + case G_IN_ORDER: + g_tree_node_in_order (tree->root, traverse_func, user_data); + break; + + case G_POST_ORDER: + g_tree_node_post_order (tree->root, traverse_func, user_data); + break; + + case G_LEVEL_ORDER: + g_warning ("g_tree_traverse(): traverse type G_LEVEL_ORDER isn't implemented."); + break; + } +} + +/** + * g_tree_search: + * @tree: a #GTree + * @search_func: a function used to search the #GTree + * @user_data: the data passed as the second argument to @search_func + * + * Searches a #GTree using @search_func. + * + * The @search_func is called with a pointer to the key of a key/value + * pair in the tree, and the passed in @user_data. If @search_func returns + * 0 for a key/value pair, then the corresponding value is returned as + * the result of g_tree_search(). If @search_func returns -1, searching + * will proceed among the key/value pairs that have a smaller key; if + * @search_func returns 1, searching will proceed among the key/value + * pairs that have a larger key. + * + * Return value: the value corresponding to the found key, or %NULL if + * the key was not found. + */ +gpointer +g_tree_search (GTree *tree, + GCompareFunc search_func, + gconstpointer user_data) +{ + g_return_val_if_fail (tree != NULL, NULL); + + if (tree->root) + return g_tree_node_search (tree->root, search_func, user_data); + else + return NULL; +} + +/** + * g_tree_height: + * @tree: a #GTree. + * + * Gets the height of a #GTree. + * + * If the #GTree contains no nodes, the height is 0. + * If the #GTree contains only one root node the height is 1. + * If the root node has children the height is 2, etc. + * + * Return value: the height of the #GTree. + **/ +gint +g_tree_height (GTree *tree) +{ + GTreeNode *node; + gint height; + + g_return_val_if_fail (tree != NULL, 0); + + if (!tree->root) + return 0; + + height = 0; + node = tree->root; + + while (1) + { + height += 1 + MAX(node->balance, 0); + + if (!node->left_child) + return height; + + node = node->left; + } +} + +/** + * g_tree_nnodes: + * @tree: a #GTree. + * + * Gets the number of nodes in a #GTree. + * + * Return value: the number of nodes in the #GTree. + **/ +gint +g_tree_nnodes (GTree *tree) +{ + g_return_val_if_fail (tree != NULL, 0); + + return tree->nnodes; +} + +static GTreeNode* +g_tree_node_balance (GTreeNode *node) +{ + if (node->balance < -1) + { + if (node->left->balance > 0) + node->left = g_tree_node_rotate_left (node->left); + node = g_tree_node_rotate_right (node); + } + else if (node->balance > 1) + { + if (node->right->balance < 0) + node->right = g_tree_node_rotate_right (node->right); + node = g_tree_node_rotate_left (node); + } + + return node; +} + +static GTreeNode * +g_tree_find_node (GTree *tree, + gconstpointer key) +{ + GTreeNode *node; + gint cmp; + + node = tree->root; + if (!node) + return NULL; + + while (1) + { + cmp = tree->key_compare (key, node->key, tree->key_compare_data); + if (cmp == 0) + return node; + else if (cmp < 0) + { + if (!node->left_child) + return NULL; + + node = node->left; + } + else + { + if (!node->right_child) + return NULL; + + node = node->right; + } + } +} + +static gint +g_tree_node_pre_order (GTreeNode *node, + GTraverseFunc traverse_func, + gpointer data) +{ + if ((*traverse_func) (node->key, node->value, data)) + return TRUE; + + if (node->left_child) + { + if (g_tree_node_pre_order (node->left, traverse_func, data)) + return TRUE; + } + + if (node->right_child) + { + if (g_tree_node_pre_order (node->right, traverse_func, data)) + return TRUE; + } + + return FALSE; +} + +static gint +g_tree_node_in_order (GTreeNode *node, + GTraverseFunc traverse_func, + gpointer data) +{ + if (node->left_child) + { + if (g_tree_node_in_order (node->left, traverse_func, data)) + return TRUE; + } + + if ((*traverse_func) (node->key, node->value, data)) + return TRUE; + + if (node->right_child) + { + if (g_tree_node_in_order (node->right, traverse_func, data)) + return TRUE; + } + + return FALSE; +} + +static gint +g_tree_node_post_order (GTreeNode *node, + GTraverseFunc traverse_func, + gpointer data) +{ + if (node->left_child) + { + if (g_tree_node_post_order (node->left, traverse_func, data)) + return TRUE; + } + + if (node->right_child) + { + if (g_tree_node_post_order (node->right, traverse_func, data)) + return TRUE; + } + + if ((*traverse_func) (node->key, node->value, data)) + return TRUE; + + return FALSE; +} + +static gpointer +g_tree_node_search (GTreeNode *node, + GCompareFunc search_func, + gconstpointer data) +{ + gint dir; + + if (!node) + return NULL; + + while (1) + { + dir = (* search_func) (node->key, data); + if (dir == 0) + return node->value; + else if (dir < 0) + { + if (!node->left_child) + return NULL; + + node = node->left; + } + else + { + if (!node->right_child) + return NULL; + + node = node->right; + } + } +} + +static GTreeNode* +g_tree_node_rotate_left (GTreeNode *node) +{ + GTreeNode *right; + gint a_bal; + gint b_bal; + + right = node->right; + + if (right->left_child) + node->right = right->left; + else + { + node->right_child = FALSE; + right->left_child = TRUE; + } + right->left = node; + + a_bal = node->balance; + b_bal = right->balance; + + if (b_bal <= 0) + { + if (a_bal >= 1) + right->balance = b_bal - 1; + else + right->balance = a_bal + b_bal - 2; + node->balance = a_bal - 1; + } + else + { + if (a_bal <= b_bal) + right->balance = a_bal - 2; + else + right->balance = b_bal - 1; + node->balance = a_bal - b_bal - 1; + } + + return right; +} + +static GTreeNode* +g_tree_node_rotate_right (GTreeNode *node) +{ + GTreeNode *left; + gint a_bal; + gint b_bal; + + left = node->left; + + if (left->right_child) + node->left = left->right; + else + { + node->left_child = FALSE; + left->right_child = TRUE; + } + left->right = node; + + a_bal = node->balance; + b_bal = left->balance; + + if (b_bal <= 0) + { + if (b_bal > a_bal) + left->balance = b_bal + 1; + else + left->balance = a_bal + 2; + node->balance = a_bal - b_bal + 1; + } + else + { + if (a_bal <= -1) + left->balance = b_bal + 1; + else + left->balance = a_bal + b_bal + 2; + node->balance = a_bal + 1; + } + + return left; +} + +#ifdef G_TREE_DEBUG +static gint +g_tree_node_height (GTreeNode *node) +{ + gint left_height; + gint right_height; + + if (node) + { + left_height = 0; + right_height = 0; + + if (node->left_child) + left_height = g_tree_node_height (node->left); + + if (node->right_child) + right_height = g_tree_node_height (node->right); + + return MAX (left_height, right_height) + 1; + } + + return 0; +} + +static void +g_tree_node_check (GTreeNode *node) +{ + gint left_height; + gint right_height; + gint balance; + GTreeNode *tmp; + + if (node) + { + if (node->left_child) + { + tmp = g_tree_node_previous (node); + g_assert (tmp->right == node); + } + + if (node->right_child) + { + tmp = g_tree_node_next (node); + g_assert (tmp->left == node); + } + + left_height = 0; + right_height = 0; + + if (node->left_child) + left_height = g_tree_node_height (node->left); + if (node->right_child) + right_height = g_tree_node_height (node->right); + + balance = right_height - left_height; + g_assert (balance == node->balance); + + if (node->left_child) + g_tree_node_check (node->left); + if (node->right_child) + g_tree_node_check (node->right); + } +} + +static void +g_tree_node_dump (GTreeNode *node, + gint indent) +{ + g_print ("%*s%c\n", indent, "", *(char *)node->key); + + if (node->left_child) + g_tree_node_dump (node->left, indent + 2); + else if (node->left) + g_print ("%*s<%c\n", indent + 2, "", *(char *)node->left->key); + + if (node->right_child) + g_tree_node_dump (node->right, indent + 2); + else if (node->right) + g_print ("%*s>%c\n", indent + 2, "", *(char *)node->right->key); +} + + +void +g_tree_dump (GTree *tree) +{ + if (tree->root) + g_tree_node_dump (tree->root, 0); +} +#endif diff --git a/glib/glib/gtree.h b/glib/glib/gtree.h new file mode 100644 index 0000000..e17a518 --- /dev/null +++ b/glib/glib/gtree.h @@ -0,0 +1,90 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_TREE_H__ +#define __G_TREE_H__ + +#include + +G_BEGIN_DECLS + +typedef struct _GTree GTree; + +typedef gboolean (*GTraverseFunc) (gpointer key, + gpointer value, + gpointer data); + +/* Balanced binary trees + */ +GTree* g_tree_new (GCompareFunc key_compare_func); +GTree* g_tree_new_with_data (GCompareDataFunc key_compare_func, + gpointer key_compare_data); +GTree* g_tree_new_full (GCompareDataFunc key_compare_func, + gpointer key_compare_data, + GDestroyNotify key_destroy_func, + GDestroyNotify value_destroy_func); +GTree* g_tree_ref (GTree *tree); +void g_tree_unref (GTree *tree); +void g_tree_destroy (GTree *tree); +void g_tree_insert (GTree *tree, + gpointer key, + gpointer value); +void g_tree_replace (GTree *tree, + gpointer key, + gpointer value); +gboolean g_tree_remove (GTree *tree, + gconstpointer key); +gboolean g_tree_steal (GTree *tree, + gconstpointer key); +gpointer g_tree_lookup (GTree *tree, + gconstpointer key); +gboolean g_tree_lookup_extended (GTree *tree, + gconstpointer lookup_key, + gpointer *orig_key, + gpointer *value); +void g_tree_foreach (GTree *tree, + GTraverseFunc func, + gpointer user_data); + +GLIB_DEPRECATED +void g_tree_traverse (GTree *tree, + GTraverseFunc traverse_func, + GTraverseType traverse_type, + gpointer user_data); + +gpointer g_tree_search (GTree *tree, + GCompareFunc search_func, + gconstpointer user_data); +gint g_tree_height (GTree *tree); +gint g_tree_nnodes (GTree *tree); + +G_END_DECLS + +#endif /* __G_TREE_H__ */ diff --git a/glib/glib/gtypes.h b/glib/glib/gtypes.h new file mode 100644 index 0000000..7e4c8ea --- /dev/null +++ b/glib/glib/gtypes.h @@ -0,0 +1,484 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_TYPES_H__ +#define __G_TYPES_H__ + +#include +#include +#include +#include + +G_BEGIN_DECLS + +/* Provide type definitions for commonly used types. + * These are useful because a "gint8" can be adjusted + * to be 1 byte (8 bits) on all platforms. Similarly and + * more importantly, "gint32" can be adjusted to be + * 4 bytes (32 bits) on all platforms. + */ + +typedef char gchar; +typedef short gshort; +typedef long glong; +typedef int gint; +typedef gint gboolean; + +typedef unsigned char guchar; +typedef unsigned short gushort; +typedef unsigned long gulong; +typedef unsigned int guint; + +typedef float gfloat; +typedef double gdouble; + +/* Define min and max constants for the fixed size numerical types */ +#define G_MININT8 ((gint8) 0x80) +#define G_MAXINT8 ((gint8) 0x7f) +#define G_MAXUINT8 ((guint8) 0xff) + +#define G_MININT16 ((gint16) 0x8000) +#define G_MAXINT16 ((gint16) 0x7fff) +#define G_MAXUINT16 ((guint16) 0xffff) + +#define G_MININT32 ((gint32) 0x80000000) +#define G_MAXINT32 ((gint32) 0x7fffffff) +#define G_MAXUINT32 ((guint32) 0xffffffff) + +#define G_MININT64 ((gint64) G_GINT64_CONSTANT(0x8000000000000000)) +#define G_MAXINT64 G_GINT64_CONSTANT(0x7fffffffffffffff) +#define G_MAXUINT64 G_GINT64_CONSTANT(0xffffffffffffffffU) + +typedef void* gpointer; +typedef const void *gconstpointer; + +typedef gint (*GCompareFunc) (gconstpointer a, + gconstpointer b); +typedef gint (*GCompareDataFunc) (gconstpointer a, + gconstpointer b, + gpointer user_data); +typedef gboolean (*GEqualFunc) (gconstpointer a, + gconstpointer b); +typedef void (*GDestroyNotify) (gpointer data); +typedef void (*GFunc) (gpointer data, + gpointer user_data); +typedef guint (*GHashFunc) (gconstpointer key); +typedef void (*GHFunc) (gpointer key, + gpointer value, + gpointer user_data); + +/** + * GFreeFunc: + * @data: a data pointer + * + * Declares a type of function which takes an arbitrary + * data pointer argument and has no return value. It is + * not currently used in GLib or GTK+. + */ +typedef void (*GFreeFunc) (gpointer data); + +/** + * GTranslateFunc: + * @str: the untranslated string + * @data: user data specified when installing the function, e.g. + * in g_option_group_set_translate_func() + * + * The type of functions which are used to translate user-visible + * strings, for output. + * + * Returns: a translation of the string for the current locale. + * The returned string is owned by GLib and must not be freed. + */ +typedef const gchar * (*GTranslateFunc) (const gchar *str, + gpointer data); + + +/* Define some mathematical constants that aren't available + * symbolically in some strict ISO C implementations. + * + * Note that the large number of digits used in these definitions + * doesn't imply that GLib or current computers in general would be + * able to handle floating point numbers with an accuracy like this. + * It's mostly an exercise in futility and future proofing. For + * extended precision floating point support, look somewhere else + * than GLib. + */ +#define G_E 2.7182818284590452353602874713526624977572470937000 +#define G_LN2 0.69314718055994530941723212145817656807550013436026 +#define G_LN10 2.3025850929940456840179914546843642076011014886288 +#define G_PI 3.1415926535897932384626433832795028841971693993751 +#define G_PI_2 1.5707963267948966192313216916397514420985846996876 +#define G_PI_4 0.78539816339744830961566084581987572104929234984378 +#define G_SQRT2 1.4142135623730950488016887242096980785696718753769 + +/* Portable endian checks and conversions + * + * glibconfig.h defines G_BYTE_ORDER which expands to one of + * the below macros. + */ +#define G_LITTLE_ENDIAN 1234 +#define G_BIG_ENDIAN 4321 +#define G_PDP_ENDIAN 3412 /* unused, need specific PDP check */ + + +/* Basic bit swapping functions + */ +#define GUINT16_SWAP_LE_BE_CONSTANT(val) ((guint16) ( \ + (guint16) ((guint16) (val) >> 8) | \ + (guint16) ((guint16) (val) << 8))) + +#define GUINT32_SWAP_LE_BE_CONSTANT(val) ((guint32) ( \ + (((guint32) (val) & (guint32) 0x000000ffU) << 24) | \ + (((guint32) (val) & (guint32) 0x0000ff00U) << 8) | \ + (((guint32) (val) & (guint32) 0x00ff0000U) >> 8) | \ + (((guint32) (val) & (guint32) 0xff000000U) >> 24))) + +#define GUINT64_SWAP_LE_BE_CONSTANT(val) ((guint64) ( \ + (((guint64) (val) & \ + (guint64) G_GINT64_CONSTANT (0x00000000000000ffU)) << 56) | \ + (((guint64) (val) & \ + (guint64) G_GINT64_CONSTANT (0x000000000000ff00U)) << 40) | \ + (((guint64) (val) & \ + (guint64) G_GINT64_CONSTANT (0x0000000000ff0000U)) << 24) | \ + (((guint64) (val) & \ + (guint64) G_GINT64_CONSTANT (0x00000000ff000000U)) << 8) | \ + (((guint64) (val) & \ + (guint64) G_GINT64_CONSTANT (0x000000ff00000000U)) >> 8) | \ + (((guint64) (val) & \ + (guint64) G_GINT64_CONSTANT (0x0000ff0000000000U)) >> 24) | \ + (((guint64) (val) & \ + (guint64) G_GINT64_CONSTANT (0x00ff000000000000U)) >> 40) | \ + (((guint64) (val) & \ + (guint64) G_GINT64_CONSTANT (0xff00000000000000U)) >> 56))) + +/* Arch specific stuff for speed + */ +#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__) + +# if __GNUC__ >= 4 && defined (__GNUC_MINOR__) && __GNUC_MINOR__ >= 3 +# define GUINT32_SWAP_LE_BE(val) ((guint32) __builtin_bswap32 ((gint32) val)) +# define GUINT64_SWAP_LE_BE(val) ((guint64) __builtin_bswap64 ((gint64) val)) +# endif + +# if defined (__i386__) +# define GUINT16_SWAP_LE_BE_IA32(val) \ + (G_GNUC_EXTENSION \ + ({ register guint16 __v, __x = ((guint16) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = GUINT16_SWAP_LE_BE_CONSTANT (__x); \ + else \ + __asm__ ("rorw $8, %w0" \ + : "=r" (__v) \ + : "0" (__x) \ + : "cc"); \ + __v; })) +# if !defined (__i486__) && !defined (__i586__) \ + && !defined (__pentium__) && !defined (__i686__) \ + && !defined (__pentiumpro__) && !defined (__pentium4__) +# define GUINT32_SWAP_LE_BE_IA32(val) \ + (G_GNUC_EXTENSION \ + ({ register guint32 __v, __x = ((guint32) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = GUINT32_SWAP_LE_BE_CONSTANT (__x); \ + else \ + __asm__ ("rorw $8, %w0\n\t" \ + "rorl $16, %0\n\t" \ + "rorw $8, %w0" \ + : "=r" (__v) \ + : "0" (__x) \ + : "cc"); \ + __v; })) +# else /* 486 and higher has bswap */ +# define GUINT32_SWAP_LE_BE_IA32(val) \ + (G_GNUC_EXTENSION \ + ({ register guint32 __v, __x = ((guint32) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = GUINT32_SWAP_LE_BE_CONSTANT (__x); \ + else \ + __asm__ ("bswap %0" \ + : "=r" (__v) \ + : "0" (__x)); \ + __v; })) +# endif /* processor specific 32-bit stuff */ +# define GUINT64_SWAP_LE_BE_IA32(val) \ + (G_GNUC_EXTENSION \ + ({ union { guint64 __ll; \ + guint32 __l[2]; } __w, __r; \ + __w.__ll = ((guint64) (val)); \ + if (__builtin_constant_p (__w.__ll)) \ + __r.__ll = GUINT64_SWAP_LE_BE_CONSTANT (__w.__ll); \ + else \ + { \ + __r.__l[0] = GUINT32_SWAP_LE_BE (__w.__l[1]); \ + __r.__l[1] = GUINT32_SWAP_LE_BE (__w.__l[0]); \ + } \ + __r.__ll; })) + /* Possibly just use the constant version and let gcc figure it out? */ +# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_IA32 (val)) +# ifndef GUINT32_SWAP_LE_BE +# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA32 (val)) +# endif +# ifndef GUINT64_SWAP_LE_BE +# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA32 (val)) +# endif +# elif defined (__ia64__) +# define GUINT16_SWAP_LE_BE_IA64(val) \ + (G_GNUC_EXTENSION \ + ({ register guint16 __v, __x = ((guint16) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = GUINT16_SWAP_LE_BE_CONSTANT (__x); \ + else \ + __asm__ __volatile__ ("shl %0 = %1, 48 ;;" \ + "mux1 %0 = %0, @rev ;;" \ + : "=r" (__v) \ + : "r" (__x)); \ + __v; })) +# define GUINT32_SWAP_LE_BE_IA64(val) \ + (G_GNUC_EXTENSION \ + ({ register guint32 __v, __x = ((guint32) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = GUINT32_SWAP_LE_BE_CONSTANT (__x); \ + else \ + __asm__ __volatile__ ("shl %0 = %1, 32 ;;" \ + "mux1 %0 = %0, @rev ;;" \ + : "=r" (__v) \ + : "r" (__x)); \ + __v; })) +# define GUINT64_SWAP_LE_BE_IA64(val) \ + (G_GNUC_EXTENSION \ + ({ register guint64 __v, __x = ((guint64) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = GUINT64_SWAP_LE_BE_CONSTANT (__x); \ + else \ + __asm__ __volatile__ ("mux1 %0 = %1, @rev ;;" \ + : "=r" (__v) \ + : "r" (__x)); \ + __v; })) +# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_IA64 (val)) +# ifndef GUINT32_SWAP_LE_BE +# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA64 (val)) +# endif +# ifndef GUINT64_SWAP_LE_BE +# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA64 (val)) +# endif +# elif defined (__x86_64__) +# define GUINT32_SWAP_LE_BE_X86_64(val) \ + (G_GNUC_EXTENSION \ + ({ register guint32 __v, __x = ((guint32) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = GUINT32_SWAP_LE_BE_CONSTANT (__x); \ + else \ + __asm__ ("bswapl %0" \ + : "=r" (__v) \ + : "0" (__x)); \ + __v; })) +# define GUINT64_SWAP_LE_BE_X86_64(val) \ + (G_GNUC_EXTENSION \ + ({ register guint64 __v, __x = ((guint64) (val)); \ + if (__builtin_constant_p (__x)) \ + __v = GUINT64_SWAP_LE_BE_CONSTANT (__x); \ + else \ + __asm__ ("bswapq %0" \ + : "=r" (__v) \ + : "0" (__x)); \ + __v; })) + /* gcc seems to figure out optimal code for this on its own */ +# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val)) +# ifndef GUINT32_SWAP_LE_BE +# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86_64 (val)) +# endif +# ifndef GUINT64_SWAP_LE_BE +# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86_64 (val)) +# endif +# else /* generic gcc */ +# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val)) +# ifndef GUINT32_SWAP_LE_BE +# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val)) +# endif +# ifndef GUINT64_SWAP_LE_BE +# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT (val)) +# endif +# endif +#else /* generic */ +# define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val)) +# define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val)) +# define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT (val)) +#endif /* generic */ + +#define GUINT16_SWAP_LE_PDP(val) ((guint16) (val)) +#define GUINT16_SWAP_BE_PDP(val) (GUINT16_SWAP_LE_BE (val)) +#define GUINT32_SWAP_LE_PDP(val) ((guint32) ( \ + (((guint32) (val) & (guint32) 0x0000ffffU) << 16) | \ + (((guint32) (val) & (guint32) 0xffff0000U) >> 16))) +#define GUINT32_SWAP_BE_PDP(val) ((guint32) ( \ + (((guint32) (val) & (guint32) 0x00ff00ffU) << 8) | \ + (((guint32) (val) & (guint32) 0xff00ff00U) >> 8))) + +/* The G*_TO_?E() macros are defined in glibconfig.h. + * The transformation is symmetric, so the FROM just maps to the TO. + */ +#define GINT16_FROM_LE(val) (GINT16_TO_LE (val)) +#define GUINT16_FROM_LE(val) (GUINT16_TO_LE (val)) +#define GINT16_FROM_BE(val) (GINT16_TO_BE (val)) +#define GUINT16_FROM_BE(val) (GUINT16_TO_BE (val)) +#define GINT32_FROM_LE(val) (GINT32_TO_LE (val)) +#define GUINT32_FROM_LE(val) (GUINT32_TO_LE (val)) +#define GINT32_FROM_BE(val) (GINT32_TO_BE (val)) +#define GUINT32_FROM_BE(val) (GUINT32_TO_BE (val)) + +#define GINT64_FROM_LE(val) (GINT64_TO_LE (val)) +#define GUINT64_FROM_LE(val) (GUINT64_TO_LE (val)) +#define GINT64_FROM_BE(val) (GINT64_TO_BE (val)) +#define GUINT64_FROM_BE(val) (GUINT64_TO_BE (val)) + +#define GLONG_FROM_LE(val) (GLONG_TO_LE (val)) +#define GULONG_FROM_LE(val) (GULONG_TO_LE (val)) +#define GLONG_FROM_BE(val) (GLONG_TO_BE (val)) +#define GULONG_FROM_BE(val) (GULONG_TO_BE (val)) + +#define GINT_FROM_LE(val) (GINT_TO_LE (val)) +#define GUINT_FROM_LE(val) (GUINT_TO_LE (val)) +#define GINT_FROM_BE(val) (GINT_TO_BE (val)) +#define GUINT_FROM_BE(val) (GUINT_TO_BE (val)) + +#define GSIZE_FROM_LE(val) (GSIZE_TO_LE (val)) +#define GSSIZE_FROM_LE(val) (GSSIZE_TO_LE (val)) +#define GSIZE_FROM_BE(val) (GSIZE_TO_BE (val)) +#define GSSIZE_FROM_BE(val) (GSSIZE_TO_BE (val)) + + +/* Portable versions of host-network order stuff + */ +#define g_ntohl(val) (GUINT32_FROM_BE (val)) +#define g_ntohs(val) (GUINT16_FROM_BE (val)) +#define g_htonl(val) (GUINT32_TO_BE (val)) +#define g_htons(val) (GUINT16_TO_BE (val)) + +/* IEEE Standard 754 Single Precision Storage Format (gfloat): + * + * 31 30 23 22 0 + * +--------+---------------+---------------+ + * | s 1bit | e[30:23] 8bit | f[22:0] 23bit | + * +--------+---------------+---------------+ + * B0------------------->B1------->B2-->B3--> + * + * IEEE Standard 754 Double Precision Storage Format (gdouble): + * + * 63 62 52 51 32 31 0 + * +--------+----------------+----------------+ +---------------+ + * | s 1bit | e[62:52] 11bit | f[51:32] 20bit | | f[31:0] 32bit | + * +--------+----------------+----------------+ +---------------+ + * B0--------------->B1---------->B2--->B3----> B4->B5->B6->B7-> + */ +/* subtract from biased_exponent to form base2 exponent (normal numbers) */ +typedef union _GDoubleIEEE754 GDoubleIEEE754; +typedef union _GFloatIEEE754 GFloatIEEE754; +#define G_IEEE754_FLOAT_BIAS (127) +#define G_IEEE754_DOUBLE_BIAS (1023) +/* multiply with base2 exponent to get base10 exponent (normal numbers) */ +#define G_LOG_2_BASE_10 (0.30102999566398119521) +#if G_BYTE_ORDER == G_LITTLE_ENDIAN +union _GFloatIEEE754 +{ + gfloat v_float; + struct { + guint mantissa : 23; + guint biased_exponent : 8; + guint sign : 1; + } mpn; +}; +union _GDoubleIEEE754 +{ + gdouble v_double; + struct { + guint mantissa_low : 32; + guint mantissa_high : 20; + guint biased_exponent : 11; + guint sign : 1; + } mpn; +}; +#elif G_BYTE_ORDER == G_BIG_ENDIAN +union _GFloatIEEE754 +{ + gfloat v_float; + struct { + guint sign : 1; + guint biased_exponent : 8; + guint mantissa : 23; + } mpn; +}; +union _GDoubleIEEE754 +{ + gdouble v_double; + struct { + guint sign : 1; + guint biased_exponent : 11; + guint mantissa_high : 20; + guint mantissa_low : 32; + } mpn; +}; +#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */ +#error unknown ENDIAN type +#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */ + +typedef struct _GTimeVal GTimeVal; + +struct _GTimeVal +{ + glong tv_sec; + glong tv_usec; +}; + +G_END_DECLS + +/* We prefix variable declarations so they can + * properly get exported in Windows DLLs. + */ +#ifndef GLIB_VAR +# ifdef G_PLATFORM_WIN32 +# ifdef GLIB_STATIC_COMPILATION +# define GLIB_VAR extern +# else /* !GLIB_STATIC_COMPILATION */ +# ifdef GLIB_COMPILATION +# ifdef DLL_EXPORT +# define GLIB_VAR __declspec(dllexport) +# else /* !DLL_EXPORT */ +# define GLIB_VAR extern +# endif /* !DLL_EXPORT */ +# else /* !GLIB_COMPILATION */ +# define GLIB_VAR extern __declspec(dllimport) +# endif /* !GLIB_COMPILATION */ +# endif /* !GLIB_STATIC_COMPILATION */ +# else /* !G_PLATFORM_WIN32 */ +# define GLIB_VAR extern +# endif /* !G_PLATFORM_WIN32 */ +#endif /* GLIB_VAR */ + +#endif /* __G_TYPES_H__ */ diff --git a/glib/glib/gunibreak.c b/glib/glib/gunibreak.c new file mode 100644 index 0000000..4b4f0e2 --- /dev/null +++ b/glib/glib/gunibreak.c @@ -0,0 +1,61 @@ +/* gunibreak.c - line break properties + * + * Copyright 2000 Red Hat, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include + +#include "gunibreak.h" + +#define TPROP_PART1(Page, Char) \ + ((break_property_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (break_property_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (break_property_data[break_property_table_part1[Page]][Char])) + +#define TPROP_PART2(Page, Char) \ + ((break_property_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (break_property_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (break_property_data[break_property_table_part2[Page]][Char])) + +#define PROP(Char) \ + (((Char) <= G_UNICODE_LAST_CHAR_PART1) \ + ? TPROP_PART1 ((Char) >> 8, (Char) & 0xff) \ + : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \ + ? TPROP_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \ + : G_UNICODE_BREAK_UNKNOWN)) + +/** + * g_unichar_break_type: + * @c: a Unicode character + * + * Determines the break type of @c. @c should be a Unicode character + * (to derive a character from UTF-8 encoded text, use + * g_utf8_get_char()). The break type is used to find word and line + * breaks ("text boundaries"), Pango implements the Unicode boundary + * resolution algorithms and normally you would use a function such + * as pango_break() instead of caring about break types yourself. + * + * Return value: the break type of @c + **/ +GUnicodeBreakType +g_unichar_break_type (gunichar c) +{ + return PROP (c); +} diff --git a/glib/glib/gunibreak.h b/glib/glib/gunibreak.h new file mode 100644 index 0000000..5f884e8 --- /dev/null +++ b/glib/glib/gunibreak.h @@ -0,0 +1,20548 @@ +/* This file is automatically generated. DO NOT EDIT! + Instead, edit gen-unicode-tables.pl and re-run. */ + +#ifndef BREAKTABLES_H +#define BREAKTABLES_H + +#include +#include + +#define G_UNICODE_DATA_VERSION "6.1.0" + +#define G_UNICODE_LAST_CHAR 0x10FFFF + +#define G_UNICODE_MAX_TABLE_INDEX 10000 + +/* the last code point that should be looked up in break_property_table_part1 */ +#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF + +static const gint8 break_property_data[][256] = { + { /* page 0, index 0 */ + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_LINE_FEED, G_UNICODE_BREAK_MANDATORY, + G_UNICODE_BREAK_MANDATORY, G_UNICODE_BREAK_CARRIAGE_RETURN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_SPACE, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PARANTHESIS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_HYPHEN, + G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_SYMBOL, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_INFIX_SEPARATOR, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_CLOSE_PARANTHESIS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_NEXT_LINE, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 2, index 1 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 3, index 2 */ + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 4, index 3 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 5, index 4 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_INFIX_SEPARATOR, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 6, index 5 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_INFIX_SEPARATOR, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 7, index 6 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 8, index 7 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 9, index 8 */ + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 10, index 9 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 11, index 10 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 12, index 11 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 13, index 12 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 14, index 13 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 15, index 14 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 16, index 15 */ + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 17, index 16 */ + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO + }, + { /* page 18, index 17 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 19, index 18 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 20, index 19 */ + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 22, index 20 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 23, index 21 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 24, index 22 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 25, index 23 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 26, index 24 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 27, index 25 */ + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 28, index 26 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 29, index 27 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK + }, + { /* page 31, index 28 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 32, index 29 */ + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ZERO_WIDTH_SPACE, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_BEFORE_AND_AFTER, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_INSEPARABLE, + G_UNICODE_BREAK_INSEPARABLE, G_UNICODE_BREAK_INSEPARABLE, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_MANDATORY, + G_UNICODE_BREAK_MANDATORY, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_INFIX_SEPARATOR, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_WORD_JOINER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 33, index 30 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 34, index 31 */ + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 35, index 32 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 36, index 33 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 37, index 34 */ + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 38, index 35 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS + }, + { /* page 39, index 36 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 41, index 37 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 43, index 38 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 44, index 39 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_AFTER + }, + { /* page 45, index 40 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK + }, + { /* page 46, index 41 */ + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_BEFORE_AND_AFTER, G_UNICODE_BREAK_BEFORE_AND_AFTER, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 47, index 42 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 48, index 43 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC + }, + { /* page 49, index 44 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER + }, + { /* page 50, index 45 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 77, index 46 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 160, index 47 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC + }, + { /* page 164, index 48 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER + }, + { /* page 166, index 49 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 167, index 50 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 168, index 51 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 169, index 52 */ + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 170, index 53 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 171, index 54 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 172, index 55 */ + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 173, index 56 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 174, index 57 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 175, index 58 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 176, index 59 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 177, index 60 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 178, index 61 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 179, index 62 */ + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 180, index 63 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 181, index 64 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 182, index 65 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 183, index 66 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 184, index 67 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 185, index 68 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 186, index 69 */ + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 187, index 70 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 188, index 71 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 189, index 72 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 190, index 73 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 191, index 74 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 192, index 75 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 193, index 76 */ + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 194, index 77 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 195, index 78 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 196, index 79 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 197, index 80 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 198, index 81 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 199, index 82 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 200, index 83 */ + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 201, index 84 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 202, index 85 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 203, index 86 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 204, index 87 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 205, index 88 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 206, index 89 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 207, index 90 */ + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 208, index 91 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 209, index 92 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 210, index 93 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 211, index 94 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 212, index 95 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 213, index 96 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 214, index 97 */ + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE + }, + { /* page 215, index 98 */ + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 251, index 99 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_HEBREW_LETTER, G_UNICODE_BREAK_HEBREW_LETTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 253, index 100 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 254, index 101 */ + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_INFIX_SEPARATOR, + G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_INSEPARABLE, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_WORD_JOINER + }, + { /* page 255, index 102 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_CONTINGENT, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 256, index 103 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 257, index 104 */ + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 258, index 105 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 259, index 106 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 260, index 107 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 264, index 108 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 265, index 109 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 266, index 110 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 267, index 111 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 268, index 112 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 270, index 113 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 272, index 114 */ + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 273, index 115 */ + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN + }, + { /* page 278, index 116 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 291, index 117 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 292, index 118 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 306, index 119 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 307, index 120 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 308, index 121 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 362, index 122 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 367, index 123 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 432, index 124 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 464, index 125 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 465, index 126 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 466, index 127 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 467, index 128 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 468, index 129 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 469, index 130 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 470, index 131 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 471, index 132 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC + }, + { /* page 494, index 133 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 496, index 134 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 497, index 135 */ + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 498, index 136 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 499, index 137 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 500, index 138 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 501, index 139 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC + }, + { /* page 502, index 140 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 503, index 141 */ + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 767, index 142 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 1023, index 143 */ + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 3584, index 144 */ + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + }, + { /* page 3585, index 145 */ + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN + } +}; + +/* U+0000 through U+2FAFF */ +static const gint16 break_property_table_part1[763] = { + 0 /* page 0 */, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 1 /* page 2 */, + 2 /* page 3 */, + 3 /* page 4 */, + 4 /* page 5 */, + 5 /* page 6 */, + 6 /* page 7 */, + 7 /* page 8 */, + 8 /* page 9 */, + 9 /* page 10 */, + 10 /* page 11 */, + 11 /* page 12 */, + 12 /* page 13 */, + 13 /* page 14 */, + 14 /* page 15 */, + 15 /* page 16 */, + 16 /* page 17 */, + 17 /* page 18 */, + 18 /* page 19 */, + 19 /* page 20 */, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 20 /* page 22 */, + 21 /* page 23 */, + 22 /* page 24 */, + 23 /* page 25 */, + 24 /* page 26 */, + 25 /* page 27 */, + 26 /* page 28 */, + 27 /* page 29 */, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 28 /* page 31 */, + 29 /* page 32 */, + 30 /* page 33 */, + 31 /* page 34 */, + 32 /* page 35 */, + 33 /* page 36 */, + 34 /* page 37 */, + 35 /* page 38 */, + 36 /* page 39 */, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 37 /* page 41 */, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 38 /* page 43 */, + 39 /* page 44 */, + 40 /* page 45 */, + 41 /* page 46 */, + 42 /* page 47 */, + 43 /* page 48 */, + 44 /* page 49 */, + 45 /* page 50 */, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + 46 /* page 77 */, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + 47 /* page 160 */, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + 48 /* page 164 */, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 49 /* page 166 */, + 50 /* page 167 */, + 51 /* page 168 */, + 52 /* page 169 */, + 53 /* page 170 */, + 54 /* page 171 */, + 55 /* page 172 */, + 56 /* page 173 */, + 57 /* page 174 */, + 58 /* page 175 */, + 59 /* page 176 */, + 60 /* page 177 */, + 61 /* page 178 */, + 62 /* page 179 */, + 63 /* page 180 */, + 64 /* page 181 */, + 65 /* page 182 */, + 66 /* page 183 */, + 67 /* page 184 */, + 68 /* page 185 */, + 69 /* page 186 */, + 70 /* page 187 */, + 71 /* page 188 */, + 72 /* page 189 */, + 73 /* page 190 */, + 74 /* page 191 */, + 75 /* page 192 */, + 76 /* page 193 */, + 77 /* page 194 */, + 78 /* page 195 */, + 79 /* page 196 */, + 80 /* page 197 */, + 81 /* page 198 */, + 82 /* page 199 */, + 83 /* page 200 */, + 84 /* page 201 */, + 85 /* page 202 */, + 86 /* page 203 */, + 87 /* page 204 */, + 88 /* page 205 */, + 89 /* page 206 */, + 90 /* page 207 */, + 91 /* page 208 */, + 92 /* page 209 */, + 93 /* page 210 */, + 94 /* page 211 */, + 95 /* page 212 */, + 96 /* page 213 */, + 97 /* page 214 */, + 98 /* page 215 */, + G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + 99 /* page 251 */, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 100 /* page 253 */, + 101 /* page 254 */, + 102 /* page 255 */, + 103 /* page 256 */, + 104 /* page 257 */, + 105 /* page 258 */, + 106 /* page 259 */, + 107 /* page 260 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 108 /* page 264 */, + 109 /* page 265 */, + 110 /* page 266 */, + 111 /* page 267 */, + 112 /* page 268 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 113 /* page 270 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 114 /* page 272 */, + 115 /* page 273 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 116 /* page 278 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 117 /* page 291 */, + 118 /* page 292 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 119 /* page 306 */, + 120 /* page 307 */, + 121 /* page 308 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX, + 122 /* page 362 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 123 /* page 367 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 124 /* page 432 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 125 /* page 464 */, + 126 /* page 465 */, + 127 /* page 466 */, + 128 /* page 467 */, + 129 /* page 468 */, + 130 /* page 469 */, + 131 /* page 470 */, + 132 /* page 471 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 133 /* page 494 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + 134 /* page 496 */, + 135 /* page 497 */, + 136 /* page 498 */, + 137 /* page 499 */, + 138 /* page 500 */, + 139 /* page 501 */, + 140 /* page 502 */, + 141 /* page 503 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX +}; + +/* U+E0000 through U+10FFFF */ +static const gint16 break_property_table_part2[768] = { + 144 /* page 3584 */, + 145 /* page 3585 */, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX +}; + +#endif /* BREAKTABLES_H */ diff --git a/glib/glib/gunichartables.h b/glib/glib/gunichartables.h new file mode 100644 index 0000000..f47d48d --- /dev/null +++ b/glib/glib/gunichartables.h @@ -0,0 +1,15148 @@ +/* This file is automatically generated. DO NOT EDIT! + Instead, edit gen-unicode-tables.pl and re-run. */ + +#ifndef CHARTABLES_H +#define CHARTABLES_H + +#define G_UNICODE_DATA_VERSION "6.1.0" + +#define G_UNICODE_LAST_CHAR 0x10ffff + +#define G_UNICODE_MAX_TABLE_INDEX 10000 + +#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF + +#define G_UNICODE_LAST_PAGE_PART1 762 + +static const char type_data[][256] = { + { /* page 0, index 0 */ + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, + G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_FORMAT, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_LETTER, + G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 1, index 1 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 2, index 2 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL + }, + { /* page 3, index 3 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER + }, + { /* page 4, index 4 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER + }, + { /* page 5, index 5 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 6, index 6 */ + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_FORMAT, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_LETTER + }, + { /* page 7, index 7 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 8, index 8 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED + }, + { /* page 9, index 9 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 10, index 10 */ + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 11, index 11 */ + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 12, index 12 */ + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 13, index 13 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 14, index 14 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 15, index 15 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 16, index 16 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER + }, + { /* page 18, index 17 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 19, index 18 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 20, index 19 */ + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER + }, + { /* page 22, index 20 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 23, index 21 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 24, index 22 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 25, index 23 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL + }, + { /* page 26, index 24 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 27, index 25 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION + }, + { /* page 28, index 26 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 29, index 27 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK + }, + { /* page 30, index 28 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER + }, + { /* page 31, index 29 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED + }, + { /* page 32, index 30 */ + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_LINE_SEPARATOR, G_UNICODE_PARAGRAPH_SEPARATOR, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_OTHER_NUMBER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 33, index 31 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL + }, + { /* page 35, index 32 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 36, index 33 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER + }, + { /* page 37, index 34 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL + }, + { /* page 38, index 35 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL + }, + { /* page 39, index 36 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL + }, + { /* page 41, index 37 */ + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL + }, + { /* page 43, index 38 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 44, index 39 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION + }, + { /* page 45, index 40 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK + }, + { /* page 46, index 41 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 47, index 42 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 48, index 43 */ + G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 49, index 44 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 50, index 45 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED + }, + { /* page 77, index 46 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL + }, + { /* page 159, index 47 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 160, index 48 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER + }, + { /* page 164, index 49 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION + }, + { /* page 166, index 50 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 167, index 51 */ + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 168, index 52 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 169, index 53 */ + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 170, index 54 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 171, index 55 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 215, index 56 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 250, index 57 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 251, index 58 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER + }, + { /* page 253, index 59 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 254, index 60 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_DASH_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT + }, + { /* page 255, index 61 */ + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 256, index 62 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 257, index 63 */ + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 258, index 64 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 259, index 65 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 260, index 66 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 264, index 67 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 265, index 68 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 266, index 69 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 267, index 70 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 268, index 71 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 270, index 72 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 272, index 73 */ + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_FORMAT, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 273, index 74 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 278, index 75 */ + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 291, index 76 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 292, index 77 */ + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, + G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 308, index 78 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 362, index 79 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 367, index 80 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 432, index 81 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 464, index 82 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 465, index 83 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, G_UNICODE_SPACING_MARK, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 466, index 84 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 467, index 85 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 468, index 86 */ + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 469, index 87 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 470, index 88 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER + }, + { /* page 471, index 89 */ + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_DECIMAL_NUMBER + }, + { /* page 494, index 90 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 496, index 91 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 497, index 92 */ + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, + G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL + }, + { /* page 498, index 93 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 499, index 94 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 500, index 95 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 501, index 96 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL + }, + { /* page 502, index 97 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 503, index 98 */ + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, + G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 678, index 99 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 695, index 100 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER + }, + { /* page 696, index 101 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 762, index 102 */ + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 3584, index 103 */ + G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED + }, + { /* page 3585, index 104 */ + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 4095, index 105 */ + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + }, + { /* page 4351, index 106 */ + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, + G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, + G_UNICODE_UNASSIGNED + } +}; + +/* U+0000 through U+2FAFF */ +static const gint16 type_table_part1[763] = { + 0 /* page 0 */, + 1 /* page 1 */, + 2 /* page 2 */, + 3 /* page 3 */, + 4 /* page 4 */, + 5 /* page 5 */, + 6 /* page 6 */, + 7 /* page 7 */, + 8 /* page 8 */, + 9 /* page 9 */, + 10 /* page 10 */, + 11 /* page 11 */, + 12 /* page 12 */, + 13 /* page 13 */, + 14 /* page 14 */, + 15 /* page 15 */, + 16 /* page 16 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 17 /* page 18 */, + 18 /* page 19 */, + 19 /* page 20 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 20 /* page 22 */, + 21 /* page 23 */, + 22 /* page 24 */, + 23 /* page 25 */, + 24 /* page 26 */, + 25 /* page 27 */, + 26 /* page 28 */, + 27 /* page 29 */, + 28 /* page 30 */, + 29 /* page 31 */, + 30 /* page 32 */, + 31 /* page 33 */, + G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 32 /* page 35 */, + 33 /* page 36 */, + 34 /* page 37 */, + 35 /* page 38 */, + 36 /* page 39 */, + G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 37 /* page 41 */, + G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + 38 /* page 43 */, + 39 /* page 44 */, + 40 /* page 45 */, + 41 /* page 46 */, + 42 /* page 47 */, + 43 /* page 48 */, + 44 /* page 49 */, + 45 /* page 50 */, + G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 46 /* page 77 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 47 /* page 159 */, + 48 /* page 160 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 49 /* page 164 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 50 /* page 166 */, + 51 /* page 167 */, + 52 /* page 168 */, + 53 /* page 169 */, + 54 /* page 170 */, + 55 /* page 171 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 56 /* page 215 */, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 57 /* page 250 */, + 58 /* page 251 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 59 /* page 253 */, + 60 /* page 254 */, + 61 /* page 255 */, + 62 /* page 256 */, + 63 /* page 257 */, + 64 /* page 258 */, + 65 /* page 259 */, + 66 /* page 260 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 67 /* page 264 */, + 68 /* page 265 */, + 69 /* page 266 */, + 70 /* page 267 */, + 71 /* page 268 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 72 /* page 270 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 73 /* page 272 */, + 74 /* page 273 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 75 /* page 278 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 76 /* page 291 */, + 77 /* page 292 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 78 /* page 308 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 79 /* page 362 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 80 /* page 367 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 81 /* page 432 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 82 /* page 464 */, + 83 /* page 465 */, + 84 /* page 466 */, + 85 /* page 467 */, + 86 /* page 468 */, + 87 /* page 469 */, + 88 /* page 470 */, + 89 /* page 471 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 90 /* page 494 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + 91 /* page 496 */, + 92 /* page 497 */, + 93 /* page 498 */, + 94 /* page 499 */, + 95 /* page 500 */, + 96 /* page 501 */, + 97 /* page 502 */, + 98 /* page 503 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 99 /* page 678 */, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 100 /* page 695 */, + 101 /* page 696 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX, + 102 /* page 762 */ +}; + +/* U+E0000 through U+10FFFF */ +static const gint16 type_table_part2[768] = { + 103 /* page 3584 */, + 104 /* page 3585 */, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + 105 /* page 4095 */, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX, + 106 /* page 4351 */ +}; + +static const gunichar attr_data[][256] = { + { /* page 0, index 0 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x0070, + 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078, 0x0079, + 0x007a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0041, 0x0042, + 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, 0x0049, 0x004a, 0x004b, + 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, + 0x0055, 0x0056, 0x0057, 0x0058, 0x0059, 0x005a, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x039c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, + 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0000, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x1000000, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, + 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, + 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0000, 0x00d8, 0x00d9, 0x00da, + 0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178 + }, + { /* page 1, index 1 */ + 0x0101, 0x0100, 0x0103, 0x0102, 0x0105, 0x0104, 0x0107, 0x0106, 0x0109, + 0x0108, 0x010b, 0x010a, 0x010d, 0x010c, 0x010f, 0x010e, 0x0111, 0x0110, + 0x0113, 0x0112, 0x0115, 0x0114, 0x0117, 0x0116, 0x0119, 0x0118, 0x011b, + 0x011a, 0x011d, 0x011c, 0x011f, 0x011e, 0x0121, 0x0120, 0x0123, 0x0122, + 0x0125, 0x0124, 0x0127, 0x0126, 0x0129, 0x0128, 0x012b, 0x012a, 0x012d, + 0x012c, 0x012f, 0x012e, 0x1000007, 0x0049, 0x0133, 0x0132, 0x0135, + 0x0134, 0x0137, 0x0136, 0x0000, 0x013a, 0x0139, 0x013c, 0x013b, 0x013e, + 0x013d, 0x0140, 0x013f, 0x0142, 0x0141, 0x0144, 0x0143, 0x0146, 0x0145, + 0x0148, 0x0147, 0x1000086, 0x014b, 0x014a, 0x014d, 0x014c, 0x014f, + 0x014e, 0x0151, 0x0150, 0x0153, 0x0152, 0x0155, 0x0154, 0x0157, 0x0156, + 0x0159, 0x0158, 0x015b, 0x015a, 0x015d, 0x015c, 0x015f, 0x015e, 0x0161, + 0x0160, 0x0163, 0x0162, 0x0165, 0x0164, 0x0167, 0x0166, 0x0169, 0x0168, + 0x016b, 0x016a, 0x016d, 0x016c, 0x016f, 0x016e, 0x0171, 0x0170, 0x0173, + 0x0172, 0x0175, 0x0174, 0x0177, 0x0176, 0x00ff, 0x017a, 0x0179, 0x017c, + 0x017b, 0x017e, 0x017d, 0x0053, 0x0243, 0x0253, 0x0183, 0x0182, 0x0185, + 0x0184, 0x0254, 0x0188, 0x0187, 0x0256, 0x0257, 0x018c, 0x018b, 0x0000, + 0x01dd, 0x0259, 0x025b, 0x0192, 0x0191, 0x0260, 0x0263, 0x01f6, 0x0269, + 0x0268, 0x0199, 0x0198, 0x023d, 0x0000, 0x026f, 0x0272, 0x0220, 0x0275, + 0x01a1, 0x01a0, 0x01a3, 0x01a2, 0x01a5, 0x01a4, 0x0280, 0x01a8, 0x01a7, + 0x0283, 0x0000, 0x0000, 0x01ad, 0x01ac, 0x0288, 0x01b0, 0x01af, 0x028a, + 0x028b, 0x01b4, 0x01b3, 0x01b6, 0x01b5, 0x0292, 0x01b9, 0x01b8, 0x0000, + 0x0000, 0x01bd, 0x01bc, 0x0000, 0x01f7, 0x0000, 0x0000, 0x0000, 0x0000, + 0x01c6, 0x0000, 0x01c4, 0x01c9, 0x0000, 0x01c7, 0x01cc, 0x0000, 0x01ca, + 0x01ce, 0x01cd, 0x01d0, 0x01cf, 0x01d2, 0x01d1, 0x01d4, 0x01d3, 0x01d6, + 0x01d5, 0x01d8, 0x01d7, 0x01da, 0x01d9, 0x01dc, 0x01db, 0x018e, 0x01df, + 0x01de, 0x01e1, 0x01e0, 0x01e3, 0x01e2, 0x01e5, 0x01e4, 0x01e7, 0x01e6, + 0x01e9, 0x01e8, 0x01eb, 0x01ea, 0x01ed, 0x01ec, 0x01ef, 0x01ee, + 0x10000ad, 0x01f3, 0x0000, 0x01f1, 0x01f5, 0x01f4, 0x0195, 0x01bf, + 0x01f9, 0x01f8, 0x01fb, 0x01fa, 0x01fd, 0x01fc, 0x01ff, 0x01fe + }, + { /* page 2, index 2 */ + 0x0201, 0x0200, 0x0203, 0x0202, 0x0205, 0x0204, 0x0207, 0x0206, 0x0209, + 0x0208, 0x020b, 0x020a, 0x020d, 0x020c, 0x020f, 0x020e, 0x0211, 0x0210, + 0x0213, 0x0212, 0x0215, 0x0214, 0x0217, 0x0216, 0x0219, 0x0218, 0x021b, + 0x021a, 0x021d, 0x021c, 0x021f, 0x021e, 0x019e, 0x0000, 0x0223, 0x0222, + 0x0225, 0x0224, 0x0227, 0x0226, 0x0229, 0x0228, 0x022b, 0x022a, 0x022d, + 0x022c, 0x022f, 0x022e, 0x0231, 0x0230, 0x0233, 0x0232, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x2c65, 0x023c, 0x023b, 0x019a, 0x2c66, + 0x2c7e, 0x2c7f, 0x0242, 0x0241, 0x0180, 0x0289, 0x028c, 0x0247, 0x0246, + 0x0249, 0x0248, 0x024b, 0x024a, 0x024d, 0x024c, 0x024f, 0x024e, 0x2c6f, + 0x2c6d, 0x2c70, 0x0181, 0x0186, 0x0000, 0x0189, 0x018a, 0x0000, 0x018f, + 0x0000, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0193, 0x0000, 0x0000, + 0x0194, 0x0000, 0xa78d, 0xa7aa, 0x0000, 0x0197, 0x0196, 0x0000, 0x2c62, + 0x0000, 0x0000, 0x0000, 0x019c, 0x0000, 0x2c6e, 0x019d, 0x0000, 0x0000, + 0x019f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2c64, + 0x0000, 0x0000, 0x01a6, 0x0000, 0x0000, 0x01a9, 0x0000, 0x0000, 0x0000, + 0x0000, 0x01ae, 0x0244, 0x01b1, 0x01b2, 0x0245, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x01b7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 3, index 3 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0371, 0x0370, 0x0373, 0x0372, 0x0000, + 0x0000, 0x0377, 0x0376, 0x0000, 0x0000, 0x0000, 0x03fd, 0x03fe, 0x03ff, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03ac, + 0x0000, 0x03ad, 0x03ae, 0x03af, 0x0000, 0x03cc, 0x0000, 0x03cd, 0x03ce, + 0x100008f, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x0000, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0x03ca, 0x03cb, 0x0386, 0x0388, 0x0389, 0x038a, 0x100009e, 0x0391, + 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, + 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x038c, + 0x038e, 0x038f, 0x03d7, 0x0392, 0x0398, 0x0000, 0x0000, 0x0000, 0x03a6, + 0x03a0, 0x03cf, 0x03d9, 0x03d8, 0x03db, 0x03da, 0x03dd, 0x03dc, 0x03df, + 0x03de, 0x03e1, 0x03e0, 0x03e3, 0x03e2, 0x03e5, 0x03e4, 0x03e7, 0x03e6, + 0x03e9, 0x03e8, 0x03eb, 0x03ea, 0x03ed, 0x03ec, 0x03ef, 0x03ee, 0x039a, + 0x03a1, 0x03f9, 0x0000, 0x03b8, 0x0395, 0x0000, 0x03f8, 0x03f7, 0x03f2, + 0x03fb, 0x03fa, 0x0000, 0x037b, 0x037c, 0x037d + }, + { /* page 4, index 4 */ + 0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 0x045e, 0x045f, 0x0430, 0x0431, + 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, 0x0438, 0x0439, 0x043a, + 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, + 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, + 0x044d, 0x044e, 0x044f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, + 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0400, + 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, + 0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, 0x0461, 0x0460, 0x0463, + 0x0462, 0x0465, 0x0464, 0x0467, 0x0466, 0x0469, 0x0468, 0x046b, 0x046a, + 0x046d, 0x046c, 0x046f, 0x046e, 0x0471, 0x0470, 0x0473, 0x0472, 0x0475, + 0x0474, 0x0477, 0x0476, 0x0479, 0x0478, 0x047b, 0x047a, 0x047d, 0x047c, + 0x047f, 0x047e, 0x0481, 0x0480, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x048b, 0x048a, 0x048d, 0x048c, 0x048f, 0x048e, + 0x0491, 0x0490, 0x0493, 0x0492, 0x0495, 0x0494, 0x0497, 0x0496, 0x0499, + 0x0498, 0x049b, 0x049a, 0x049d, 0x049c, 0x049f, 0x049e, 0x04a1, 0x04a0, + 0x04a3, 0x04a2, 0x04a5, 0x04a4, 0x04a7, 0x04a6, 0x04a9, 0x04a8, 0x04ab, + 0x04aa, 0x04ad, 0x04ac, 0x04af, 0x04ae, 0x04b1, 0x04b0, 0x04b3, 0x04b2, + 0x04b5, 0x04b4, 0x04b7, 0x04b6, 0x04b9, 0x04b8, 0x04bb, 0x04ba, 0x04bd, + 0x04bc, 0x04bf, 0x04be, 0x04cf, 0x04c2, 0x04c1, 0x04c4, 0x04c3, 0x04c6, + 0x04c5, 0x04c8, 0x04c7, 0x04ca, 0x04c9, 0x04cc, 0x04cb, 0x04ce, 0x04cd, + 0x04c0, 0x04d1, 0x04d0, 0x04d3, 0x04d2, 0x04d5, 0x04d4, 0x04d7, 0x04d6, + 0x04d9, 0x04d8, 0x04db, 0x04da, 0x04dd, 0x04dc, 0x04df, 0x04de, 0x04e1, + 0x04e0, 0x04e3, 0x04e2, 0x04e5, 0x04e4, 0x04e7, 0x04e6, 0x04e9, 0x04e8, + 0x04eb, 0x04ea, 0x04ed, 0x04ec, 0x04ef, 0x04ee, 0x04f1, 0x04f0, 0x04f3, + 0x04f2, 0x04f5, 0x04f4, 0x04f7, 0x04f6, 0x04f9, 0x04f8, 0x04fb, 0x04fa, + 0x04fd, 0x04fc, 0x04ff, 0x04fe + }, + { /* page 5, index 5 */ + 0x0501, 0x0500, 0x0503, 0x0502, 0x0505, 0x0504, 0x0507, 0x0506, 0x0509, + 0x0508, 0x050b, 0x050a, 0x050d, 0x050c, 0x050f, 0x050e, 0x0511, 0x0510, + 0x0513, 0x0512, 0x0515, 0x0514, 0x0517, 0x0516, 0x0519, 0x0518, 0x051b, + 0x051a, 0x051d, 0x051c, 0x051f, 0x051e, 0x0521, 0x0520, 0x0523, 0x0522, + 0x0525, 0x0524, 0x0527, 0x0526, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0561, 0x0562, 0x0563, 0x0564, 0x0565, + 0x0566, 0x0567, 0x0568, 0x0569, 0x056a, 0x056b, 0x056c, 0x056d, 0x056e, + 0x056f, 0x0570, 0x0571, 0x0572, 0x0573, 0x0574, 0x0575, 0x0576, 0x0577, + 0x0578, 0x0579, 0x057a, 0x057b, 0x057c, 0x057d, 0x057e, 0x057f, 0x0580, + 0x0581, 0x0582, 0x0583, 0x0584, 0x0585, 0x0586, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0531, 0x0532, + 0x0533, 0x0534, 0x0535, 0x0536, 0x0537, 0x0538, 0x0539, 0x053a, 0x053b, + 0x053c, 0x053d, 0x053e, 0x053f, 0x0540, 0x0541, 0x0542, 0x0543, 0x0544, + 0x0545, 0x0546, 0x0547, 0x0548, 0x0549, 0x054a, 0x054b, 0x054c, 0x054d, + 0x054e, 0x054f, 0x0550, 0x0551, 0x0552, 0x0553, 0x0554, 0x0555, 0x0556, + 0x1000044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 6, index 6 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 7, index 7 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 9, index 8 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 10, index 9 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 11, index 10 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 12, index 11 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 13, index 12 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 14, index 13 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 15, index 14 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 16, index 15 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d00, 0x2d01, + 0x2d02, 0x2d03, 0x2d04, 0x2d05, 0x2d06, 0x2d07, 0x2d08, 0x2d09, 0x2d0a, + 0x2d0b, 0x2d0c, 0x2d0d, 0x2d0e, 0x2d0f, 0x2d10, 0x2d11, 0x2d12, 0x2d13, + 0x2d14, 0x2d15, 0x2d16, 0x2d17, 0x2d18, 0x2d19, 0x2d1a, 0x2d1b, 0x2d1c, + 0x2d1d, 0x2d1e, 0x2d1f, 0x2d20, 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, + 0x0000, 0x2d27, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2d2d, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 23, index 16 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 24, index 17 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 25, index 18 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 26, index 19 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, + 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 27, index 20 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 28, index 21 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 29, index 22 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xa77d, 0x0000, 0x0000, 0x0000, 0x2c63, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 30, index 23 */ + 0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06, 0x1e09, + 0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e, 0x1e11, 0x1e10, + 0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16, 0x1e19, 0x1e18, 0x1e1b, + 0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e, 0x1e21, 0x1e20, 0x1e23, 0x1e22, + 0x1e25, 0x1e24, 0x1e27, 0x1e26, 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, + 0x1e2c, 0x1e2f, 0x1e2e, 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, + 0x1e37, 0x1e36, 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, + 0x1e3e, 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46, + 0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e, 0x1e51, + 0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56, 0x1e59, 0x1e58, + 0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e, 0x1e61, 0x1e60, 0x1e63, + 0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66, 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, + 0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e, 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, + 0x1e74, 0x1e77, 0x1e76, 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, + 0x1e7f, 0x1e7e, 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, + 0x1e86, 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e, + 0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0x10000b6, 0x10000bf, + 0x10000c8, 0x10000d1, 0x10000da, 0x1e60, 0x0000, 0x0000, 0x00df, 0x0000, + 0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6, 0x1ea9, + 0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae, 0x1eb1, 0x1eb0, + 0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6, 0x1eb9, 0x1eb8, 0x1ebb, + 0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe, 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, + 0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6, 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, + 0x1ecc, 0x1ecf, 0x1ece, 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, + 0x1ed7, 0x1ed6, 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, + 0x1ede, 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6, + 0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee, 0x1ef1, + 0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6, 0x1ef9, 0x1ef8, + 0x1efb, 0x1efa, 0x1efd, 0x1efc, 0x1eff, 0x1efe + }, + { /* page 31, index 24 */ + 0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f00, + 0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f18, 0x1f19, + 0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x0000, 0x0000, 0x1f10, 0x1f11, 0x1f12, + 0x1f13, 0x1f14, 0x1f15, 0x0000, 0x0000, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, + 0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, + 0x1f25, 0x1f26, 0x1f27, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, + 0x1f3e, 0x1f3f, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, + 0x1f37, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x0000, 0x0000, + 0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x0000, 0x0000, + 0x10000e3, 0x1f59, 0x10000ee, 0x1f5b, 0x10000fd, 0x1f5d, 0x100010c, + 0x1f5f, 0x0000, 0x1f51, 0x0000, 0x1f53, 0x0000, 0x1f55, 0x0000, 0x1f57, + 0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1f60, + 0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1fba, 0x1fbb, + 0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, + 0x1feb, 0x1ffa, 0x1ffb, 0x0000, 0x0000, 0x10001b7, 0x10001c4, 0x10001d1, + 0x10001de, 0x10001eb, 0x10001f8, 0x1000205, 0x1000212, 0x100021f, + 0x1000229, 0x1000233, 0x100023d, 0x1000247, 0x1000251, 0x100025b, + 0x1000265, 0x100026f, 0x100027c, 0x1000289, 0x1000296, 0x10002a3, + 0x10002b0, 0x10002bd, 0x10002ca, 0x10002d7, 0x10002e1, 0x10002eb, + 0x10002f5, 0x10002ff, 0x1000309, 0x1000313, 0x100031d, 0x1000327, + 0x1000334, 0x1000341, 0x100034e, 0x100035b, 0x1000368, 0x1000375, + 0x1000382, 0x100038f, 0x1000399, 0x10003a3, 0x10003ad, 0x10003b7, + 0x10003c1, 0x10003cb, 0x10003d5, 0x1fb8, 0x1fb9, 0x100041e, 0x10003df, + 0x100042b, 0x0000, 0x100011b, 0x1000466, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, + 0x10003eb, 0x0000, 0x0399, 0x0000, 0x0000, 0x0000, 0x1000436, 0x10003f4, + 0x1000443, 0x0000, 0x1000126, 0x1000475, 0x1f72, 0x1f73, 0x1f74, 0x1f75, + 0x1000400, 0x0000, 0x0000, 0x0000, 0x1fd8, 0x1fd9, 0x1000131, 0x1000140, + 0x0000, 0x0000, 0x100014f, 0x100015a, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, + 0x0000, 0x0000, 0x0000, 0x0000, 0x1fe8, 0x1fe9, 0x1000169, 0x1000178, + 0x1000187, 0x1fec, 0x1000192, 0x100019d, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, + 0x1fe5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100044e, 0x1000409, + 0x100045b, 0x0000, 0x10001ac, 0x1000484, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, + 0x1000415, 0x0000, 0x0000, 0x0000 + }, + { /* page 33, index 25 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x03c9, 0x0000, 0x0000, 0x0000, 0x006b, 0x00e5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x214e, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2132, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2184, 0x2183, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 44, index 26 */ + 0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37, 0x2c38, + 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f, 0x2c40, 0x2c41, + 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 0x2c48, 0x2c49, 0x2c4a, + 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 0x2c50, 0x2c51, 0x2c52, 0x2c53, + 0x2c54, 0x2c55, 0x2c56, 0x2c57, 0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, + 0x2c5d, 0x2c5e, 0x0000, 0x2c00, 0x2c01, 0x2c02, 0x2c03, 0x2c04, 0x2c05, + 0x2c06, 0x2c07, 0x2c08, 0x2c09, 0x2c0a, 0x2c0b, 0x2c0c, 0x2c0d, 0x2c0e, + 0x2c0f, 0x2c10, 0x2c11, 0x2c12, 0x2c13, 0x2c14, 0x2c15, 0x2c16, 0x2c17, + 0x2c18, 0x2c19, 0x2c1a, 0x2c1b, 0x2c1c, 0x2c1d, 0x2c1e, 0x2c1f, 0x2c20, + 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c27, 0x2c28, 0x2c29, + 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x0000, 0x2c61, 0x2c60, 0x026b, + 0x1d7d, 0x027d, 0x023a, 0x023e, 0x2c68, 0x2c67, 0x2c6a, 0x2c69, 0x2c6c, + 0x2c6b, 0x0251, 0x0271, 0x0250, 0x0252, 0x0000, 0x2c73, 0x2c72, 0x0000, + 0x2c76, 0x2c75, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x023f, 0x0240, 0x2c81, 0x2c80, 0x2c83, 0x2c82, 0x2c85, 0x2c84, 0x2c87, + 0x2c86, 0x2c89, 0x2c88, 0x2c8b, 0x2c8a, 0x2c8d, 0x2c8c, 0x2c8f, 0x2c8e, + 0x2c91, 0x2c90, 0x2c93, 0x2c92, 0x2c95, 0x2c94, 0x2c97, 0x2c96, 0x2c99, + 0x2c98, 0x2c9b, 0x2c9a, 0x2c9d, 0x2c9c, 0x2c9f, 0x2c9e, 0x2ca1, 0x2ca0, + 0x2ca3, 0x2ca2, 0x2ca5, 0x2ca4, 0x2ca7, 0x2ca6, 0x2ca9, 0x2ca8, 0x2cab, + 0x2caa, 0x2cad, 0x2cac, 0x2caf, 0x2cae, 0x2cb1, 0x2cb0, 0x2cb3, 0x2cb2, + 0x2cb5, 0x2cb4, 0x2cb7, 0x2cb6, 0x2cb9, 0x2cb8, 0x2cbb, 0x2cba, 0x2cbd, + 0x2cbc, 0x2cbf, 0x2cbe, 0x2cc1, 0x2cc0, 0x2cc3, 0x2cc2, 0x2cc5, 0x2cc4, + 0x2cc7, 0x2cc6, 0x2cc9, 0x2cc8, 0x2ccb, 0x2cca, 0x2ccd, 0x2ccc, 0x2ccf, + 0x2cce, 0x2cd1, 0x2cd0, 0x2cd3, 0x2cd2, 0x2cd5, 0x2cd4, 0x2cd7, 0x2cd6, + 0x2cd9, 0x2cd8, 0x2cdb, 0x2cda, 0x2cdd, 0x2cdc, 0x2cdf, 0x2cde, 0x2ce1, + 0x2ce0, 0x2ce3, 0x2ce2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2cec, 0x2ceb, 0x2cee, 0x2ced, 0x0000, 0x0000, 0x0000, 0x2cf3, + 0x2cf2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 45, index 27 */ + 0x10a0, 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8, + 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0, 0x10b1, + 0x10b2, 0x10b3, 0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8, 0x10b9, 0x10ba, + 0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf, 0x10c0, 0x10c1, 0x10c2, 0x10c3, + 0x10c4, 0x10c5, 0x0000, 0x10c7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x10cd, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 166, index 28 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, + 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0xa641, 0xa640, 0xa643, 0xa642, 0xa645, 0xa644, 0xa647, 0xa646, + 0xa649, 0xa648, 0xa64b, 0xa64a, 0xa64d, 0xa64c, 0xa64f, 0xa64e, 0xa651, + 0xa650, 0xa653, 0xa652, 0xa655, 0xa654, 0xa657, 0xa656, 0xa659, 0xa658, + 0xa65b, 0xa65a, 0xa65d, 0xa65c, 0xa65f, 0xa65e, 0xa661, 0xa660, 0xa663, + 0xa662, 0xa665, 0xa664, 0xa667, 0xa666, 0xa669, 0xa668, 0xa66b, 0xa66a, + 0xa66d, 0xa66c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xa681, 0xa680, 0xa683, 0xa682, 0xa685, 0xa684, 0xa687, + 0xa686, 0xa689, 0xa688, 0xa68b, 0xa68a, 0xa68d, 0xa68c, 0xa68f, 0xa68e, + 0xa691, 0xa690, 0xa693, 0xa692, 0xa695, 0xa694, 0xa697, 0xa696, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 167, index 29 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa723, 0xa722, + 0xa725, 0xa724, 0xa727, 0xa726, 0xa729, 0xa728, 0xa72b, 0xa72a, 0xa72d, + 0xa72c, 0xa72f, 0xa72e, 0x0000, 0x0000, 0xa733, 0xa732, 0xa735, 0xa734, + 0xa737, 0xa736, 0xa739, 0xa738, 0xa73b, 0xa73a, 0xa73d, 0xa73c, 0xa73f, + 0xa73e, 0xa741, 0xa740, 0xa743, 0xa742, 0xa745, 0xa744, 0xa747, 0xa746, + 0xa749, 0xa748, 0xa74b, 0xa74a, 0xa74d, 0xa74c, 0xa74f, 0xa74e, 0xa751, + 0xa750, 0xa753, 0xa752, 0xa755, 0xa754, 0xa757, 0xa756, 0xa759, 0xa758, + 0xa75b, 0xa75a, 0xa75d, 0xa75c, 0xa75f, 0xa75e, 0xa761, 0xa760, 0xa763, + 0xa762, 0xa765, 0xa764, 0xa767, 0xa766, 0xa769, 0xa768, 0xa76b, 0xa76a, + 0xa76d, 0xa76c, 0xa76f, 0xa76e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0xa77a, 0xa779, 0xa77c, 0xa77b, 0x1d79, + 0xa77f, 0xa77e, 0xa781, 0xa780, 0xa783, 0xa782, 0xa785, 0xa784, 0xa787, + 0xa786, 0x0000, 0x0000, 0x0000, 0xa78c, 0xa78b, 0x0265, 0x0000, 0x0000, + 0xa791, 0xa790, 0xa793, 0xa792, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa7a1, 0xa7a0, + 0xa7a3, 0xa7a2, 0xa7a5, 0xa7a4, 0xa7a7, 0xa7a6, 0xa7a9, 0xa7a8, 0x0266, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 168, index 30 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 169, index 31 */ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 170, index 32 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 171, index 33 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 251, index 34 */ + 0x100000f, 0x1000016, 0x100001d, 0x1000024, 0x100002d, 0x1000036, + 0x100003d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100004f, 0x100005a, 0x1000065, + 0x1000070, 0x100007b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000 + }, + { /* page 255, index 35 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, + 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xff41, 0xff42, 0xff43, + 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, + 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, + 0xff56, 0xff57, 0xff58, 0xff59, 0xff5a, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, + 0xff28, 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, + 0xff3a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 260, index 36 */ + 0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f, + 0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, + 0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, + 0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, + 0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f, + 0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407, + 0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, + 0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, + 0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, + 0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 272, index 37 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 273, index 38 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 278, index 39 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000 + }, + { /* page 471, index 40 */ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, + 0x0007, 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, + 0x0006, 0x0007, 0x0008, 0x0009 + } +}; + +/* U+0000 through U+2FAFF */ +static const gint16 attr_table_part1[763] = { + 0 /* page 0 */, + 1 /* page 1 */, + 2 /* page 2 */, + 3 /* page 3 */, + 4 /* page 4 */, + 5 /* page 5 */, + 6 /* page 6 */, + 7 /* page 7 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 8 /* page 9 */, + 9 /* page 10 */, + 10 /* page 11 */, + 11 /* page 12 */, + 12 /* page 13 */, + 13 /* page 14 */, + 14 /* page 15 */, + 15 /* page 16 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 16 /* page 23 */, + 17 /* page 24 */, + 18 /* page 25 */, + 19 /* page 26 */, + 20 /* page 27 */, + 21 /* page 28 */, + 22 /* page 29 */, + 23 /* page 30 */, + 24 /* page 31 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 25 /* page 33 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 26 /* page 44 */, + 27 /* page 45 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 28 /* page 166 */, + 29 /* page 167 */, + 30 /* page 168 */, + 31 /* page 169 */, + 32 /* page 170 */, + 33 /* page 171 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 34 /* page 251 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 35 /* page 255 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 36 /* page 260 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 37 /* page 272 */, + 38 /* page 273 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 39 /* page 278 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 40 /* page 471 */, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX +}; + +/* U+E0000 through U+10FFFF */ +static const gint16 attr_table_part2[768] = { + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX, + 0x0000 + G_UNICODE_MAX_TABLE_INDEX +}; + +static const gunichar title_table[][3] = { + { 0x01c5, 0x01c4, 0x01c6 }, + { 0x01c8, 0x01c7, 0x01c9 }, + { 0x01cb, 0x01ca, 0x01cc }, + { 0x01f2, 0x01f1, 0x01f3 }, + { 0x1f88, 0x0000, 0x1f80 }, + { 0x1f89, 0x0000, 0x1f81 }, + { 0x1f8a, 0x0000, 0x1f82 }, + { 0x1f8b, 0x0000, 0x1f83 }, + { 0x1f8c, 0x0000, 0x1f84 }, + { 0x1f8d, 0x0000, 0x1f85 }, + { 0x1f8e, 0x0000, 0x1f86 }, + { 0x1f8f, 0x0000, 0x1f87 }, + { 0x1f98, 0x0000, 0x1f90 }, + { 0x1f99, 0x0000, 0x1f91 }, + { 0x1f9a, 0x0000, 0x1f92 }, + { 0x1f9b, 0x0000, 0x1f93 }, + { 0x1f9c, 0x0000, 0x1f94 }, + { 0x1f9d, 0x0000, 0x1f95 }, + { 0x1f9e, 0x0000, 0x1f96 }, + { 0x1f9f, 0x0000, 0x1f97 }, + { 0x1fa8, 0x0000, 0x1fa0 }, + { 0x1fa9, 0x0000, 0x1fa1 }, + { 0x1faa, 0x0000, 0x1fa2 }, + { 0x1fab, 0x0000, 0x1fa3 }, + { 0x1fac, 0x0000, 0x1fa4 }, + { 0x1fad, 0x0000, 0x1fa5 }, + { 0x1fae, 0x0000, 0x1fa6 }, + { 0x1faf, 0x0000, 0x1fa7 }, + { 0x1fbc, 0x0000, 0x1fb3 }, + { 0x1fcc, 0x0000, 0x1fc3 }, + { 0x1ffc, 0x0000, 0x1ff3 } +}; + + +/* Table of special cases for case conversion; each record contains + * First, the best single character mapping to lowercase if Lu, + * and to uppercase if Ll, followed by the output mapping for the two cases + * other than the case of the codepoint, in the order [Ll],[Lu],[Lt], + * encoded in UTF-8, separated and terminated by a null character. + */ +static const gchar special_case_table[] = { + "\x00\x53\x53\x00\x53\x73\0" /* offset 0 */ + "\x69\x69\xcc\x87\x00\xc4\xb0\0" /* offset 7 */ + "\x00\x46\x46\x00\x46\x66\0" /* offset 15 */ + "\x00\x46\x49\x00\x46\x69\0" /* offset 22 */ + "\x00\x46\x4c\x00\x46\x6c\0" /* offset 29 */ + "\x00\x46\x46\x49\x00\x46\x66\x69\0" /* offset 36 */ + "\x00\x46\x46\x4c\x00\x46\x66\x6c\0" /* offset 45 */ + "\x00\x53\x54\x00\x53\x74\0" /* offset 54 */ + "\x00\x53\x54\x00\x53\x74\0" /* offset 61 */ + "\x00\xd4\xb5\xd5\x92\x00\xd4\xb5\xd6\x82\0" /* offset 68 */ + "\x00\xd5\x84\xd5\x86\x00\xd5\x84\xd5\xb6\0" /* offset 79 */ + "\x00\xd5\x84\xd4\xb5\x00\xd5\x84\xd5\xa5\0" /* offset 90 */ + "\x00\xd5\x84\xd4\xbb\x00\xd5\x84\xd5\xab\0" /* offset 101 */ + "\x00\xd5\x8e\xd5\x86\x00\xd5\x8e\xd5\xb6\0" /* offset 112 */ + "\x00\xd5\x84\xd4\xbd\x00\xd5\x84\xd5\xad\0" /* offset 123 */ + "\x00\xca\xbc\x4e\x00\xca\xbc\x4e\0" /* offset 134 */ + "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 143 */ + "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 158 */ + "\x00\x4a\xcc\x8c\x00\x4a\xcc\x8c\0" /* offset 173 */ + "\x00\x48\xcc\xb1\x00\x48\xcc\xb1\0" /* offset 182 */ + "\x00\x54\xcc\x88\x00\x54\xcc\x88\0" /* offset 191 */ + "\x00\x57\xcc\x8a\x00\x57\xcc\x8a\0" /* offset 200 */ + "\x00\x59\xcc\x8a\x00\x59\xcc\x8a\0" /* offset 209 */ + "\x00\x41\xca\xbe\x00\x41\xca\xbe\0" /* offset 218 */ + "\x00\xce\xa5\xcc\x93\x00\xce\xa5\xcc\x93\0" /* offset 227 */ + "\x00\xce\xa5\xcc\x93\xcc\x80\x00\xce\xa5\xcc\x93\xcc\x80\0" /* offset 238 */ + "\x00\xce\xa5\xcc\x93\xcc\x81\x00\xce\xa5\xcc\x93\xcc\x81\0" /* offset 253 */ + "\x00\xce\xa5\xcc\x93\xcd\x82\x00\xce\xa5\xcc\x93\xcd\x82\0" /* offset 268 */ + "\x00\xce\x91\xcd\x82\x00\xce\x91\xcd\x82\0" /* offset 283 */ + "\x00\xce\x97\xcd\x82\x00\xce\x97\xcd\x82\0" /* offset 294 */ + "\x00\xce\x99\xcc\x88\xcc\x80\x00\xce\x99\xcc\x88\xcc\x80\0" /* offset 305 */ + "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 320 */ + "\x00\xce\x99\xcd\x82\x00\xce\x99\xcd\x82\0" /* offset 335 */ + "\x00\xce\x99\xcc\x88\xcd\x82\x00\xce\x99\xcc\x88\xcd\x82\0" /* offset 346 */ + "\x00\xce\xa5\xcc\x88\xcc\x80\x00\xce\xa5\xcc\x88\xcc\x80\0" /* offset 361 */ + "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 376 */ + "\x00\xce\xa1\xcc\x93\x00\xce\xa1\xcc\x93\0" /* offset 391 */ + "\x00\xce\xa5\xcd\x82\x00\xce\xa5\xcd\x82\0" /* offset 402 */ + "\x00\xce\xa5\xcc\x88\xcd\x82\x00\xce\xa5\xcc\x88\xcd\x82\0" /* offset 413 */ + "\x00\xce\xa9\xcd\x82\x00\xce\xa9\xcd\x82\0" /* offset 428 */ + "\xe1\xbe\x88\xe1\xbc\x88\xce\x99\x00\xe1\xbe\x88\0" /* offset 439 */ + "\xe1\xbe\x89\xe1\xbc\x89\xce\x99\x00\xe1\xbe\x89\0" /* offset 452 */ + "\xe1\xbe\x8a\xe1\xbc\x8a\xce\x99\x00\xe1\xbe\x8a\0" /* offset 465 */ + "\xe1\xbe\x8b\xe1\xbc\x8b\xce\x99\x00\xe1\xbe\x8b\0" /* offset 478 */ + "\xe1\xbe\x8c\xe1\xbc\x8c\xce\x99\x00\xe1\xbe\x8c\0" /* offset 491 */ + "\xe1\xbe\x8d\xe1\xbc\x8d\xce\x99\x00\xe1\xbe\x8d\0" /* offset 504 */ + "\xe1\xbe\x8e\xe1\xbc\x8e\xce\x99\x00\xe1\xbe\x8e\0" /* offset 517 */ + "\xe1\xbe\x8f\xe1\xbc\x8f\xce\x99\x00\xe1\xbe\x8f\0" /* offset 530 */ + "\xe1\xbe\x80\x00\xe1\xbc\x88\xce\x99\0" /* offset 543 */ + "\xe1\xbe\x81\x00\xe1\xbc\x89\xce\x99\0" /* offset 553 */ + "\xe1\xbe\x82\x00\xe1\xbc\x8a\xce\x99\0" /* offset 563 */ + "\xe1\xbe\x83\x00\xe1\xbc\x8b\xce\x99\0" /* offset 573 */ + "\xe1\xbe\x84\x00\xe1\xbc\x8c\xce\x99\0" /* offset 583 */ + "\xe1\xbe\x85\x00\xe1\xbc\x8d\xce\x99\0" /* offset 593 */ + "\xe1\xbe\x86\x00\xe1\xbc\x8e\xce\x99\0" /* offset 603 */ + "\xe1\xbe\x87\x00\xe1\xbc\x8f\xce\x99\0" /* offset 613 */ + "\xe1\xbe\x98\xe1\xbc\xa8\xce\x99\x00\xe1\xbe\x98\0" /* offset 623 */ + "\xe1\xbe\x99\xe1\xbc\xa9\xce\x99\x00\xe1\xbe\x99\0" /* offset 636 */ + "\xe1\xbe\x9a\xe1\xbc\xaa\xce\x99\x00\xe1\xbe\x9a\0" /* offset 649 */ + "\xe1\xbe\x9b\xe1\xbc\xab\xce\x99\x00\xe1\xbe\x9b\0" /* offset 662 */ + "\xe1\xbe\x9c\xe1\xbc\xac\xce\x99\x00\xe1\xbe\x9c\0" /* offset 675 */ + "\xe1\xbe\x9d\xe1\xbc\xad\xce\x99\x00\xe1\xbe\x9d\0" /* offset 688 */ + "\xe1\xbe\x9e\xe1\xbc\xae\xce\x99\x00\xe1\xbe\x9e\0" /* offset 701 */ + "\xe1\xbe\x9f\xe1\xbc\xaf\xce\x99\x00\xe1\xbe\x9f\0" /* offset 714 */ + "\xe1\xbe\x90\x00\xe1\xbc\xa8\xce\x99\0" /* offset 727 */ + "\xe1\xbe\x91\x00\xe1\xbc\xa9\xce\x99\0" /* offset 737 */ + "\xe1\xbe\x92\x00\xe1\xbc\xaa\xce\x99\0" /* offset 747 */ + "\xe1\xbe\x93\x00\xe1\xbc\xab\xce\x99\0" /* offset 757 */ + "\xe1\xbe\x94\x00\xe1\xbc\xac\xce\x99\0" /* offset 767 */ + "\xe1\xbe\x95\x00\xe1\xbc\xad\xce\x99\0" /* offset 777 */ + "\xe1\xbe\x96\x00\xe1\xbc\xae\xce\x99\0" /* offset 787 */ + "\xe1\xbe\x97\x00\xe1\xbc\xaf\xce\x99\0" /* offset 797 */ + "\xe1\xbe\xa8\xe1\xbd\xa8\xce\x99\x00\xe1\xbe\xa8\0" /* offset 807 */ + "\xe1\xbe\xa9\xe1\xbd\xa9\xce\x99\x00\xe1\xbe\xa9\0" /* offset 820 */ + "\xe1\xbe\xaa\xe1\xbd\xaa\xce\x99\x00\xe1\xbe\xaa\0" /* offset 833 */ + "\xe1\xbe\xab\xe1\xbd\xab\xce\x99\x00\xe1\xbe\xab\0" /* offset 846 */ + "\xe1\xbe\xac\xe1\xbd\xac\xce\x99\x00\xe1\xbe\xac\0" /* offset 859 */ + "\xe1\xbe\xad\xe1\xbd\xad\xce\x99\x00\xe1\xbe\xad\0" /* offset 872 */ + "\xe1\xbe\xae\xe1\xbd\xae\xce\x99\x00\xe1\xbe\xae\0" /* offset 885 */ + "\xe1\xbe\xaf\xe1\xbd\xaf\xce\x99\x00\xe1\xbe\xaf\0" /* offset 898 */ + "\xe1\xbe\xa0\x00\xe1\xbd\xa8\xce\x99\0" /* offset 911 */ + "\xe1\xbe\xa1\x00\xe1\xbd\xa9\xce\x99\0" /* offset 921 */ + "\xe1\xbe\xa2\x00\xe1\xbd\xaa\xce\x99\0" /* offset 931 */ + "\xe1\xbe\xa3\x00\xe1\xbd\xab\xce\x99\0" /* offset 941 */ + "\xe1\xbe\xa4\x00\xe1\xbd\xac\xce\x99\0" /* offset 951 */ + "\xe1\xbe\xa5\x00\xe1\xbd\xad\xce\x99\0" /* offset 961 */ + "\xe1\xbe\xa6\x00\xe1\xbd\xae\xce\x99\0" /* offset 971 */ + "\xe1\xbe\xa7\x00\xe1\xbd\xaf\xce\x99\0" /* offset 981 */ + "\xe1\xbe\xbc\xce\x91\xce\x99\x00\xe1\xbe\xbc\0" /* offset 991 */ + "\xe1\xbe\xb3\x00\xce\x91\xce\x99\0" /* offset 1003 */ + "\xe1\xbf\x8c\xce\x97\xce\x99\x00\xe1\xbf\x8c\0" /* offset 1012 */ + "\xe1\xbf\x83\x00\xce\x97\xce\x99\0" /* offset 1024 */ + "\xe1\xbf\xbc\xce\xa9\xce\x99\x00\xe1\xbf\xbc\0" /* offset 1033 */ + "\xe1\xbf\xb3\x00\xce\xa9\xce\x99\0" /* offset 1045 */ + "\x00\xe1\xbe\xba\xce\x99\x00\xe1\xbe\xba\xcd\x85\0" /* offset 1054 */ + "\x00\xce\x86\xce\x99\x00\xce\x86\xcd\x85\0" /* offset 1067 */ + "\x00\xe1\xbf\x8a\xce\x99\x00\xe1\xbf\x8a\xcd\x85\0" /* offset 1078 */ + "\x00\xce\x89\xce\x99\x00\xce\x89\xcd\x85\0" /* offset 1091 */ + "\x00\xe1\xbf\xba\xce\x99\x00\xe1\xbf\xba\xcd\x85\0" /* offset 1102 */ + "\x00\xce\x8f\xce\x99\x00\xce\x8f\xcd\x85\0" /* offset 1115 */ + "\x00\xce\x91\xcd\x82\xce\x99\x00\xce\x91\xcd\x82\xcd\x85\0" /* offset 1126 */ + "\x00\xce\x97\xcd\x82\xce\x99\x00\xce\x97\xcd\x82\xcd\x85\0" /* offset 1141 */ + "\x00\xce\xa9\xcd\x82\xce\x99\x00\xce\xa9\xcd\x82\xcd\x85\0" /* offset 1156 */ +}; + + +/* Table of casefolding cases that can't be derived by lowercasing + */ +static const struct { + guint16 ch; + gchar data[7]; +} casefold_table[] = { + { 0x00b5, "\xce\xbc" }, + { 0x00df, "\x73\x73" }, + { 0x0130, "\x69\xcc\x87" }, + { 0x0149, "\xca\xbc\x6e" }, + { 0x017f, "\x73" }, + { 0x01f0, "\x6a\xcc\x8c" }, + { 0x0345, "\xce\xb9" }, + { 0x0390, "\xce\xb9\xcc\x88\xcc\x81" }, + { 0x03b0, "\xcf\x85\xcc\x88\xcc\x81" }, + { 0x03c2, "\xcf\x83" }, + { 0x03d0, "\xce\xb2" }, + { 0x03d1, "\xce\xb8" }, + { 0x03d5, "\xcf\x86" }, + { 0x03d6, "\xcf\x80" }, + { 0x03f0, "\xce\xba" }, + { 0x03f1, "\xcf\x81" }, + { 0x03f5, "\xce\xb5" }, + { 0x0587, "\xd5\xa5\xd6\x82" }, + { 0x1e96, "\x68\xcc\xb1" }, + { 0x1e97, "\x74\xcc\x88" }, + { 0x1e98, "\x77\xcc\x8a" }, + { 0x1e99, "\x79\xcc\x8a" }, + { 0x1e9a, "\x61\xca\xbe" }, + { 0x1e9b, "\xe1\xb9\xa1" }, + { 0x1e9e, "\x73\x73" }, + { 0x1f50, "\xcf\x85\xcc\x93" }, + { 0x1f52, "\xcf\x85\xcc\x93\xcc\x80" }, + { 0x1f54, "\xcf\x85\xcc\x93\xcc\x81" }, + { 0x1f56, "\xcf\x85\xcc\x93\xcd\x82" }, + { 0x1f80, "\xe1\xbc\x80\xce\xb9" }, + { 0x1f81, "\xe1\xbc\x81\xce\xb9" }, + { 0x1f82, "\xe1\xbc\x82\xce\xb9" }, + { 0x1f83, "\xe1\xbc\x83\xce\xb9" }, + { 0x1f84, "\xe1\xbc\x84\xce\xb9" }, + { 0x1f85, "\xe1\xbc\x85\xce\xb9" }, + { 0x1f86, "\xe1\xbc\x86\xce\xb9" }, + { 0x1f87, "\xe1\xbc\x87\xce\xb9" }, + { 0x1f88, "\xe1\xbc\x80\xce\xb9" }, + { 0x1f89, "\xe1\xbc\x81\xce\xb9" }, + { 0x1f8a, "\xe1\xbc\x82\xce\xb9" }, + { 0x1f8b, "\xe1\xbc\x83\xce\xb9" }, + { 0x1f8c, "\xe1\xbc\x84\xce\xb9" }, + { 0x1f8d, "\xe1\xbc\x85\xce\xb9" }, + { 0x1f8e, "\xe1\xbc\x86\xce\xb9" }, + { 0x1f8f, "\xe1\xbc\x87\xce\xb9" }, + { 0x1f90, "\xe1\xbc\xa0\xce\xb9" }, + { 0x1f91, "\xe1\xbc\xa1\xce\xb9" }, + { 0x1f92, "\xe1\xbc\xa2\xce\xb9" }, + { 0x1f93, "\xe1\xbc\xa3\xce\xb9" }, + { 0x1f94, "\xe1\xbc\xa4\xce\xb9" }, + { 0x1f95, "\xe1\xbc\xa5\xce\xb9" }, + { 0x1f96, "\xe1\xbc\xa6\xce\xb9" }, + { 0x1f97, "\xe1\xbc\xa7\xce\xb9" }, + { 0x1f98, "\xe1\xbc\xa0\xce\xb9" }, + { 0x1f99, "\xe1\xbc\xa1\xce\xb9" }, + { 0x1f9a, "\xe1\xbc\xa2\xce\xb9" }, + { 0x1f9b, "\xe1\xbc\xa3\xce\xb9" }, + { 0x1f9c, "\xe1\xbc\xa4\xce\xb9" }, + { 0x1f9d, "\xe1\xbc\xa5\xce\xb9" }, + { 0x1f9e, "\xe1\xbc\xa6\xce\xb9" }, + { 0x1f9f, "\xe1\xbc\xa7\xce\xb9" }, + { 0x1fa0, "\xe1\xbd\xa0\xce\xb9" }, + { 0x1fa1, "\xe1\xbd\xa1\xce\xb9" }, + { 0x1fa2, "\xe1\xbd\xa2\xce\xb9" }, + { 0x1fa3, "\xe1\xbd\xa3\xce\xb9" }, + { 0x1fa4, "\xe1\xbd\xa4\xce\xb9" }, + { 0x1fa5, "\xe1\xbd\xa5\xce\xb9" }, + { 0x1fa6, "\xe1\xbd\xa6\xce\xb9" }, + { 0x1fa7, "\xe1\xbd\xa7\xce\xb9" }, + { 0x1fa8, "\xe1\xbd\xa0\xce\xb9" }, + { 0x1fa9, "\xe1\xbd\xa1\xce\xb9" }, + { 0x1faa, "\xe1\xbd\xa2\xce\xb9" }, + { 0x1fab, "\xe1\xbd\xa3\xce\xb9" }, + { 0x1fac, "\xe1\xbd\xa4\xce\xb9" }, + { 0x1fad, "\xe1\xbd\xa5\xce\xb9" }, + { 0x1fae, "\xe1\xbd\xa6\xce\xb9" }, + { 0x1faf, "\xe1\xbd\xa7\xce\xb9" }, + { 0x1fb2, "\xe1\xbd\xb0\xce\xb9" }, + { 0x1fb3, "\xce\xb1\xce\xb9" }, + { 0x1fb4, "\xce\xac\xce\xb9" }, + { 0x1fb6, "\xce\xb1\xcd\x82" }, + { 0x1fb7, "\xce\xb1\xcd\x82\xce\xb9" }, + { 0x1fbc, "\xce\xb1\xce\xb9" }, + { 0x1fbe, "\xce\xb9" }, + { 0x1fc2, "\xe1\xbd\xb4\xce\xb9" }, + { 0x1fc3, "\xce\xb7\xce\xb9" }, + { 0x1fc4, "\xce\xae\xce\xb9" }, + { 0x1fc6, "\xce\xb7\xcd\x82" }, + { 0x1fc7, "\xce\xb7\xcd\x82\xce\xb9" }, + { 0x1fcc, "\xce\xb7\xce\xb9" }, + { 0x1fd2, "\xce\xb9\xcc\x88\xcc\x80" }, + { 0x1fd3, "\xce\xb9\xcc\x88\xcc\x81" }, + { 0x1fd6, "\xce\xb9\xcd\x82" }, + { 0x1fd7, "\xce\xb9\xcc\x88\xcd\x82" }, + { 0x1fe2, "\xcf\x85\xcc\x88\xcc\x80" }, + { 0x1fe3, "\xcf\x85\xcc\x88\xcc\x81" }, + { 0x1fe4, "\xcf\x81\xcc\x93" }, + { 0x1fe6, "\xcf\x85\xcd\x82" }, + { 0x1fe7, "\xcf\x85\xcc\x88\xcd\x82" }, + { 0x1ff2, "\xe1\xbd\xbc\xce\xb9" }, + { 0x1ff3, "\xcf\x89\xce\xb9" }, + { 0x1ff4, "\xcf\x8e\xce\xb9" }, + { 0x1ff6, "\xcf\x89\xcd\x82" }, + { 0x1ff7, "\xcf\x89\xcd\x82\xce\xb9" }, + { 0x1ffc, "\xcf\x89\xce\xb9" }, + { 0x2160, "\xe2\x85\xb0" }, + { 0x2161, "\xe2\x85\xb1" }, + { 0x2162, "\xe2\x85\xb2" }, + { 0x2163, "\xe2\x85\xb3" }, + { 0x2164, "\xe2\x85\xb4" }, + { 0x2165, "\xe2\x85\xb5" }, + { 0x2166, "\xe2\x85\xb6" }, + { 0x2167, "\xe2\x85\xb7" }, + { 0x2168, "\xe2\x85\xb8" }, + { 0x2169, "\xe2\x85\xb9" }, + { 0x216a, "\xe2\x85\xba" }, + { 0x216b, "\xe2\x85\xbb" }, + { 0x216c, "\xe2\x85\xbc" }, + { 0x216d, "\xe2\x85\xbd" }, + { 0x216e, "\xe2\x85\xbe" }, + { 0x216f, "\xe2\x85\xbf" }, + { 0x24b6, "\xe2\x93\x90" }, + { 0x24b7, "\xe2\x93\x91" }, + { 0x24b8, "\xe2\x93\x92" }, + { 0x24b9, "\xe2\x93\x93" }, + { 0x24ba, "\xe2\x93\x94" }, + { 0x24bb, "\xe2\x93\x95" }, + { 0x24bc, "\xe2\x93\x96" }, + { 0x24bd, "\xe2\x93\x97" }, + { 0x24be, "\xe2\x93\x98" }, + { 0x24bf, "\xe2\x93\x99" }, + { 0x24c0, "\xe2\x93\x9a" }, + { 0x24c1, "\xe2\x93\x9b" }, + { 0x24c2, "\xe2\x93\x9c" }, + { 0x24c3, "\xe2\x93\x9d" }, + { 0x24c4, "\xe2\x93\x9e" }, + { 0x24c5, "\xe2\x93\x9f" }, + { 0x24c6, "\xe2\x93\xa0" }, + { 0x24c7, "\xe2\x93\xa1" }, + { 0x24c8, "\xe2\x93\xa2" }, + { 0x24c9, "\xe2\x93\xa3" }, + { 0x24ca, "\xe2\x93\xa4" }, + { 0x24cb, "\xe2\x93\xa5" }, + { 0x24cc, "\xe2\x93\xa6" }, + { 0x24cd, "\xe2\x93\xa7" }, + { 0x24ce, "\xe2\x93\xa8" }, + { 0x24cf, "\xe2\x93\xa9" }, + { 0xfb00, "\x66\x66" }, + { 0xfb01, "\x66\x69" }, + { 0xfb02, "\x66\x6c" }, + { 0xfb03, "\x66\x66\x69" }, + { 0xfb04, "\x66\x66\x6c" }, + { 0xfb05, "\x73\x74" }, + { 0xfb06, "\x73\x74" }, + { 0xfb13, "\xd5\xb4\xd5\xb6" }, + { 0xfb14, "\xd5\xb4\xd5\xa5" }, + { 0xfb15, "\xd5\xb4\xd5\xab" }, + { 0xfb16, "\xd5\xbe\xd5\xb6" }, + { 0xfb17, "\xd5\xb4\xd5\xad" }, +}; + +#endif /* CHARTABLES_H */ diff --git a/glib/glib/gunicode.h b/glib/glib/gunicode.h new file mode 100644 index 0000000..83b4941 --- /dev/null +++ b/glib/glib/gunicode.h @@ -0,0 +1,751 @@ +/* gunicode.h - Unicode manipulation functions + * + * Copyright (C) 1999, 2000 Tom Tromey + * Copyright 2000, 2005 Red Hat, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_UNICODE_H__ +#define __G_UNICODE_H__ + +#include +#include + +G_BEGIN_DECLS + +/** + * gunichar: + * + * A type which can hold any UTF-32 or UCS-4 character code, + * also known as a Unicode code point. + * + * If you want to produce the UTF-8 representation of a #gunichar, + * use g_ucs4_to_utf8(). See also g_utf8_to_ucs4() for the reverse + * process. + * + * To print/scan values of this type as integer, use + * %G_GINT32_MODIFIER and/or %G_GUINT32_FORMAT. + * + * The notation to express a Unicode code point in running text is + * as a hexadecimal number with four to six digits and uppercase + * letters, prefixed by the string "U+". Leading zeros are omitted, + * unless the code point would have fewer than four hexadecimal digits. + * For example, "U+0041 LATIN CAPITAL LETTER A". To print a code point + * in the U+-notation, use the format string "U+\%04"G_GINT32_FORMAT"X". + * To scan, use the format string "U+\%06"G_GINT32_FORMAT"X". + * + * |[ + * gunichar c; + * sscanf ("U+0041", "U+%06"G_GINT32_FORMAT"X", &c) + * g_print ("Read U+%04"G_GINT32_FORMAT"X", c); + * ]| + */ +typedef guint32 gunichar; + +/** + * gunichar2: + * + * A type which can hold any UTF-16 code + * pointUTF-16 also has so called + * surrogate pairs to encode characters beyond + * the BMP as pairs of 16bit numbers. Surrogate pairs cannot be stored + * in a single gunichar2 field, but all GLib functions accepting gunichar2 + * arrays will correctly interpret surrogate pairs.. + * + * To print/scan values of this type to/from text you need to convert + * to/from UTF-8, using g_utf16_to_utf8()/g_utf8_to_utf16(). + * + * To print/scan values of this type as integer, use + * %G_GINT16_MODIFIER and/or %G_GUINT16_FORMAT. + */ +typedef guint16 gunichar2; + +/** + * GUnicodeType: + * @G_UNICODE_CONTROL: General category "Other, Control" (Cc) + * @G_UNICODE_FORMAT: General category "Other, Format" (Cf) + * @G_UNICODE_UNASSIGNED: General category "Other, Not Assigned" (Cn) + * @G_UNICODE_PRIVATE_USE: General category "Other, Private Use" (Co) + * @G_UNICODE_SURROGATE: General category "Other, Surrogate" (Cs) + * @G_UNICODE_LOWERCASE_LETTER: General category "Letter, Lowercase" (Ll) + * @G_UNICODE_MODIFIER_LETTER: General category "Letter, Modifier" (Lm) + * @G_UNICODE_OTHER_LETTER: General category "Letter, Other" (Lo) + * @G_UNICODE_TITLECASE_LETTER: General category "Letter, Titlecase" (Lt) + * @G_UNICODE_UPPERCASE_LETTER: General category "Letter, Uppercase" (Lu) + * @G_UNICODE_SPACING_MARK: General category "Mark, Spacing" (Mc) + * @G_UNICODE_ENCLOSING_MARK: General category "Mark, Enclosing" (Me) + * @G_UNICODE_NON_SPACING_MARK: General category "Mark, Nonspacing" (Mn) + * @G_UNICODE_DECIMAL_NUMBER: General category "Number, Decimal Digit" (Nd) + * @G_UNICODE_LETTER_NUMBER: General category "Number, Letter" (Nl) + * @G_UNICODE_OTHER_NUMBER: General category "Number, Other" (No) + * @G_UNICODE_CONNECT_PUNCTUATION: General category "Punctuation, Connector" (Pc) + * @G_UNICODE_DASH_PUNCTUATION: General category "Punctuation, Dash" (Pd) + * @G_UNICODE_CLOSE_PUNCTUATION: General category "Punctuation, Close" (Pe) + * @G_UNICODE_FINAL_PUNCTUATION: General category "Punctuation, Final quote" (Pf) + * @G_UNICODE_INITIAL_PUNCTUATION: General category "Punctuation, Initial quote" (Pi) + * @G_UNICODE_OTHER_PUNCTUATION: General category "Punctuation, Other" (Po) + * @G_UNICODE_OPEN_PUNCTUATION: General category "Punctuation, Open" (Ps) + * @G_UNICODE_CURRENCY_SYMBOL: General category "Symbol, Currency" (Sc) + * @G_UNICODE_MODIFIER_SYMBOL: General category "Symbol, Modifier" (Sk) + * @G_UNICODE_MATH_SYMBOL: General category "Symbol, Math" (Sm) + * @G_UNICODE_OTHER_SYMBOL: General category "Symbol, Other" (So) + * @G_UNICODE_LINE_SEPARATOR: General category "Separator, Line" (Zl) + * @G_UNICODE_PARAGRAPH_SEPARATOR: General category "Separator, Paragraph" (Zp) + * @G_UNICODE_SPACE_SEPARATOR: General category "Separator, Space" (Zs) + * + * These are the possible character classifications from the + * Unicode specification. + * See http://www.unicode.org/Public/UNIDATA/UnicodeData.html. + */ +typedef enum +{ + G_UNICODE_CONTROL, + G_UNICODE_FORMAT, + G_UNICODE_UNASSIGNED, + G_UNICODE_PRIVATE_USE, + G_UNICODE_SURROGATE, + G_UNICODE_LOWERCASE_LETTER, + G_UNICODE_MODIFIER_LETTER, + G_UNICODE_OTHER_LETTER, + G_UNICODE_TITLECASE_LETTER, + G_UNICODE_UPPERCASE_LETTER, + G_UNICODE_SPACING_MARK, + G_UNICODE_ENCLOSING_MARK, + G_UNICODE_NON_SPACING_MARK, + G_UNICODE_DECIMAL_NUMBER, + G_UNICODE_LETTER_NUMBER, + G_UNICODE_OTHER_NUMBER, + G_UNICODE_CONNECT_PUNCTUATION, + G_UNICODE_DASH_PUNCTUATION, + G_UNICODE_CLOSE_PUNCTUATION, + G_UNICODE_FINAL_PUNCTUATION, + G_UNICODE_INITIAL_PUNCTUATION, + G_UNICODE_OTHER_PUNCTUATION, + G_UNICODE_OPEN_PUNCTUATION, + G_UNICODE_CURRENCY_SYMBOL, + G_UNICODE_MODIFIER_SYMBOL, + G_UNICODE_MATH_SYMBOL, + G_UNICODE_OTHER_SYMBOL, + G_UNICODE_LINE_SEPARATOR, + G_UNICODE_PARAGRAPH_SEPARATOR, + G_UNICODE_SPACE_SEPARATOR +} GUnicodeType; + +/** + * G_UNICODE_COMBINING_MARK: + * + * Older name for %G_UNICODE_SPACING_MARK. + * + * Deprecated: 2.30: Use %G_UNICODE_SPACING_MARK. + */ +#ifndef G_DISABLE_DEPRECATED +#define G_UNICODE_COMBINING_MARK G_UNICODE_SPACING_MARK +#endif + +/** + * GUnicodeBreakType: + * @G_UNICODE_BREAK_MANDATORY: Mandatory Break (BK) + * @G_UNICODE_BREAK_CARRIAGE_RETURN: Carriage Return (CR) + * @G_UNICODE_BREAK_LINE_FEED: Line Feed (LF) + * @G_UNICODE_BREAK_COMBINING_MARK: Attached Characters and Combining Marks (CM) + * @G_UNICODE_BREAK_SURROGATE: Surrogates (SG) + * @G_UNICODE_BREAK_ZERO_WIDTH_SPACE: Zero Width Space (ZW) + * @G_UNICODE_BREAK_INSEPARABLE: Inseparable (IN) + * @G_UNICODE_BREAK_NON_BREAKING_GLUE: Non-breaking ("Glue") (GL) + * @G_UNICODE_BREAK_CONTINGENT: Contingent Break Opportunity (CB) + * @G_UNICODE_BREAK_SPACE: Space (SP) + * @G_UNICODE_BREAK_AFTER: Break Opportunity After (BA) + * @G_UNICODE_BREAK_BEFORE: Break Opportunity Before (BB) + * @G_UNICODE_BREAK_BEFORE_AND_AFTER: Break Opportunity Before and After (B2) + * @G_UNICODE_BREAK_HYPHEN: Hyphen (HY) + * @G_UNICODE_BREAK_NON_STARTER: Nonstarter (NS) + * @G_UNICODE_BREAK_OPEN_PUNCTUATION: Opening Punctuation (OP) + * @G_UNICODE_BREAK_CLOSE_PUNCTUATION: Closing Punctuation (CL) + * @G_UNICODE_BREAK_QUOTATION: Ambiguous Quotation (QU) + * @G_UNICODE_BREAK_EXCLAMATION: Exclamation/Interrogation (EX) + * @G_UNICODE_BREAK_IDEOGRAPHIC: Ideographic (ID) + * @G_UNICODE_BREAK_NUMERIC: Numeric (NU) + * @G_UNICODE_BREAK_INFIX_SEPARATOR: Infix Separator (Numeric) (IS) + * @G_UNICODE_BREAK_SYMBOL: Symbols Allowing Break After (SY) + * @G_UNICODE_BREAK_ALPHABETIC: Ordinary Alphabetic and Symbol Characters (AL) + * @G_UNICODE_BREAK_PREFIX: Prefix (Numeric) (PR) + * @G_UNICODE_BREAK_POSTFIX: Postfix (Numeric) (PO) + * @G_UNICODE_BREAK_COMPLEX_CONTEXT: Complex Content Dependent (South East Asian) (SA) + * @G_UNICODE_BREAK_AMBIGUOUS: Ambiguous (Alphabetic or Ideographic) (AI) + * @G_UNICODE_BREAK_UNKNOWN: Unknown (XX) + * @G_UNICODE_BREAK_NEXT_LINE: Next Line (NL) + * @G_UNICODE_BREAK_WORD_JOINER: Word Joiner (WJ) + * @G_UNICODE_BREAK_HANGUL_L_JAMO: Hangul L Jamo (JL) + * @G_UNICODE_BREAK_HANGUL_V_JAMO: Hangul V Jamo (JV) + * @G_UNICODE_BREAK_HANGUL_T_JAMO: Hangul T Jamo (JT) + * @G_UNICODE_BREAK_HANGUL_LV_SYLLABLE: Hangul LV Syllable (H2) + * @G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE: Hangul LVT Syllable (H3) + * @G_UNICODE_BREAK_CLOSE_PARANTHESIS: Closing Parenthesis (CP). Since 2.28 + * @G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER: Conditional Japanese Starter (CJ). Since: 2.32 + * @G_UNICODE_BREAK_HEBREW_LETTER: Hebrew Letter (HL). Since: 2.32 + * + * These are the possible line break classifications. + * + * The five Hangul types were added in Unicode 4.1, so, has been + * introduced in GLib 2.10. Note that new types may be added in the future. + * Applications should be ready to handle unknown values. + * They may be regarded as %G_UNICODE_BREAK_UNKNOWN. + * + * See http://www.unicode.org/unicode/reports/tr14/. + */ +typedef enum +{ + G_UNICODE_BREAK_MANDATORY, + G_UNICODE_BREAK_CARRIAGE_RETURN, + G_UNICODE_BREAK_LINE_FEED, + G_UNICODE_BREAK_COMBINING_MARK, + G_UNICODE_BREAK_SURROGATE, + G_UNICODE_BREAK_ZERO_WIDTH_SPACE, + G_UNICODE_BREAK_INSEPARABLE, + G_UNICODE_BREAK_NON_BREAKING_GLUE, + G_UNICODE_BREAK_CONTINGENT, + G_UNICODE_BREAK_SPACE, + G_UNICODE_BREAK_AFTER, + G_UNICODE_BREAK_BEFORE, + G_UNICODE_BREAK_BEFORE_AND_AFTER, + G_UNICODE_BREAK_HYPHEN, + G_UNICODE_BREAK_NON_STARTER, + G_UNICODE_BREAK_OPEN_PUNCTUATION, + G_UNICODE_BREAK_CLOSE_PUNCTUATION, + G_UNICODE_BREAK_QUOTATION, + G_UNICODE_BREAK_EXCLAMATION, + G_UNICODE_BREAK_IDEOGRAPHIC, + G_UNICODE_BREAK_NUMERIC, + G_UNICODE_BREAK_INFIX_SEPARATOR, + G_UNICODE_BREAK_SYMBOL, + G_UNICODE_BREAK_ALPHABETIC, + G_UNICODE_BREAK_PREFIX, + G_UNICODE_BREAK_POSTFIX, + G_UNICODE_BREAK_COMPLEX_CONTEXT, + G_UNICODE_BREAK_AMBIGUOUS, + G_UNICODE_BREAK_UNKNOWN, + G_UNICODE_BREAK_NEXT_LINE, + G_UNICODE_BREAK_WORD_JOINER, + G_UNICODE_BREAK_HANGUL_L_JAMO, + G_UNICODE_BREAK_HANGUL_V_JAMO, + G_UNICODE_BREAK_HANGUL_T_JAMO, + G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, + G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, + G_UNICODE_BREAK_CLOSE_PARANTHESIS, + G_UNICODE_BREAK_CONDITIONAL_JAPANESE_STARTER, + G_UNICODE_BREAK_HEBREW_LETTER +} GUnicodeBreakType; + +/** + * GUnicodeScript: + * @G_UNICODE_SCRIPT_INVALID_CODE: + * a value never returned from g_unichar_get_script() + * @G_UNICODE_SCRIPT_COMMON: a character used by multiple different scripts + * @G_UNICODE_SCRIPT_INHERITED: a mark glyph that takes its script from the + * i base glyph to which it is attached + * @G_UNICODE_SCRIPT_ARABIC: Arabic + * @G_UNICODE_SCRIPT_ARMENIAN: Armenian + * @G_UNICODE_SCRIPT_BENGALI: Bengali + * @G_UNICODE_SCRIPT_BOPOMOFO: Bopomofo + * @G_UNICODE_SCRIPT_CHEROKEE: Cherokee + * @G_UNICODE_SCRIPT_COPTIC: Coptic + * @G_UNICODE_SCRIPT_CYRILLIC: Cyrillic + * @G_UNICODE_SCRIPT_DESERET: Deseret + * @G_UNICODE_SCRIPT_DEVANAGARI: Devanagari + * @G_UNICODE_SCRIPT_ETHIOPIC: Ethiopic + * @G_UNICODE_SCRIPT_GEORGIAN: Georgian + * @G_UNICODE_SCRIPT_GOTHIC: Gothic + * @G_UNICODE_SCRIPT_GREEK: Greek + * @G_UNICODE_SCRIPT_GUJARATI: Gujarati + * @G_UNICODE_SCRIPT_GURMUKHI: Gurmukhi + * @G_UNICODE_SCRIPT_HAN: Han + * @G_UNICODE_SCRIPT_HANGUL: Hangul + * @G_UNICODE_SCRIPT_HEBREW: Hebrew + * @G_UNICODE_SCRIPT_HIRAGANA: Hiragana + * @G_UNICODE_SCRIPT_KANNADA: Kannada + * @G_UNICODE_SCRIPT_KATAKANA: Katakana + * @G_UNICODE_SCRIPT_KHMER: Khmer + * @G_UNICODE_SCRIPT_LAO: Lao + * @G_UNICODE_SCRIPT_LATIN: Latin + * @G_UNICODE_SCRIPT_MALAYALAM: Malayalam + * @G_UNICODE_SCRIPT_MONGOLIAN: Mongolian + * @G_UNICODE_SCRIPT_MYANMAR: Myanmar + * @G_UNICODE_SCRIPT_OGHAM: Ogham + * @G_UNICODE_SCRIPT_OLD_ITALIC: Old Italic + * @G_UNICODE_SCRIPT_ORIYA: Oriya + * @G_UNICODE_SCRIPT_RUNIC: Runic + * @G_UNICODE_SCRIPT_SINHALA: Sinhala + * @G_UNICODE_SCRIPT_SYRIAC: Syriac + * @G_UNICODE_SCRIPT_TAMIL: Tamil + * @G_UNICODE_SCRIPT_TELUGU: Telugu + * @G_UNICODE_SCRIPT_THAANA: Thaana + * @G_UNICODE_SCRIPT_THAI: Thai + * @G_UNICODE_SCRIPT_TIBETAN: Tibetan + * @G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL: + * Canadian Aboriginal + * @G_UNICODE_SCRIPT_YI: Yi + * @G_UNICODE_SCRIPT_TAGALOG: Tagalog + * @G_UNICODE_SCRIPT_HANUNOO: Hanunoo + * @G_UNICODE_SCRIPT_BUHID: Buhid + * @G_UNICODE_SCRIPT_TAGBANWA: Tagbanwa + * @G_UNICODE_SCRIPT_BRAILLE: Braille + * @G_UNICODE_SCRIPT_CYPRIOT: Cypriot + * @G_UNICODE_SCRIPT_LIMBU: Limbu + * @G_UNICODE_SCRIPT_OSMANYA: Osmanya + * @G_UNICODE_SCRIPT_SHAVIAN: Shavian + * @G_UNICODE_SCRIPT_LINEAR_B: Linear B + * @G_UNICODE_SCRIPT_TAI_LE: Tai Le + * @G_UNICODE_SCRIPT_UGARITIC: Ugaritic + * @G_UNICODE_SCRIPT_NEW_TAI_LUE: + * New Tai Lue + * @G_UNICODE_SCRIPT_BUGINESE: Buginese + * @G_UNICODE_SCRIPT_GLAGOLITIC: Glagolitic + * @G_UNICODE_SCRIPT_TIFINAGH: Tifinagh + * @G_UNICODE_SCRIPT_SYLOTI_NAGRI: + * Syloti Nagri + * @G_UNICODE_SCRIPT_OLD_PERSIAN: + * Old Persian + * @G_UNICODE_SCRIPT_KHAROSHTHI: Kharoshthi + * @G_UNICODE_SCRIPT_UNKNOWN: an unassigned code point + * @G_UNICODE_SCRIPT_BALINESE: Balinese + * @G_UNICODE_SCRIPT_CUNEIFORM: Cuneiform + * @G_UNICODE_SCRIPT_PHOENICIAN: Phoenician + * @G_UNICODE_SCRIPT_PHAGS_PA: Phags-pa + * @G_UNICODE_SCRIPT_NKO: N'Ko + * @G_UNICODE_SCRIPT_KAYAH_LI: Kayah Li. Since 2.16.3 + * @G_UNICODE_SCRIPT_LEPCHA: Lepcha. Since 2.16.3 + * @G_UNICODE_SCRIPT_REJANG: Rejang. Since 2.16.3 + * @G_UNICODE_SCRIPT_SUNDANESE: Sundanese. Since 2.16.3 + * @G_UNICODE_SCRIPT_SAURASHTRA: Saurashtra. Since 2.16.3 + * @G_UNICODE_SCRIPT_CHAM: Cham. Since 2.16.3 + * @G_UNICODE_SCRIPT_OL_CHIKI: Ol Chiki. Since 2.16.3 + * @G_UNICODE_SCRIPT_VAI: Vai. Since 2.16.3 + * @G_UNICODE_SCRIPT_CARIAN: Carian. Since 2.16.3 + * @G_UNICODE_SCRIPT_LYCIAN: Lycian. Since 2.16.3 + * @G_UNICODE_SCRIPT_LYDIAN: Lydian. Since 2.16.3 + * @G_UNICODE_SCRIPT_AVESTAN: Avestan. Since 2.26 + * @G_UNICODE_SCRIPT_BAMUM: Bamum. Since 2.26 + * @G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS: + * Egyptian Hieroglpyhs. Since 2.26 + * @G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC: + * Imperial Aramaic. Since 2.26 + * @G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI: + * Inscriptional Pahlavi. Since 2.26 + * @G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN: + * Inscriptional Parthian. Since 2.26 + * @G_UNICODE_SCRIPT_JAVANESE: Javanese. Since 2.26 + * @G_UNICODE_SCRIPT_KAITHI: Kaithi. Since 2.26 + * @G_UNICODE_SCRIPT_LISU: Lisu. Since 2.26 + * @G_UNICODE_SCRIPT_MEETEI_MAYEK: + * Meetei Mayek. Since 2.26 + * @G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN: + * Old South Arabian. Since 2.26 + * @G_UNICODE_SCRIPT_OLD_TURKIC: Old Turkic. Since 2.28 + * @G_UNICODE_SCRIPT_SAMARITAN: Samaritan. Since 2.26 + * @G_UNICODE_SCRIPT_TAI_THAM: Tai Tham. Since 2.26 + * @G_UNICODE_SCRIPT_TAI_VIET: Tai Viet. Since 2.26 + * @G_UNICODE_SCRIPT_BATAK: Batak. Since 2.28 + * @G_UNICODE_SCRIPT_BRAHMI: Brahmi. Since 2.28 + * @G_UNICODE_SCRIPT_MANDAIC: Mandaic. Since 2.28 + * @G_UNICODE_SCRIPT_CHAKMA: Chakma. Since: 2.32 + * @G_UNICODE_SCRIPT_MEROITIC_CURSIVE: Meroitic Cursive. Since: 2.32 + * @G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS, Meroitic Hieroglyphs. Since: 2.32 + * @G_UNICODE_SCRIPT_MIAO: Miao. Since: 2.32 + * @G_UNICODE_SCRIPT_SHARADA: Sharada. Since: 2.32 + * @G_UNICODE_SCRIPT_SORA_SOMPENG: Sora Sompeng. Since: 2.32 + * @G_UNICODE_SCRIPT_TAKRI: Takri. Since: 2.32 + * + * The #GUnicodeScript enumeration identifies different writing + * systems. The values correspond to the names as defined in the + * Unicode standard. The enumeration has been added in GLib 2.14, + * and is interchangeable with #PangoScript. + * + * Note that new types may be added in the future. Applications + * should be ready to handle unknown values. + * See Unicode Standard Annex + * #24: Script names. + */ +typedef enum +{ /* ISO 15924 code */ + G_UNICODE_SCRIPT_INVALID_CODE = -1, + G_UNICODE_SCRIPT_COMMON = 0, /* Zyyy */ + G_UNICODE_SCRIPT_INHERITED, /* Zinh (Qaai) */ + G_UNICODE_SCRIPT_ARABIC, /* Arab */ + G_UNICODE_SCRIPT_ARMENIAN, /* Armn */ + G_UNICODE_SCRIPT_BENGALI, /* Beng */ + G_UNICODE_SCRIPT_BOPOMOFO, /* Bopo */ + G_UNICODE_SCRIPT_CHEROKEE, /* Cher */ + G_UNICODE_SCRIPT_COPTIC, /* Copt (Qaac) */ + G_UNICODE_SCRIPT_CYRILLIC, /* Cyrl (Cyrs) */ + G_UNICODE_SCRIPT_DESERET, /* Dsrt */ + G_UNICODE_SCRIPT_DEVANAGARI, /* Deva */ + G_UNICODE_SCRIPT_ETHIOPIC, /* Ethi */ + G_UNICODE_SCRIPT_GEORGIAN, /* Geor (Geon, Geoa) */ + G_UNICODE_SCRIPT_GOTHIC, /* Goth */ + G_UNICODE_SCRIPT_GREEK, /* Grek */ + G_UNICODE_SCRIPT_GUJARATI, /* Gujr */ + G_UNICODE_SCRIPT_GURMUKHI, /* Guru */ + G_UNICODE_SCRIPT_HAN, /* Hani */ + G_UNICODE_SCRIPT_HANGUL, /* Hang */ + G_UNICODE_SCRIPT_HEBREW, /* Hebr */ + G_UNICODE_SCRIPT_HIRAGANA, /* Hira */ + G_UNICODE_SCRIPT_KANNADA, /* Knda */ + G_UNICODE_SCRIPT_KATAKANA, /* Kana */ + G_UNICODE_SCRIPT_KHMER, /* Khmr */ + G_UNICODE_SCRIPT_LAO, /* Laoo */ + G_UNICODE_SCRIPT_LATIN, /* Latn (Latf, Latg) */ + G_UNICODE_SCRIPT_MALAYALAM, /* Mlym */ + G_UNICODE_SCRIPT_MONGOLIAN, /* Mong */ + G_UNICODE_SCRIPT_MYANMAR, /* Mymr */ + G_UNICODE_SCRIPT_OGHAM, /* Ogam */ + G_UNICODE_SCRIPT_OLD_ITALIC, /* Ital */ + G_UNICODE_SCRIPT_ORIYA, /* Orya */ + G_UNICODE_SCRIPT_RUNIC, /* Runr */ + G_UNICODE_SCRIPT_SINHALA, /* Sinh */ + G_UNICODE_SCRIPT_SYRIAC, /* Syrc (Syrj, Syrn, Syre) */ + G_UNICODE_SCRIPT_TAMIL, /* Taml */ + G_UNICODE_SCRIPT_TELUGU, /* Telu */ + G_UNICODE_SCRIPT_THAANA, /* Thaa */ + G_UNICODE_SCRIPT_THAI, /* Thai */ + G_UNICODE_SCRIPT_TIBETAN, /* Tibt */ + G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */ + G_UNICODE_SCRIPT_YI, /* Yiii */ + G_UNICODE_SCRIPT_TAGALOG, /* Tglg */ + G_UNICODE_SCRIPT_HANUNOO, /* Hano */ + G_UNICODE_SCRIPT_BUHID, /* Buhd */ + G_UNICODE_SCRIPT_TAGBANWA, /* Tagb */ + + /* Unicode-4.0 additions */ + G_UNICODE_SCRIPT_BRAILLE, /* Brai */ + G_UNICODE_SCRIPT_CYPRIOT, /* Cprt */ + G_UNICODE_SCRIPT_LIMBU, /* Limb */ + G_UNICODE_SCRIPT_OSMANYA, /* Osma */ + G_UNICODE_SCRIPT_SHAVIAN, /* Shaw */ + G_UNICODE_SCRIPT_LINEAR_B, /* Linb */ + G_UNICODE_SCRIPT_TAI_LE, /* Tale */ + G_UNICODE_SCRIPT_UGARITIC, /* Ugar */ + + /* Unicode-4.1 additions */ + G_UNICODE_SCRIPT_NEW_TAI_LUE, /* Talu */ + G_UNICODE_SCRIPT_BUGINESE, /* Bugi */ + G_UNICODE_SCRIPT_GLAGOLITIC, /* Glag */ + G_UNICODE_SCRIPT_TIFINAGH, /* Tfng */ + G_UNICODE_SCRIPT_SYLOTI_NAGRI, /* Sylo */ + G_UNICODE_SCRIPT_OLD_PERSIAN, /* Xpeo */ + G_UNICODE_SCRIPT_KHAROSHTHI, /* Khar */ + + /* Unicode-5.0 additions */ + G_UNICODE_SCRIPT_UNKNOWN, /* Zzzz */ + G_UNICODE_SCRIPT_BALINESE, /* Bali */ + G_UNICODE_SCRIPT_CUNEIFORM, /* Xsux */ + G_UNICODE_SCRIPT_PHOENICIAN, /* Phnx */ + G_UNICODE_SCRIPT_PHAGS_PA, /* Phag */ + G_UNICODE_SCRIPT_NKO, /* Nkoo */ + + /* Unicode-5.1 additions */ + G_UNICODE_SCRIPT_KAYAH_LI, /* Kali */ + G_UNICODE_SCRIPT_LEPCHA, /* Lepc */ + G_UNICODE_SCRIPT_REJANG, /* Rjng */ + G_UNICODE_SCRIPT_SUNDANESE, /* Sund */ + G_UNICODE_SCRIPT_SAURASHTRA, /* Saur */ + G_UNICODE_SCRIPT_CHAM, /* Cham */ + G_UNICODE_SCRIPT_OL_CHIKI, /* Olck */ + G_UNICODE_SCRIPT_VAI, /* Vaii */ + G_UNICODE_SCRIPT_CARIAN, /* Cari */ + G_UNICODE_SCRIPT_LYCIAN, /* Lyci */ + G_UNICODE_SCRIPT_LYDIAN, /* Lydi */ + + /* Unicode-5.2 additions */ + G_UNICODE_SCRIPT_AVESTAN, /* Avst */ + G_UNICODE_SCRIPT_BAMUM, /* Bamu */ + G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS, /* Egyp */ + G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC, /* Armi */ + G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI, /* Phli */ + G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN, /* Prti */ + G_UNICODE_SCRIPT_JAVANESE, /* Java */ + G_UNICODE_SCRIPT_KAITHI, /* Kthi */ + G_UNICODE_SCRIPT_LISU, /* Lisu */ + G_UNICODE_SCRIPT_MEETEI_MAYEK, /* Mtei */ + G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN, /* Sarb */ + G_UNICODE_SCRIPT_OLD_TURKIC, /* Orkh */ + G_UNICODE_SCRIPT_SAMARITAN, /* Samr */ + G_UNICODE_SCRIPT_TAI_THAM, /* Lana */ + G_UNICODE_SCRIPT_TAI_VIET, /* Tavt */ + + /* Unicode-6.0 additions */ + G_UNICODE_SCRIPT_BATAK, /* Batk */ + G_UNICODE_SCRIPT_BRAHMI, /* Brah */ + G_UNICODE_SCRIPT_MANDAIC, /* Mand */ + + /* Unicode-6.1 additions */ + G_UNICODE_SCRIPT_CHAKMA, /* Cakm */ + G_UNICODE_SCRIPT_MEROITIC_CURSIVE, /* Merc */ + G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS, /* Mero */ + G_UNICODE_SCRIPT_MIAO, /* Plrd */ + G_UNICODE_SCRIPT_SHARADA, /* Shrd */ + G_UNICODE_SCRIPT_SORA_SOMPENG, /* Sora */ + G_UNICODE_SCRIPT_TAKRI /* Takr */ +} GUnicodeScript; + +guint32 g_unicode_script_to_iso15924 (GUnicodeScript script); +GUnicodeScript g_unicode_script_from_iso15924 (guint32 iso15924); + +/* These are all analogs of the functions. + */ +gboolean g_unichar_isalnum (gunichar c) G_GNUC_CONST; +gboolean g_unichar_isalpha (gunichar c) G_GNUC_CONST; +gboolean g_unichar_iscntrl (gunichar c) G_GNUC_CONST; +gboolean g_unichar_isdigit (gunichar c) G_GNUC_CONST; +gboolean g_unichar_isgraph (gunichar c) G_GNUC_CONST; +gboolean g_unichar_islower (gunichar c) G_GNUC_CONST; +gboolean g_unichar_isprint (gunichar c) G_GNUC_CONST; +gboolean g_unichar_ispunct (gunichar c) G_GNUC_CONST; +gboolean g_unichar_isspace (gunichar c) G_GNUC_CONST; +gboolean g_unichar_isupper (gunichar c) G_GNUC_CONST; +gboolean g_unichar_isxdigit (gunichar c) G_GNUC_CONST; +gboolean g_unichar_istitle (gunichar c) G_GNUC_CONST; +gboolean g_unichar_isdefined (gunichar c) G_GNUC_CONST; +gboolean g_unichar_iswide (gunichar c) G_GNUC_CONST; +gboolean g_unichar_iswide_cjk(gunichar c) G_GNUC_CONST; +gboolean g_unichar_iszerowidth(gunichar c) G_GNUC_CONST; +gboolean g_unichar_ismark (gunichar c) G_GNUC_CONST; + +/* More functions. These convert between the three cases. + * See the Unicode book to understand title case. */ +gunichar g_unichar_toupper (gunichar c) G_GNUC_CONST; +gunichar g_unichar_tolower (gunichar c) G_GNUC_CONST; +gunichar g_unichar_totitle (gunichar c) G_GNUC_CONST; + +/* If C is a digit (according to `g_unichar_isdigit'), then return its + numeric value. Otherwise return -1. */ +gint g_unichar_digit_value (gunichar c) G_GNUC_CONST; + +gint g_unichar_xdigit_value (gunichar c) G_GNUC_CONST; + +/* Return the Unicode character type of a given character. */ +GUnicodeType g_unichar_type (gunichar c) G_GNUC_CONST; + +/* Return the line break property for a given character */ +GUnicodeBreakType g_unichar_break_type (gunichar c) G_GNUC_CONST; + +/* Returns the combining class for a given character */ +gint g_unichar_combining_class (gunichar uc) G_GNUC_CONST; + +gboolean g_unichar_get_mirror_char (gunichar ch, + gunichar *mirrored_ch); + +GUnicodeScript g_unichar_get_script (gunichar ch) G_GNUC_CONST; + +/* Validate a Unicode character */ +gboolean g_unichar_validate (gunichar ch) G_GNUC_CONST; + +/* Pairwise canonical compose/decompose */ +gboolean g_unichar_compose (gunichar a, + gunichar b, + gunichar *ch); +gboolean g_unichar_decompose (gunichar ch, + gunichar *a, + gunichar *b); + +gsize g_unichar_fully_decompose (gunichar ch, + gboolean compat, + gunichar *result, + gsize result_len); + +/** + * G_UNICHAR_MAX_DECOMPOSITION_LENGTH: + * + * The maximum length (in codepoints) of a compatibility or canonical + * decomposition of a single Unicode character. + * + * This is as defined by Unicode 6.1. + * + * Since: 2.32 + */ +#define G_UNICHAR_MAX_DECOMPOSITION_LENGTH 18 /* codepoints */ + +/* Compute canonical ordering of a string in-place. This rearranges + decomposed characters in the string according to their combining + classes. See the Unicode manual for more information. */ +void g_unicode_canonical_ordering (gunichar *string, + gsize len); + + +GLIB_DEPRECATED_IN_2_30 +gunichar *g_unicode_canonical_decomposition (gunichar ch, + gsize *result_len) G_GNUC_MALLOC; + +/* Array of skip-bytes-per-initial character. + */ +GLIB_VAR const gchar * const g_utf8_skip; + +/** + * g_utf8_next_char: + * @p: Pointer to the start of a valid UTF-8 character + * + * Skips to the next character in a UTF-8 string. The string must be + * valid; this macro is as fast as possible, and has no error-checking. + * You would use this macro to iterate over a string character by + * character. The macro returns the start of the next UTF-8 character. + * Before using this macro, use g_utf8_validate() to validate strings + * that may contain invalid UTF-8. + */ +#define g_utf8_next_char(p) (char *)((p) + g_utf8_skip[*(const guchar *)(p)]) + +gunichar g_utf8_get_char (const gchar *p) G_GNUC_PURE; +gunichar g_utf8_get_char_validated (const gchar *p, + gssize max_len) G_GNUC_PURE; + +gchar* g_utf8_offset_to_pointer (const gchar *str, + glong offset) G_GNUC_PURE; +glong g_utf8_pointer_to_offset (const gchar *str, + const gchar *pos) G_GNUC_PURE; +gchar* g_utf8_prev_char (const gchar *p) G_GNUC_PURE; +gchar* g_utf8_find_next_char (const gchar *p, + const gchar *end) G_GNUC_PURE; +gchar* g_utf8_find_prev_char (const gchar *str, + const gchar *p) G_GNUC_PURE; + +glong g_utf8_strlen (const gchar *p, + gssize max) G_GNUC_PURE; + +gchar *g_utf8_substring (const gchar *str, + glong start_pos, + glong end_pos) G_GNUC_MALLOC; + +gchar *g_utf8_strncpy (gchar *dest, + const gchar *src, + gsize n); + +/* Find the UTF-8 character corresponding to ch, in string p. These + functions are equivalants to strchr and strrchr */ +gchar* g_utf8_strchr (const gchar *p, + gssize len, + gunichar c); +gchar* g_utf8_strrchr (const gchar *p, + gssize len, + gunichar c); +gchar* g_utf8_strreverse (const gchar *str, + gssize len); + +gunichar2 *g_utf8_to_utf16 (const gchar *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) G_GNUC_MALLOC; +gunichar * g_utf8_to_ucs4 (const gchar *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) G_GNUC_MALLOC; +gunichar * g_utf8_to_ucs4_fast (const gchar *str, + glong len, + glong *items_written) G_GNUC_MALLOC; +gunichar * g_utf16_to_ucs4 (const gunichar2 *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) G_GNUC_MALLOC; +gchar* g_utf16_to_utf8 (const gunichar2 *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) G_GNUC_MALLOC; +gunichar2 *g_ucs4_to_utf16 (const gunichar *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) G_GNUC_MALLOC; +gchar* g_ucs4_to_utf8 (const gunichar *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) G_GNUC_MALLOC; + +gint g_unichar_to_utf8 (gunichar c, + gchar *outbuf); + +gboolean g_utf8_validate (const gchar *str, + gssize max_len, + const gchar **end); + +gchar *g_utf8_strup (const gchar *str, + gssize len) G_GNUC_MALLOC; +gchar *g_utf8_strdown (const gchar *str, + gssize len) G_GNUC_MALLOC; +gchar *g_utf8_casefold (const gchar *str, + gssize len) G_GNUC_MALLOC; + +/** + * GNormalizeMode: + * @G_NORMALIZE_DEFAULT: standardize differences that do not affect the + * text content, such as the above-mentioned accent representation + * @G_NORMALIZE_NFD: another name for %G_NORMALIZE_DEFAULT + * @G_NORMALIZE_DEFAULT_COMPOSE: like %G_NORMALIZE_DEFAULT, but with + * composed forms rather than a maximally decomposed form + * @G_NORMALIZE_NFC: another name for %G_NORMALIZE_DEFAULT_COMPOSE + * @G_NORMALIZE_ALL: beyond %G_NORMALIZE_DEFAULT also standardize the + * "compatibility" characters in Unicode, such as SUPERSCRIPT THREE + * to the standard forms (in this case DIGIT THREE). Formatting + * information may be lost but for most text operations such + * characters should be considered the same + * @G_NORMALIZE_NFKD: another name for %G_NORMALIZE_ALL + * @G_NORMALIZE_ALL_COMPOSE: like %G_NORMALIZE_ALL, but with composed + * forms rather than a maximally decomposed form + * @G_NORMALIZE_NFKC: another name for %G_NORMALIZE_ALL_COMPOSE + * + * Defines how a Unicode string is transformed in a canonical + * form, standardizing such issues as whether a character with + * an accent is represented as a base character and combining + * accent or as a single precomposed character. Unicode strings + * should generally be normalized before comparing them. + */ +typedef enum { + G_NORMALIZE_DEFAULT, + G_NORMALIZE_NFD = G_NORMALIZE_DEFAULT, + G_NORMALIZE_DEFAULT_COMPOSE, + G_NORMALIZE_NFC = G_NORMALIZE_DEFAULT_COMPOSE, + G_NORMALIZE_ALL, + G_NORMALIZE_NFKD = G_NORMALIZE_ALL, + G_NORMALIZE_ALL_COMPOSE, + G_NORMALIZE_NFKC = G_NORMALIZE_ALL_COMPOSE +} GNormalizeMode; + +gchar *g_utf8_normalize (const gchar *str, + gssize len, + GNormalizeMode mode) G_GNUC_MALLOC; + +gint g_utf8_collate (const gchar *str1, + const gchar *str2) G_GNUC_PURE; +gchar *g_utf8_collate_key (const gchar *str, + gssize len) G_GNUC_MALLOC; +gchar *g_utf8_collate_key_for_filename (const gchar *str, + gssize len) G_GNUC_MALLOC; + + +/* private */ + +gchar *_g_utf8_make_valid (const gchar *name); + +G_END_DECLS + +#endif /* __G_UNICODE_H__ */ diff --git a/glib/glib/gunicodeprivate.h b/glib/glib/gunicodeprivate.h new file mode 100644 index 0000000..c6cca84 --- /dev/null +++ b/glib/glib/gunicodeprivate.h @@ -0,0 +1,35 @@ +/* gunicodeprivate.h + * + * Copyright (C) 2003 Noah Levitt + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_UNICODE_PRIVATE_H__ +#define __G_UNICODE_PRIVATE_H__ + +#include "gtypes.h" + +G_BEGIN_DECLS + +G_GNUC_INTERNAL gunichar *_g_utf8_normalize_wc + (const gchar *str, + gssize max_len, + GNormalizeMode mode); + +G_END_DECLS + +#endif /* __G_UNICODE_PRIVATE_H__ */ diff --git a/glib/glib/gunicollate.c b/glib/glib/gunicollate.c new file mode 100644 index 0000000..3649786 --- /dev/null +++ b/glib/glib/gunicollate.c @@ -0,0 +1,683 @@ +/* gunicollate.c - Collation + * + * Copyright 2001,2005 Red Hat, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#ifdef __STDC_ISO_10646__ +#include +#endif + +#ifdef HAVE_CARBON +#include +#endif + +#include "gmem.h" +#include "gunicode.h" +#include "gunicodeprivate.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gcharset.h" +#ifndef __STDC_ISO_10646__ +#include "gconvert.h" +#endif + + +#ifdef _MSC_VER +/* Workaround for bug in MSVCR80.DLL */ +static gsize +msc_strxfrm_wrapper (char *string1, + const char *string2, + gsize count) +{ + if (!string1 || count <= 0) + { + char tmp; + + return strxfrm (&tmp, string2, 1); + } + return strxfrm (string1, string2, count); +} +#define strxfrm msc_strxfrm_wrapper +#endif + +/** + * g_utf8_collate: + * @str1: a UTF-8 encoded string + * @str2: a UTF-8 encoded string + * + * Compares two strings for ordering using the linguistically + * correct rules for the current locale. + * When sorting a large number of strings, it will be significantly + * faster to obtain collation keys with g_utf8_collate_key() and + * compare the keys with strcmp() when sorting instead of sorting + * the original strings. + * + * Return value: < 0 if @str1 compares before @str2, + * 0 if they compare equal, > 0 if @str1 compares after @str2. + **/ +gint +g_utf8_collate (const gchar *str1, + const gchar *str2) +{ + gint result; + +#ifdef HAVE_CARBON + + UniChar *str1_utf16; + UniChar *str2_utf16; + glong len1; + glong len2; + SInt32 retval = 0; + + g_return_val_if_fail (str1 != NULL, 0); + g_return_val_if_fail (str2 != NULL, 0); + + str1_utf16 = g_utf8_to_utf16 (str1, -1, NULL, &len1, NULL); + str2_utf16 = g_utf8_to_utf16 (str2, -1, NULL, &len2, NULL); + + UCCompareTextDefault (kUCCollateStandardOptions, + str1_utf16, len1, str2_utf16, len2, + NULL, &retval); + result = retval; + + g_free (str2_utf16); + g_free (str1_utf16); + +#elif defined(__STDC_ISO_10646__) + + gunichar *str1_norm; + gunichar *str2_norm; + + g_return_val_if_fail (str1 != NULL, 0); + g_return_val_if_fail (str2 != NULL, 0); + + str1_norm = _g_utf8_normalize_wc (str1, -1, G_NORMALIZE_ALL_COMPOSE); + str2_norm = _g_utf8_normalize_wc (str2, -1, G_NORMALIZE_ALL_COMPOSE); + + result = wcscoll ((wchar_t *)str1_norm, (wchar_t *)str2_norm); + + g_free (str1_norm); + g_free (str2_norm); + +#else /* !__STDC_ISO_10646__ */ + + const gchar *charset; + gchar *str1_norm; + gchar *str2_norm; + + g_return_val_if_fail (str1 != NULL, 0); + g_return_val_if_fail (str2 != NULL, 0); + + str1_norm = g_utf8_normalize (str1, -1, G_NORMALIZE_ALL_COMPOSE); + str2_norm = g_utf8_normalize (str2, -1, G_NORMALIZE_ALL_COMPOSE); + + if (g_get_charset (&charset)) + { + result = strcoll (str1_norm, str2_norm); + } + else + { + gchar *str1_locale = g_convert (str1_norm, -1, charset, "UTF-8", NULL, NULL, NULL); + gchar *str2_locale = g_convert (str2_norm, -1, charset, "UTF-8", NULL, NULL, NULL); + + if (str1_locale && str2_locale) + result = strcoll (str1_locale, str2_locale); + else if (str1_locale) + result = -1; + else if (str2_locale) + result = 1; + else + result = strcmp (str1_norm, str2_norm); + + g_free (str1_locale); + g_free (str2_locale); + } + + g_free (str1_norm); + g_free (str2_norm); + +#endif /* __STDC_ISO_10646__ */ + + return result; +} + +#if defined(__STDC_ISO_10646__) || defined(HAVE_CARBON) +/* We need UTF-8 encoding of numbers to encode the weights if + * we are using wcsxfrm. However, we aren't encoding Unicode + * characters, so we can't simply use g_unichar_to_utf8. + * + * The following routine is taken (with modification) from GNU + * libc's strxfrm routine: + * + * Copyright (C) 1995-1999,2000,2001 Free Software Foundation, Inc. + * Written by Ulrich Drepper , 1995. + */ +static inline int +utf8_encode (char *buf, wchar_t val) +{ + int retval; + + if (val < 0x80) + { + if (buf) + *buf++ = (char) val; + retval = 1; + } + else + { + int step; + + for (step = 2; step < 6; ++step) + if ((val & (~(guint32)0 << (5 * step + 1))) == 0) + break; + retval = step; + + if (buf) + { + *buf = (unsigned char) (~0xff >> step); + --step; + do + { + buf[step] = 0x80 | (val & 0x3f); + val >>= 6; + } + while (--step > 0); + *buf |= val; + } + } + + return retval; +} +#endif /* __STDC_ISO_10646__ || HAVE_CARBON */ + +#ifdef HAVE_CARBON + +static gchar * +collate_key_to_string (UCCollationValue *key, + gsize key_len) +{ + gchar *result; + gsize result_len; + gsize i; + + /* Pretty smart algorithm here: ignore first eight bytes of the + * collation key. It doesn't produce results equivalent to + * UCCompareCollationKeys's, but the difference seems to be only + * that UCCompareCollationKeys in some cases produces 0 where our + * comparison gets -1 or 1. */ + + if (key_len * sizeof (UCCollationValue) <= 8) + return g_strdup (""); + + result_len = 0; + for (i = 8; i < key_len * sizeof (UCCollationValue); i++) + /* there may be nul bytes, encode byteval+1 */ + result_len += utf8_encode (NULL, *((guchar*)key + i) + 1); + + result = g_malloc (result_len + 1); + result_len = 0; + for (i = 8; i < key_len * sizeof (UCCollationValue); i++) + result_len += utf8_encode (result + result_len, *((guchar*)key + i) + 1); + + result[result_len] = 0; + return result; +} + +static gchar * +carbon_collate_key_with_collator (const gchar *str, + gssize len, + CollatorRef collator) +{ + UniChar *str_utf16 = NULL; + glong len_utf16; + OSStatus ret; + UCCollationValue staticbuf[512]; + UCCollationValue *freeme = NULL; + UCCollationValue *buf; + ItemCount buf_len; + ItemCount key_len; + ItemCount try_len; + gchar *result = NULL; + + str_utf16 = g_utf8_to_utf16 (str, len, NULL, &len_utf16, NULL); + try_len = len_utf16 * 5 + 2; + + if (try_len <= sizeof staticbuf) + { + buf = staticbuf; + buf_len = sizeof staticbuf; + } + else + { + freeme = g_new (UCCollationValue, try_len); + buf = freeme; + buf_len = try_len; + } + + ret = UCGetCollationKey (collator, str_utf16, len_utf16, + buf_len, &key_len, buf); + + if (ret == kCollateBufferTooSmall) + { + freeme = g_renew (UCCollationValue, freeme, try_len * 2); + buf = freeme; + buf_len = try_len * 2; + ret = UCGetCollationKey (collator, str_utf16, len_utf16, + buf_len, &key_len, buf); + } + + if (ret == 0) + result = collate_key_to_string (buf, key_len); + else + result = g_strdup (""); + + g_free (freeme); + g_free (str_utf16); + return result; +} + +static gchar * +carbon_collate_key (const gchar *str, + gssize len) +{ + static CollatorRef collator; + + if (G_UNLIKELY (!collator)) + { + UCCreateCollator (NULL, 0, kUCCollateStandardOptions, &collator); + + if (!collator) + { + static gboolean been_here; + if (!been_here) + g_warning ("%s: UCCreateCollator failed", G_STRLOC); + been_here = TRUE; + return g_strdup (""); + } + } + + return carbon_collate_key_with_collator (str, len, collator); +} + +static gchar * +carbon_collate_key_for_filename (const gchar *str, + gssize len) +{ + static CollatorRef collator; + + if (G_UNLIKELY (!collator)) + { + /* http://developer.apple.com/qa/qa2004/qa1159.html */ + UCCreateCollator (NULL, 0, + kUCCollateComposeInsensitiveMask + | kUCCollateWidthInsensitiveMask + | kUCCollateCaseInsensitiveMask + | kUCCollateDigitsOverrideMask + | kUCCollateDigitsAsNumberMask + | kUCCollatePunctuationSignificantMask, + &collator); + + if (!collator) + { + static gboolean been_here; + if (!been_here) + g_warning ("%s: UCCreateCollator failed", G_STRLOC); + been_here = TRUE; + return g_strdup (""); + } + } + + return carbon_collate_key_with_collator (str, len, collator); +} + +#endif /* HAVE_CARBON */ + +/** + * g_utf8_collate_key: + * @str: a UTF-8 encoded string. + * @len: length of @str, in bytes, or -1 if @str is nul-terminated. + * + * Converts a string into a collation key that can be compared + * with other collation keys produced by the same function using + * strcmp(). + * + * The results of comparing the collation keys of two strings + * with strcmp() will always be the same as comparing the two + * original keys with g_utf8_collate(). + * + * Note that this function depends on the + * current locale. + * + * Return value: a newly allocated string. This string should + * be freed with g_free() when you are done with it. + **/ +gchar * +g_utf8_collate_key (const gchar *str, + gssize len) +{ + gchar *result; + +#ifdef HAVE_CARBON + + g_return_val_if_fail (str != NULL, NULL); + result = carbon_collate_key (str, len); + +#elif defined(__STDC_ISO_10646__) + + gsize xfrm_len; + gunichar *str_norm; + wchar_t *result_wc; + gsize i; + gsize result_len = 0; + + g_return_val_if_fail (str != NULL, NULL); + + str_norm = _g_utf8_normalize_wc (str, len, G_NORMALIZE_ALL_COMPOSE); + + xfrm_len = wcsxfrm (NULL, (wchar_t *)str_norm, 0); + result_wc = g_new (wchar_t, xfrm_len + 1); + wcsxfrm (result_wc, (wchar_t *)str_norm, xfrm_len + 1); + + for (i=0; i < xfrm_len; i++) + result_len += utf8_encode (NULL, result_wc[i]); + + result = g_malloc (result_len + 1); + result_len = 0; + for (i=0; i < xfrm_len; i++) + result_len += utf8_encode (result + result_len, result_wc[i]); + + result[result_len] = '\0'; + + g_free (result_wc); + g_free (str_norm); + + return result; +#else /* !__STDC_ISO_10646__ */ + + gsize xfrm_len; + const gchar *charset; + gchar *str_norm; + + g_return_val_if_fail (str != NULL, NULL); + + str_norm = g_utf8_normalize (str, len, G_NORMALIZE_ALL_COMPOSE); + + result = NULL; + + if (g_get_charset (&charset)) + { + xfrm_len = strxfrm (NULL, str_norm, 0); + if (xfrm_len >= 0 && xfrm_len < G_MAXINT - 2) + { + result = g_malloc (xfrm_len + 1); + strxfrm (result, str_norm, xfrm_len + 1); + } + } + else + { + gchar *str_locale = g_convert (str_norm, -1, charset, "UTF-8", NULL, NULL, NULL); + + if (str_locale) + { + xfrm_len = strxfrm (NULL, str_locale, 0); + if (xfrm_len < 0 || xfrm_len >= G_MAXINT - 2) + { + g_free (str_locale); + str_locale = NULL; + } + } + if (str_locale) + { + result = g_malloc (xfrm_len + 2); + result[0] = 'A'; + strxfrm (result + 1, str_locale, xfrm_len + 1); + + g_free (str_locale); + } + } + + if (!result) + { + xfrm_len = strlen (str_norm); + result = g_malloc (xfrm_len + 2); + result[0] = 'B'; + memcpy (result + 1, str_norm, xfrm_len); + result[xfrm_len+1] = '\0'; + } + + g_free (str_norm); +#endif /* __STDC_ISO_10646__ */ + + return result; +} + +/* This is a collation key that is very very likely to sort before any + collation key that libc strxfrm generates. We use this before any + special case (dot or number) to make sure that its sorted before + anything else. + */ +#define COLLATION_SENTINEL "\1\1\1" + +/** + * g_utf8_collate_key_for_filename: + * @str: a UTF-8 encoded string. + * @len: length of @str, in bytes, or -1 if @str is nul-terminated. + * + * Converts a string into a collation key that can be compared + * with other collation keys produced by the same function using strcmp(). + * + * In order to sort filenames correctly, this function treats the dot '.' + * as a special case. Most dictionary orderings seem to consider it + * insignificant, thus producing the ordering "event.c" "eventgenerator.c" + * "event.h" instead of "event.c" "event.h" "eventgenerator.c". Also, we + * would like to treat numbers intelligently so that "file1" "file10" "file5" + * is sorted as "file1" "file5" "file10". + * + * Note that this function depends on the + * current locale. + * + * Return value: a newly allocated string. This string should + * be freed with g_free() when you are done with it. + * + * Since: 2.8 + */ +gchar* +g_utf8_collate_key_for_filename (const gchar *str, + gssize len) +{ +#ifndef HAVE_CARBON + GString *result; + GString *append; + const gchar *p; + const gchar *prev; + const gchar *end; + gchar *collate_key; + gint digits; + gint leading_zeros; + + /* + * How it works: + * + * Split the filename into collatable substrings which do + * not contain [.0-9] and special-cased substrings. The collatable + * substrings are run through the normal g_utf8_collate_key() and the + * resulting keys are concatenated with keys generated from the + * special-cased substrings. + * + * Special cases: Dots are handled by replacing them with '\1' which + * implies that short dot-delimited substrings are before long ones, + * e.g. + * + * a\1a (a.a) + * a-\1a (a-.a) + * aa\1a (aa.a) + * + * Numbers are handled by prepending to each number d-1 superdigits + * where d = number of digits in the number and SUPERDIGIT is a + * character with an integer value higher than any digit (for instance + * ':'). This ensures that single-digit numbers are sorted before + * double-digit numbers which in turn are sorted separately from + * triple-digit numbers, etc. To avoid strange side-effects when + * sorting strings that already contain SUPERDIGITs, a '\2' + * is also prepended, like this + * + * file\21 (file1) + * file\25 (file5) + * file\2:10 (file10) + * file\2:26 (file26) + * file\2::100 (file100) + * file:foo (file:foo) + * + * This has the side-effect of sorting numbers before everything else (except + * dots), but this is probably OK. + * + * Leading digits are ignored when doing the above. To discriminate + * numbers which differ only in the number of leading digits, we append + * the number of leading digits as a byte at the very end of the collation + * key. + * + * To try avoid conflict with any collation key sequence generated by libc we + * start each switch to a special cased part with a sentinel that hopefully + * will sort before anything libc will generate. + */ + + if (len < 0) + len = strlen (str); + + result = g_string_sized_new (len * 2); + append = g_string_sized_new (0); + + end = str + len; + + /* No need to use utf8 functions, since we're only looking for ascii chars */ + for (prev = p = str; p < end; p++) + { + switch (*p) + { + case '.': + if (prev != p) + { + collate_key = g_utf8_collate_key (prev, p - prev); + g_string_append (result, collate_key); + g_free (collate_key); + } + + g_string_append (result, COLLATION_SENTINEL "\1"); + + /* skip the dot */ + prev = p + 1; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (prev != p) + { + collate_key = g_utf8_collate_key (prev, p - prev); + g_string_append (result, collate_key); + g_free (collate_key); + } + + g_string_append (result, COLLATION_SENTINEL "\2"); + + prev = p; + + /* write d-1 colons */ + if (*p == '0') + { + leading_zeros = 1; + digits = 0; + } + else + { + leading_zeros = 0; + digits = 1; + } + + while (++p < end) + { + if (*p == '0' && !digits) + ++leading_zeros; + else if (g_ascii_isdigit(*p)) + ++digits; + else + { + /* count an all-zero sequence as + * one digit plus leading zeros + */ + if (!digits) + { + ++digits; + --leading_zeros; + } + break; + } + } + + while (digits > 1) + { + g_string_append_c (result, ':'); + --digits; + } + + if (leading_zeros > 0) + { + g_string_append_c (append, (char)leading_zeros); + prev += leading_zeros; + } + + /* write the number itself */ + g_string_append_len (result, prev, p - prev); + + prev = p; + --p; /* go one step back to avoid disturbing outer loop */ + break; + + default: + /* other characters just accumulate */ + break; + } + } + + if (prev != p) + { + collate_key = g_utf8_collate_key (prev, p - prev); + g_string_append (result, collate_key); + g_free (collate_key); + } + + g_string_append (result, append->str); + g_string_free (append, TRUE); + + return g_string_free (result, FALSE); +#else /* HAVE_CARBON */ + return carbon_collate_key_for_filename (str, len); +#endif +} diff --git a/glib/glib/gunicomp.h b/glib/glib/gunicomp.h new file mode 100644 index 0000000..a686553 --- /dev/null +++ b/glib/glib/gunicomp.h @@ -0,0 +1,922 @@ +#define COMPOSE_FIRST_START 1 +#define COMPOSE_FIRST_SINGLE_START 147 +#define COMPOSE_SECOND_START 371 +#define COMPOSE_SECOND_SINGLE_START 402 + +#define COMPOSE_TABLE_LAST 272 + +static const guint16 compose_data[][256] = { + { /* page 0, index 0 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 148, 149, 0, 0, 1, 2, 3, 4, 5, + 150, 6, 7, 8, 151, 9, 10, 11, 12, 13, 14, 0, 15, 16, 17, 18, 19, 20, 21, + 22, 23, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 152, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 153, 154, + 50, 155, 0, 0, 51, 0, 0, 0, 0, 156, 0, 0, 0, 0, 52, 53, 157, 0, 158, 0, + 0, 0, 54, 0, 0, 0, 0, 0, 55, 0, 159, 160, 56, 161, 0, 0, 57, 0, 0, 0, 0, + 162, 0, 0, 0, 0, 58, 59, 163, 0, 164, 0, 0, 0, 60, 0, 0, 0 + }, + { /* page 1, index 1 */ + 0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 65, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 166, 0, + 0, 0, 0, 167, 168, 0, 0, 0, 0, 0, 0, 169, 170, 171, 172, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, + 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 0, 174, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 + }, + { /* page 2, index 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 178, 179, 180, 0, 0, 0, 0, + 181, 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 3, index 3 */ + 371, 372, 373, 374, 375, 0, 376, 377, 378, 379, 380, 381, 382, 0, 0, 383, + 0, 384, 0, 385, 386, 0, 0, 0, 0, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 388, + 389, 390, 391, 392, 393, 0, 0, 0, 0, 394, 395, 0, 396, 397, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 398, 0, 0, 399, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, + 72, 0, 73, 0, 74, 0, 0, 0, 0, 0, 75, 0, 184, 0, 0, 0, 76, 0, 0, 0, 77, 0, + 0, 185, 0, 186, 0, 0, 78, 0, 0, 0, 79, 0, 80, 0, 81, 0, 0, 0, 0, 0, 82, + 0, 83, 0, 0, 0, 84, 0, 0, 0, 85, 86, 87, 0, 0, 187, 0, 0, 0, 88, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 4, index 4 */ + 0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 189, 0, 90, + 91, 190, 92, 0, 191, 0, 0, 0, 192, 0, 0, 0, 0, 93, 0, 0, 0, 193, 0, 0, 0, + 194, 0, 195, 0, 0, 94, 0, 0, 196, 0, 95, 96, 197, 97, 0, 198, 0, 0, 0, + 199, 0, 0, 0, 0, 98, 0, 0, 0, 200, 0, 0, 0, 201, 0, 202, 0, 0, 0, 0, 0, + 0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 207, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 208, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 6, index 5 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 210, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 402, 403, 404, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, + 0, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 9, index 6 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, + 216, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 405, + 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 406, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 11, index 7 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 407, 0, 0, 0, 0, 0, 0, 0, 0, + 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 408, 409, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 410, 0, 0, 0, 0, 0, 0, 0, 102, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 12, index 8 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, + 0, 0, 412, 0, 0, 0, 103, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, + 414, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 13, index 9 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 415, 0, 0, 0, 0, 0, 0, 0, 104, + 223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 416, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 417, 0, 0, 0, 0, 418, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 105, 0, 0, 224, 0, 0, 419, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 16, index 10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 27, index 11 */ + 0, 0, 0, 0, 0, 226, 0, 227, 0, 228, 0, 229, 0, 230, 0, 0, 0, 231, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 233, 0, 234, 235, 0, 0, + 236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 30, index 12 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 237, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 240, 0, 0, + 0, 0, 0, 0, 241, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 244, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 246, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 31, index 13 */ + 108, 109, 247, 248, 249, 250, 251, 252, 110, 111, 253, 254, 255, 256, + 257, 258, 112, 113, 0, 0, 0, 0, 0, 0, 114, 115, 0, 0, 0, 0, 0, 0, 116, + 117, 259, 260, 261, 262, 263, 264, 118, 119, 265, 266, 267, 268, 269, + 270, 120, 121, 0, 0, 0, 0, 0, 0, 122, 123, 0, 0, 0, 0, 0, 0, 124, 125, 0, + 0, 0, 0, 0, 0, 126, 127, 0, 0, 0, 0, 0, 0, 128, 129, 0, 0, 0, 0, 0, 0, 0, + 130, 0, 0, 0, 0, 0, 0, 131, 132, 271, 272, 273, 274, 275, 276, 133, 134, + 277, 278, 279, 280, 281, 282, 283, 0, 0, 0, 284, 0, 0, 0, 0, 0, 0, 0, + 285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, + 0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, 136, 0 + }, + { /* page 33, index 14 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 289, 0, 290, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 292, 0, 293, 0, + 294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 34, index 15 */ + 0, 0, 0, 295, 0, 0, 0, 0, 296, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, 299, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 301, + 0, 302, 0, 0, 303, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 305, 0, 0, 306, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 308, 309, 0, 0, 310, 311, 0, 0, 312, 313, 314, 315, 0, 0, 0, 0, + 316, 317, 0, 0, 318, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 321, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 323, 324, 0, 325, + 0, 0, 0, 0, 0, 0, 326, 327, 328, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 48, index 16 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, + 0, 0, 0, 331, 0, 332, 0, 333, 0, 334, 0, 335, 0, 336, 0, 337, 0, 338, 0, + 339, 0, 340, 0, 341, 0, 342, 0, 0, 343, 0, 344, 0, 345, 0, 0, 0, 0, 0, 0, + 137, 0, 0, 138, 0, 0, 139, 0, 0, 140, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 400, 401, + 0, 0, 346, 0, 0, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 348, 0, 349, 0, 350, + 0, 351, 0, 352, 0, 353, 0, 354, 0, 355, 0, 356, 0, 357, 0, 358, 0, 359, + 0, 0, 360, 0, 361, 0, 362, 0, 0, 0, 0, 0, 0, 142, 0, 0, 143, 0, 0, 144, + 0, 0, 145, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 363, 364, 365, 366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 367, 0, 0 + }, + { /* page 272, index 17 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 368, 0, 369, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +static const gint16 compose_table[COMPOSE_TABLE_LAST + 1] = { + 0 /* page 0 */, + 1 /* page 1 */, + 2 /* page 2 */, + 3 /* page 3 */, + 4 /* page 4 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 5 /* page 6 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 6 /* page 9 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 7 /* page 11 */, + 8 /* page 12 */, + 9 /* page 13 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 10 /* page 16 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 11 /* page 27 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 12 /* page 30 */, + 13 /* page 31 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 14 /* page 33 */, + 15 /* page 34 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 16 /* page 48 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 17 /* page 272 */ +}; + +static const gunichar compose_first_single[][2] = { + { 0x0338, 0x226e }, + { 0x0338, 0x2260 }, + { 0x0338, 0x226f }, + { 0x0307, 0x1e1e }, + { 0x0302, 0x0134 }, + { 0x0307, 0x1e1f }, + { 0x0304, 0x01de }, + { 0x0301, 0x01fa }, + { 0x0301, 0x1e08 }, + { 0x0301, 0x1e2e }, + { 0x0304, 0x022a }, + { 0x0301, 0x01fe }, + { 0x0304, 0x01df }, + { 0x0301, 0x01fb }, + { 0x0301, 0x1e09 }, + { 0x0301, 0x1e2f }, + { 0x0304, 0x022b }, + { 0x0301, 0x01ff }, + { 0x0307, 0x1e64 }, + { 0x0307, 0x1e65 }, + { 0x0307, 0x1e66 }, + { 0x0307, 0x1e67 }, + { 0x0301, 0x1e78 }, + { 0x0301, 0x1e79 }, + { 0x0308, 0x1e7a }, + { 0x0308, 0x1e7b }, + { 0x0307, 0x1e9b }, + { 0x030c, 0x01ee }, + { 0x0304, 0x01ec }, + { 0x0304, 0x01ed }, + { 0x0304, 0x01e0 }, + { 0x0304, 0x01e1 }, + { 0x0306, 0x1e1c }, + { 0x0306, 0x1e1d }, + { 0x0304, 0x0230 }, + { 0x0304, 0x0231 }, + { 0x030c, 0x01ef }, + { 0x0314, 0x1fec }, + { 0x0345, 0x1fb4 }, + { 0x0345, 0x1fc4 }, + { 0x0345, 0x1ff4 }, + { 0x0308, 0x0407 }, + { 0x0301, 0x0403 }, + { 0x0308, 0x04de }, + { 0x0301, 0x040c }, + { 0x0308, 0x04e6 }, + { 0x0308, 0x04f4 }, + { 0x0308, 0x04f8 }, + { 0x0308, 0x04ec }, + { 0x0301, 0x0453 }, + { 0x0308, 0x04df }, + { 0x0301, 0x045c }, + { 0x0308, 0x04e7 }, + { 0x0308, 0x04f5 }, + { 0x0308, 0x04f9 }, + { 0x0308, 0x04ed }, + { 0x0308, 0x0457 }, + { 0x030f, 0x0476 }, + { 0x030f, 0x0477 }, + { 0x0308, 0x04da }, + { 0x0308, 0x04db }, + { 0x0308, 0x04ea }, + { 0x0308, 0x04eb }, + { 0x0654, 0x0624 }, + { 0x0654, 0x0626 }, + { 0x0654, 0x06c2 }, + { 0x0654, 0x06d3 }, + { 0x0654, 0x06c0 }, + { 0x093c, 0x0929 }, + { 0x093c, 0x0931 }, + { 0x093c, 0x0934 }, + { 0x0bd7, 0x0b94 }, + { 0x0bbe, 0x0bcb }, + { 0x0c56, 0x0c48 }, + { 0x0cd5, 0x0cc0 }, + { 0x0cd5, 0x0ccb }, + { 0x0d3e, 0x0d4b }, + { 0x0dca, 0x0ddd }, + { 0x102e, 0x1026 }, + { 0x1b35, 0x1b06 }, + { 0x1b35, 0x1b08 }, + { 0x1b35, 0x1b0a }, + { 0x1b35, 0x1b0c }, + { 0x1b35, 0x1b0e }, + { 0x1b35, 0x1b12 }, + { 0x1b35, 0x1b3b }, + { 0x1b35, 0x1b3d }, + { 0x1b35, 0x1b40 }, + { 0x1b35, 0x1b41 }, + { 0x1b35, 0x1b43 }, + { 0x0304, 0x1e38 }, + { 0x0304, 0x1e39 }, + { 0x0304, 0x1e5c }, + { 0x0304, 0x1e5d }, + { 0x0307, 0x1e68 }, + { 0x0307, 0x1e69 }, + { 0x0302, 0x1ec6 }, + { 0x0302, 0x1ec7 }, + { 0x0302, 0x1ed8 }, + { 0x0302, 0x1ed9 }, + { 0x0345, 0x1f82 }, + { 0x0345, 0x1f83 }, + { 0x0345, 0x1f84 }, + { 0x0345, 0x1f85 }, + { 0x0345, 0x1f86 }, + { 0x0345, 0x1f87 }, + { 0x0345, 0x1f8a }, + { 0x0345, 0x1f8b }, + { 0x0345, 0x1f8c }, + { 0x0345, 0x1f8d }, + { 0x0345, 0x1f8e }, + { 0x0345, 0x1f8f }, + { 0x0345, 0x1f92 }, + { 0x0345, 0x1f93 }, + { 0x0345, 0x1f94 }, + { 0x0345, 0x1f95 }, + { 0x0345, 0x1f96 }, + { 0x0345, 0x1f97 }, + { 0x0345, 0x1f9a }, + { 0x0345, 0x1f9b }, + { 0x0345, 0x1f9c }, + { 0x0345, 0x1f9d }, + { 0x0345, 0x1f9e }, + { 0x0345, 0x1f9f }, + { 0x0345, 0x1fa2 }, + { 0x0345, 0x1fa3 }, + { 0x0345, 0x1fa4 }, + { 0x0345, 0x1fa5 }, + { 0x0345, 0x1fa6 }, + { 0x0345, 0x1fa7 }, + { 0x0345, 0x1faa }, + { 0x0345, 0x1fab }, + { 0x0345, 0x1fac }, + { 0x0345, 0x1fad }, + { 0x0345, 0x1fae }, + { 0x0345, 0x1faf }, + { 0x0345, 0x1fb2 }, + { 0x0345, 0x1fc2 }, + { 0x0345, 0x1ff2 }, + { 0x0345, 0x1fb7 }, + { 0x0345, 0x1fc7 }, + { 0x0345, 0x1ff7 }, + { 0x0338, 0x219a }, + { 0x0338, 0x219b }, + { 0x0338, 0x21ae }, + { 0x0338, 0x21cd }, + { 0x0338, 0x21cf }, + { 0x0338, 0x21ce }, + { 0x0338, 0x2204 }, + { 0x0338, 0x2209 }, + { 0x0338, 0x220c }, + { 0x0338, 0x2224 }, + { 0x0338, 0x2226 }, + { 0x0338, 0x2241 }, + { 0x0338, 0x2244 }, + { 0x0338, 0x2247 }, + { 0x0338, 0x2249 }, + { 0x0338, 0x226d }, + { 0x0338, 0x2262 }, + { 0x0338, 0x2270 }, + { 0x0338, 0x2271 }, + { 0x0338, 0x2274 }, + { 0x0338, 0x2275 }, + { 0x0338, 0x2278 }, + { 0x0338, 0x2279 }, + { 0x0338, 0x2280 }, + { 0x0338, 0x2281 }, + { 0x0338, 0x22e0 }, + { 0x0338, 0x22e1 }, + { 0x0338, 0x2284 }, + { 0x0338, 0x2285 }, + { 0x0338, 0x2288 }, + { 0x0338, 0x2289 }, + { 0x0338, 0x22e2 }, + { 0x0338, 0x22e3 }, + { 0x0338, 0x22ac }, + { 0x0338, 0x22ad }, + { 0x0338, 0x22ae }, + { 0x0338, 0x22af }, + { 0x0338, 0x22ea }, + { 0x0338, 0x22eb }, + { 0x0338, 0x22ec }, + { 0x0338, 0x22ed }, + { 0x3099, 0x3094 }, + { 0x3099, 0x304c }, + { 0x3099, 0x304e }, + { 0x3099, 0x3050 }, + { 0x3099, 0x3052 }, + { 0x3099, 0x3054 }, + { 0x3099, 0x3056 }, + { 0x3099, 0x3058 }, + { 0x3099, 0x305a }, + { 0x3099, 0x305c }, + { 0x3099, 0x305e }, + { 0x3099, 0x3060 }, + { 0x3099, 0x3062 }, + { 0x3099, 0x3065 }, + { 0x3099, 0x3067 }, + { 0x3099, 0x3069 }, + { 0x3099, 0x309e }, + { 0x3099, 0x30f4 }, + { 0x3099, 0x30ac }, + { 0x3099, 0x30ae }, + { 0x3099, 0x30b0 }, + { 0x3099, 0x30b2 }, + { 0x3099, 0x30b4 }, + { 0x3099, 0x30b6 }, + { 0x3099, 0x30b8 }, + { 0x3099, 0x30ba }, + { 0x3099, 0x30bc }, + { 0x3099, 0x30be }, + { 0x3099, 0x30c0 }, + { 0x3099, 0x30c2 }, + { 0x3099, 0x30c5 }, + { 0x3099, 0x30c7 }, + { 0x3099, 0x30c9 }, + { 0x3099, 0x30f7 }, + { 0x3099, 0x30f8 }, + { 0x3099, 0x30f9 }, + { 0x3099, 0x30fa }, + { 0x3099, 0x30fe }, + { 0x110ba, 0x1109a }, + { 0x110ba, 0x1109c }, + { 0x110ba, 0x110ab } +}; +static const guint16 compose_second_single[][2] = { + { 0x0627, 0x0622 }, + { 0x0627, 0x0623 }, + { 0x0627, 0x0625 }, + { 0x09c7, 0x09cb }, + { 0x09c7, 0x09cc }, + { 0x0b47, 0x0b4b }, + { 0x0b47, 0x0b48 }, + { 0x0b47, 0x0b4c }, + { 0x0bc6, 0x0bca }, + { 0x0bc6, 0x0bcc }, + { 0x0cc6, 0x0cca }, + { 0x0cc6, 0x0cc7 }, + { 0x0cc6, 0x0cc8 }, + { 0x0d46, 0x0d4a }, + { 0x0d46, 0x0d4c }, + { 0x0dd9, 0x0dda }, + { 0x0dd9, 0x0ddc }, + { 0x0dd9, 0x0dde } +}; +static const guint16 compose_array[146][31] = { + { 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x0100, 0x0102, 0x0226, 0x00c4, 0x1ea2, 0x00c5, 0, 0x01cd, 0x0200, 0x0202, 0, 0, 0, 0x1ea0, 0, 0x1e00, 0, 0, 0x0104, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e04, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e06, 0, 0, 0, 0 }, + { 0, 0x0106, 0x0108, 0, 0, 0, 0x010a, 0, 0, 0, 0, 0x010c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00c7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e0a, 0, 0, 0, 0, 0x010e, 0, 0, 0, 0, 0, 0x1e0c, 0, 0, 0, 0x1e10, 0, 0x1e12, 0, 0, 0x1e0e, 0, 0, 0, 0 }, + { 0x00c8, 0x00c9, 0x00ca, 0x1ebc, 0x0112, 0x0114, 0x0116, 0x00cb, 0x1eba, 0, 0, 0x011a, 0x0204, 0x0206, 0, 0, 0, 0x1eb8, 0, 0, 0, 0x0228, 0x0118, 0x1e18, 0, 0x1e1a, 0, 0, 0, 0, 0 }, + { 0, 0x01f4, 0x011c, 0, 0x1e20, 0x011e, 0x0120, 0, 0, 0, 0, 0x01e6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0122, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0x0124, 0, 0, 0, 0x1e22, 0x1e26, 0, 0, 0, 0x021e, 0, 0, 0, 0, 0, 0x1e24, 0, 0, 0, 0x1e28, 0, 0, 0x1e2a, 0, 0, 0, 0, 0, 0 }, + { 0x00cc, 0x00cd, 0x00ce, 0x0128, 0x012a, 0x012c, 0x0130, 0x00cf, 0x1ec8, 0, 0, 0x01cf, 0x0208, 0x020a, 0, 0, 0, 0x1eca, 0, 0, 0, 0, 0x012e, 0, 0, 0x1e2c, 0, 0, 0, 0, 0 }, + { 0, 0x1e30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01e8, 0, 0, 0, 0, 0, 0x1e32, 0, 0, 0, 0x0136, 0, 0, 0, 0, 0x1e34, 0, 0, 0, 0 }, + { 0, 0x0139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x013d, 0, 0, 0, 0, 0, 0x1e36, 0, 0, 0, 0x013b, 0, 0x1e3c, 0, 0, 0x1e3a, 0, 0, 0, 0 }, + { 0, 0x1e3e, 0, 0, 0, 0, 0x1e40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x01f8, 0x0143, 0, 0x00d1, 0, 0, 0x1e44, 0, 0, 0, 0, 0x0147, 0, 0, 0, 0, 0, 0x1e46, 0, 0, 0, 0x0145, 0, 0x1e4a, 0, 0, 0x1e48, 0, 0, 0, 0 }, + { 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x014c, 0x014e, 0x022e, 0x00d6, 0x1ece, 0, 0x0150, 0x01d1, 0x020c, 0x020e, 0, 0, 0x01a0, 0x1ecc, 0, 0, 0, 0, 0x01ea, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e54, 0, 0, 0, 0, 0x1e56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x0154, 0, 0, 0, 0, 0x1e58, 0, 0, 0, 0, 0x0158, 0x0210, 0x0212, 0, 0, 0, 0x1e5a, 0, 0, 0, 0x0156, 0, 0, 0, 0, 0x1e5e, 0, 0, 0, 0 }, + { 0, 0x015a, 0x015c, 0, 0, 0, 0x1e60, 0, 0, 0, 0, 0x0160, 0, 0, 0, 0, 0, 0x1e62, 0, 0, 0x0218, 0x015e, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e6a, 0, 0, 0, 0, 0x0164, 0, 0, 0, 0, 0, 0x1e6c, 0, 0, 0x021a, 0x0162, 0, 0x1e70, 0, 0, 0x1e6e, 0, 0, 0, 0 }, + { 0x00d9, 0x00da, 0x00db, 0x0168, 0x016a, 0x016c, 0, 0x00dc, 0x1ee6, 0x016e, 0x0170, 0x01d3, 0x0214, 0x0216, 0, 0, 0x01af, 0x1ee4, 0x1e72, 0, 0, 0, 0x0172, 0x1e76, 0, 0x1e74, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0x1e7c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e7e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e80, 0x1e82, 0x0174, 0, 0, 0, 0x1e86, 0x1e84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e8a, 0x1e8c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ef2, 0x00dd, 0x0176, 0x1ef8, 0x0232, 0, 0x1e8e, 0x0178, 0x1ef6, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x0179, 0x1e90, 0, 0, 0, 0x017b, 0, 0, 0, 0, 0x017d, 0, 0, 0, 0, 0, 0x1e92, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e94, 0, 0, 0, 0 }, + { 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x0101, 0x0103, 0x0227, 0x00e4, 0x1ea3, 0x00e5, 0, 0x01ce, 0x0201, 0x0203, 0, 0, 0, 0x1ea1, 0, 0x1e01, 0, 0, 0x0105, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e03, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e05, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e07, 0, 0, 0, 0 }, + { 0, 0x0107, 0x0109, 0, 0, 0, 0x010b, 0, 0, 0, 0, 0x010d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x00e7, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e0b, 0, 0, 0, 0, 0x010f, 0, 0, 0, 0, 0, 0x1e0d, 0, 0, 0, 0x1e11, 0, 0x1e13, 0, 0, 0x1e0f, 0, 0, 0, 0 }, + { 0x00e8, 0x00e9, 0x00ea, 0x1ebd, 0x0113, 0x0115, 0x0117, 0x00eb, 0x1ebb, 0, 0, 0x011b, 0x0205, 0x0207, 0, 0, 0, 0x1eb9, 0, 0, 0, 0x0229, 0x0119, 0x1e19, 0, 0x1e1b, 0, 0, 0, 0, 0 }, + { 0, 0x01f5, 0x011d, 0, 0x1e21, 0x011f, 0x0121, 0, 0, 0, 0, 0x01e7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0123, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0x0125, 0, 0, 0, 0x1e23, 0x1e27, 0, 0, 0, 0x021f, 0, 0, 0, 0, 0, 0x1e25, 0, 0, 0, 0x1e29, 0, 0, 0x1e2b, 0, 0x1e96, 0, 0, 0, 0 }, + { 0x00ec, 0x00ed, 0x00ee, 0x0129, 0x012b, 0x012d, 0, 0x00ef, 0x1ec9, 0, 0, 0x01d0, 0x0209, 0x020b, 0, 0, 0, 0x1ecb, 0, 0, 0, 0, 0x012f, 0, 0, 0x1e2d, 0, 0, 0, 0, 0 }, + { 0, 0, 0x0135, 0, 0, 0, 0, 0, 0, 0, 0, 0x01f0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01e9, 0, 0, 0, 0, 0, 0x1e33, 0, 0, 0, 0x0137, 0, 0, 0, 0, 0x1e35, 0, 0, 0, 0 }, + { 0, 0x013a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x013e, 0, 0, 0, 0, 0, 0x1e37, 0, 0, 0, 0x013c, 0, 0x1e3d, 0, 0, 0x1e3b, 0, 0, 0, 0 }, + { 0, 0x1e3f, 0, 0, 0, 0, 0x1e41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x01f9, 0x0144, 0, 0x00f1, 0, 0, 0x1e45, 0, 0, 0, 0, 0x0148, 0, 0, 0, 0, 0, 0x1e47, 0, 0, 0, 0x0146, 0, 0x1e4b, 0, 0, 0x1e49, 0, 0, 0, 0 }, + { 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x014d, 0x014f, 0x022f, 0x00f6, 0x1ecf, 0, 0x0151, 0x01d2, 0x020d, 0x020f, 0, 0, 0x01a1, 0x1ecd, 0, 0, 0, 0, 0x01eb, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e55, 0, 0, 0, 0, 0x1e57, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x0155, 0, 0, 0, 0, 0x1e59, 0, 0, 0, 0, 0x0159, 0x0211, 0x0213, 0, 0, 0, 0x1e5b, 0, 0, 0, 0x0157, 0, 0, 0, 0, 0x1e5f, 0, 0, 0, 0 }, + { 0, 0x015b, 0x015d, 0, 0, 0, 0x1e61, 0, 0, 0, 0, 0x0161, 0, 0, 0, 0, 0, 0x1e63, 0, 0, 0x0219, 0x015f, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e6b, 0x1e97, 0, 0, 0, 0x0165, 0, 0, 0, 0, 0, 0x1e6d, 0, 0, 0x021b, 0x0163, 0, 0x1e71, 0, 0, 0x1e6f, 0, 0, 0, 0 }, + { 0x00f9, 0x00fa, 0x00fb, 0x0169, 0x016b, 0x016d, 0, 0x00fc, 0x1ee7, 0x016f, 0x0171, 0x01d4, 0x0215, 0x0217, 0, 0, 0x01b0, 0x1ee5, 0x1e73, 0, 0, 0, 0x0173, 0x1e77, 0, 0x1e75, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0x1e7d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e7f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e81, 0x1e83, 0x0175, 0, 0, 0, 0x1e87, 0x1e85, 0, 0x1e98, 0, 0, 0, 0, 0, 0, 0, 0x1e89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0x1e8b, 0x1e8d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ef3, 0x00fd, 0x0177, 0x1ef9, 0x0233, 0, 0x1e8f, 0x00ff, 0x1ef7, 0x1e99, 0, 0, 0, 0, 0, 0, 0, 0x1ef5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x017a, 0x1e91, 0, 0, 0, 0x017c, 0, 0, 0, 0, 0x017e, 0, 0, 0, 0, 0, 0x1e93, 0, 0, 0, 0, 0, 0, 0, 0, 0x1e95, 0, 0, 0, 0 }, + { 0x1fed, 0x0385, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fc1, 0, 0, 0 }, + { 0x1ea6, 0x1ea4, 0, 0x1eaa, 0, 0, 0, 0, 0x1ea8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x01fc, 0, 0, 0x01e2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ec0, 0x1ebe, 0, 0x1ec4, 0, 0, 0, 0, 0x1ec2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ed2, 0x1ed0, 0, 0x1ed6, 0, 0, 0, 0, 0x1ed4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e4c, 0, 0, 0x022c, 0, 0, 0x1e4e, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x01db, 0x01d7, 0, 0, 0x01d5, 0, 0, 0, 0, 0, 0, 0x01d9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ea7, 0x1ea5, 0, 0x1eab, 0, 0, 0, 0, 0x1ea9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x01fd, 0, 0, 0x01e3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ec1, 0x1ebf, 0, 0x1ec5, 0, 0, 0, 0, 0x1ec3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ed3, 0x1ed1, 0, 0x1ed7, 0, 0, 0, 0, 0x1ed5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0x1e4d, 0, 0, 0x022d, 0, 0, 0x1e4f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x01dc, 0x01d8, 0, 0, 0x01d6, 0, 0, 0, 0, 0, 0, 0x01da, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1eb0, 0x1eae, 0, 0x1eb4, 0, 0, 0, 0, 0x1eb2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1eb1, 0x1eaf, 0, 0x1eb5, 0, 0, 0, 0, 0x1eb3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e14, 0x1e16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e15, 0x1e17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e50, 0x1e52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1e51, 0x1e53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1edc, 0x1eda, 0, 0x1ee0, 0, 0, 0, 0, 0x1ede, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ee2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1edd, 0x1edb, 0, 0x1ee1, 0, 0, 0, 0, 0x1edf, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ee3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1eea, 0x1ee8, 0, 0x1eee, 0, 0, 0, 0, 0x1eec, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1eeb, 0x1ee9, 0, 0x1eef, 0, 0, 0, 0, 0x1eed, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ef1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1fba, 0x0386, 0, 0, 0x1fb9, 0x1fb8, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f08, 0x1f09, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fbc, 0, 0 }, + { 0x1fc8, 0x0388, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f18, 0x1f19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1fca, 0x0389, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f28, 0x1f29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fcc, 0, 0 }, + { 0x1fda, 0x038a, 0, 0, 0x1fd9, 0x1fd8, 0, 0x03aa, 0, 0, 0, 0, 0, 0, 0x1f38, 0x1f39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ff8, 0x038c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f48, 0x1f49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1fea, 0x038e, 0, 0, 0x1fe9, 0x1fe8, 0, 0x03ab, 0, 0, 0, 0, 0, 0, 0, 0x1f59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1ffa, 0x038f, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f68, 0x1f69, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ffc, 0, 0 }, + { 0x1f70, 0x03ac, 0, 0, 0x1fb1, 0x1fb0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f00, 0x1f01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fb6, 0x1fb3, 0, 0 }, + { 0x1f72, 0x03ad, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f10, 0x1f11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f74, 0x03ae, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f20, 0x1f21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fc6, 0x1fc3, 0, 0 }, + { 0x1f76, 0x03af, 0, 0, 0x1fd1, 0x1fd0, 0, 0x03ca, 0, 0, 0, 0, 0, 0, 0x1f30, 0x1f31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fd6, 0, 0, 0 }, + { 0x1f78, 0x03cc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f40, 0x1f41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fe4, 0x1fe5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f7a, 0x03cd, 0, 0, 0x1fe1, 0x1fe0, 0, 0x03cb, 0, 0, 0, 0, 0, 0, 0x1f50, 0x1f51, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fe6, 0, 0, 0 }, + { 0x1f7c, 0x03ce, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f60, 0x1f61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1ff6, 0x1ff3, 0, 0 }, + { 0x1fd2, 0x0390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fd7, 0, 0, 0 }, + { 0x1fe2, 0x03b0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fe7, 0, 0, 0 }, + { 0, 0x03d3, 0, 0, 0, 0, 0, 0x03d4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0x04d0, 0, 0x04d2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x0400, 0, 0, 0, 0, 0x04d6, 0, 0x0401, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0x04c1, 0, 0x04dc, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x040d, 0, 0, 0, 0x04e2, 0x0419, 0, 0x04e4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0x04ee, 0x040e, 0, 0x04f0, 0, 0, 0x04f2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0x04d1, 0, 0x04d3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x0450, 0, 0, 0, 0, 0x04d7, 0, 0x0451, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0x04c2, 0, 0x04dd, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x045d, 0, 0, 0, 0x04e3, 0x0439, 0, 0x04e5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0x04ef, 0x045e, 0, 0x04f1, 0, 0, 0x04f3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0x1eac, 0, 0, 0x1eb6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0x1ead, 0, 0, 0x1eb7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f02, 0x1f04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f06, 0x1f80, 0, 0 }, + { 0x1f03, 0x1f05, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f07, 0x1f81, 0, 0 }, + { 0x1f0a, 0x1f0c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f0e, 0x1f88, 0, 0 }, + { 0x1f0b, 0x1f0d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f0f, 0x1f89, 0, 0 }, + { 0x1f12, 0x1f14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f13, 0x1f15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f1a, 0x1f1c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f1b, 0x1f1d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f22, 0x1f24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f26, 0x1f90, 0, 0 }, + { 0x1f23, 0x1f25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f27, 0x1f91, 0, 0 }, + { 0x1f2a, 0x1f2c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f2e, 0x1f98, 0, 0 }, + { 0x1f2b, 0x1f2d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f2f, 0x1f99, 0, 0 }, + { 0x1f32, 0x1f34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f36, 0, 0, 0 }, + { 0x1f33, 0x1f35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f37, 0, 0, 0 }, + { 0x1f3a, 0x1f3c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f3e, 0, 0, 0 }, + { 0x1f3b, 0x1f3d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f3f, 0, 0, 0 }, + { 0x1f42, 0x1f44, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f43, 0x1f45, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f4a, 0x1f4c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f4b, 0x1f4d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0x1f52, 0x1f54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f56, 0, 0, 0 }, + { 0x1f53, 0x1f55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f57, 0, 0, 0 }, + { 0x1f5b, 0x1f5d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f5f, 0, 0, 0 }, + { 0x1f62, 0x1f64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f66, 0x1fa0, 0, 0 }, + { 0x1f63, 0x1f65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f67, 0x1fa1, 0, 0 }, + { 0x1f6a, 0x1f6c, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f6e, 0x1fa8, 0, 0 }, + { 0x1f6b, 0x1f6d, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1f6f, 0x1fa9, 0, 0 }, + { 0x1fcd, 0x1fce, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fcf, 0, 0, 0 }, + { 0x1fdd, 0x1fde, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1fdf, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3070, 0x3071 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3073, 0x3074 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3076, 0x3077 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3079, 0x307a }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x307c, 0x307d }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30d0, 0x30d1 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30d3, 0x30d4 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30d6, 0x30d7 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30d9, 0x30da }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x30dc, 0x30dd } +}; diff --git a/glib/glib/gunidecomp.c b/glib/glib/gunidecomp.c new file mode 100644 index 0000000..8ba24fd --- /dev/null +++ b/glib/glib/gunidecomp.c @@ -0,0 +1,751 @@ +/* decomp.c - Character decomposition. + * + * Copyright (C) 1999, 2000 Tom Tromey + * Copyright 2000 Red Hat, Inc. + * + * The Gnome Library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * The Gnome Library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the Gnome Library; see the file COPYING.LIB. If not, + * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/** + * SECTION:unicode + * @Title: Unicode Manipulation + * @Short_description: functions operating on Unicode characters and + * UTF-8 strings + * @See_also: g_locale_to_utf8(), g_locale_from_utf8() + * + * This section describes a number of functions for dealing with + * Unicode characters and strings. There are analogues of the + * traditional ctype.h character classification + * and case conversion functions, UTF-8 analogues of some string utility + * functions, functions to perform normalization, case conversion and + * collation on UTF-8 strings and finally functions to convert between + * the UTF-8, UTF-16 and UCS-4 encodings of Unicode. + * + * The implementations of the Unicode functions in GLib are based + * on the Unicode Character Data tables, which are available from + * www.unicode.org. + * GLib 2.8 supports Unicode 4.0, GLib 2.10 supports Unicode 4.1, + * GLib 2.12 supports Unicode 5.0, GLib 2.16.3 supports Unicode 5.1, + * GLib 2.30 supports Unicode 6.0. + */ + +#include "config.h" + +#include + +#include "gunicode.h" +#include "gunidecomp.h" +#include "gmem.h" +#include "gunicomp.h" +#include "gunicodeprivate.h" + + +#define CC_PART1(Page, Char) \ + ((combining_class_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (combining_class_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (cclass_data[combining_class_table_part1[Page]][Char])) + +#define CC_PART2(Page, Char) \ + ((combining_class_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (combining_class_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (cclass_data[combining_class_table_part2[Page]][Char])) + +#define COMBINING_CLASS(Char) \ + (((Char) <= G_UNICODE_LAST_CHAR_PART1) \ + ? CC_PART1 ((Char) >> 8, (Char) & 0xff) \ + : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \ + ? CC_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \ + : 0)) + +/** + * g_unichar_combining_class: + * @uc: a Unicode character + * + * Determines the canonical combining class of a Unicode character. + * + * Return value: the combining class of the character + * + * Since: 2.14 + **/ +gint +g_unichar_combining_class (gunichar uc) +{ + return COMBINING_CLASS (uc); +} + +/* constants for hangul syllable [de]composition */ +#define SBase 0xAC00 +#define LBase 0x1100 +#define VBase 0x1161 +#define TBase 0x11A7 +#define LCount 19 +#define VCount 21 +#define TCount 28 +#define NCount (VCount * TCount) +#define SCount (LCount * NCount) + +/** + * g_unicode_canonical_ordering: + * @string: a UCS-4 encoded string. + * @len: the maximum length of @string to use. + * + * Computes the canonical ordering of a string in-place. + * This rearranges decomposed characters in the string + * according to their combining classes. See the Unicode + * manual for more information. + **/ +void +g_unicode_canonical_ordering (gunichar *string, + gsize len) +{ + gsize i; + int swap = 1; + + while (swap) + { + int last; + swap = 0; + last = COMBINING_CLASS (string[0]); + for (i = 0; i < len - 1; ++i) + { + int next = COMBINING_CLASS (string[i + 1]); + if (next != 0 && last > next) + { + gsize j; + /* Percolate item leftward through string. */ + for (j = i + 1; j > 0; --j) + { + gunichar t; + if (COMBINING_CLASS (string[j - 1]) <= next) + break; + t = string[j]; + string[j] = string[j - 1]; + string[j - 1] = t; + swap = 1; + } + /* We're re-entering the loop looking at the old + character again. */ + next = last; + } + last = next; + } + } +} + +/* http://www.unicode.org/unicode/reports/tr15/#Hangul + * r should be null or have sufficient space. Calling with r == NULL will + * only calculate the result_len; however, a buffer with space for three + * characters will always be big enough. */ +static void +decompose_hangul (gunichar s, + gunichar *r, + gsize *result_len) +{ + gint SIndex = s - SBase; + gint TIndex = SIndex % TCount; + + if (r) + { + r[0] = LBase + SIndex / NCount; + r[1] = VBase + (SIndex % NCount) / TCount; + } + + if (TIndex) + { + if (r) + r[2] = TBase + TIndex; + *result_len = 3; + } + else + *result_len = 2; +} + +/* returns a pointer to a null-terminated UTF-8 string */ +static const gchar * +find_decomposition (gunichar ch, + gboolean compat) +{ + int start = 0; + int end = G_N_ELEMENTS (decomp_table); + + if (ch >= decomp_table[start].ch && + ch <= decomp_table[end - 1].ch) + { + while (TRUE) + { + int half = (start + end) / 2; + if (ch == decomp_table[half].ch) + { + int offset; + + if (compat) + { + offset = decomp_table[half].compat_offset; + if (offset == G_UNICODE_NOT_PRESENT_OFFSET) + offset = decomp_table[half].canon_offset; + } + else + { + offset = decomp_table[half].canon_offset; + if (offset == G_UNICODE_NOT_PRESENT_OFFSET) + return NULL; + } + + return &(decomp_expansion_string[offset]); + } + else if (half == start) + break; + else if (ch > decomp_table[half].ch) + start = half; + else + end = half; + } + } + + return NULL; +} + +/** + * g_unicode_canonical_decomposition: + * @ch: a Unicode character. + * @result_len: location to store the length of the return value. + * + * Computes the canonical decomposition of a Unicode character. + * + * Return value: a newly allocated string of Unicode characters. + * @result_len is set to the resulting length of the string. + * + * Deprecated: 2.30: Use the more flexible g_unichar_fully_decompose() + * instead. + **/ +gunichar * +g_unicode_canonical_decomposition (gunichar ch, + gsize *result_len) +{ + const gchar *decomp; + const gchar *p; + gunichar *r; + + /* Hangul syllable */ + if (ch >= SBase && ch < SBase + SCount) + { + decompose_hangul (ch, NULL, result_len); + r = g_malloc (*result_len * sizeof (gunichar)); + decompose_hangul (ch, r, result_len); + } + else if ((decomp = find_decomposition (ch, FALSE)) != NULL) + { + /* Found it. */ + int i; + + *result_len = g_utf8_strlen (decomp, -1); + r = g_malloc (*result_len * sizeof (gunichar)); + + for (p = decomp, i = 0; *p != '\0'; p = g_utf8_next_char (p), i++) + r[i] = g_utf8_get_char (p); + } + else + { + /* Not in our table. */ + r = g_malloc (sizeof (gunichar)); + *r = ch; + *result_len = 1; + } + + return r; +} + +/* L,V => LV and LV,T => LVT */ +static gboolean +combine_hangul (gunichar a, + gunichar b, + gunichar *result) +{ + gint LIndex = a - LBase; + gint SIndex = a - SBase; + + gint VIndex = b - VBase; + gint TIndex = b - TBase; + + if (0 <= LIndex && LIndex < LCount + && 0 <= VIndex && VIndex < VCount) + { + *result = SBase + (LIndex * VCount + VIndex) * TCount; + return TRUE; + } + else if (0 <= SIndex && SIndex < SCount && (SIndex % TCount) == 0 + && 0 < TIndex && TIndex < TCount) + { + *result = a + TIndex; + return TRUE; + } + + return FALSE; +} + +#define CI(Page, Char) \ + ((compose_table[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (compose_table[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (compose_data[compose_table[Page]][Char])) + +#define COMPOSE_INDEX(Char) \ + (((Char >> 8) > (COMPOSE_TABLE_LAST)) ? 0 : CI((Char) >> 8, (Char) & 0xff)) + +static gboolean +combine (gunichar a, + gunichar b, + gunichar *result) +{ + gushort index_a, index_b; + + if (combine_hangul (a, b, result)) + return TRUE; + + index_a = COMPOSE_INDEX(a); + + if (index_a >= COMPOSE_FIRST_SINGLE_START && index_a < COMPOSE_SECOND_START) + { + if (b == compose_first_single[index_a - COMPOSE_FIRST_SINGLE_START][0]) + { + *result = compose_first_single[index_a - COMPOSE_FIRST_SINGLE_START][1]; + return TRUE; + } + else + return FALSE; + } + + index_b = COMPOSE_INDEX(b); + + if (index_b >= COMPOSE_SECOND_SINGLE_START) + { + if (a == compose_second_single[index_b - COMPOSE_SECOND_SINGLE_START][0]) + { + *result = compose_second_single[index_b - COMPOSE_SECOND_SINGLE_START][1]; + return TRUE; + } + else + return FALSE; + } + + if (index_a >= COMPOSE_FIRST_START && index_a < COMPOSE_FIRST_SINGLE_START && + index_b >= COMPOSE_SECOND_START && index_b < COMPOSE_SECOND_SINGLE_START) + { + gunichar res = compose_array[index_a - COMPOSE_FIRST_START][index_b - COMPOSE_SECOND_START]; + + if (res) + { + *result = res; + return TRUE; + } + } + + return FALSE; +} + +gunichar * +_g_utf8_normalize_wc (const gchar *str, + gssize max_len, + GNormalizeMode mode) +{ + gsize n_wc; + gunichar *wc_buffer; + const char *p; + gsize last_start; + gboolean do_compat = (mode == G_NORMALIZE_NFKC || + mode == G_NORMALIZE_NFKD); + gboolean do_compose = (mode == G_NORMALIZE_NFC || + mode == G_NORMALIZE_NFKC); + + n_wc = 0; + p = str; + while ((max_len < 0 || p < str + max_len) && *p) + { + const gchar *decomp; + gunichar wc = g_utf8_get_char (p); + + if (wc >= SBase && wc < SBase + SCount) + { + gsize result_len; + decompose_hangul (wc, NULL, &result_len); + n_wc += result_len; + } + else + { + decomp = find_decomposition (wc, do_compat); + + if (decomp) + n_wc += g_utf8_strlen (decomp, -1); + else + n_wc++; + } + + p = g_utf8_next_char (p); + } + + wc_buffer = g_new (gunichar, n_wc + 1); + + last_start = 0; + n_wc = 0; + p = str; + while ((max_len < 0 || p < str + max_len) && *p) + { + gunichar wc = g_utf8_get_char (p); + const gchar *decomp; + int cc; + gsize old_n_wc = n_wc; + + if (wc >= SBase && wc < SBase + SCount) + { + gsize result_len; + decompose_hangul (wc, wc_buffer + n_wc, &result_len); + n_wc += result_len; + } + else + { + decomp = find_decomposition (wc, do_compat); + + if (decomp) + { + const char *pd; + for (pd = decomp; *pd != '\0'; pd = g_utf8_next_char (pd)) + wc_buffer[n_wc++] = g_utf8_get_char (pd); + } + else + wc_buffer[n_wc++] = wc; + } + + if (n_wc > 0) + { + cc = COMBINING_CLASS (wc_buffer[old_n_wc]); + + if (cc == 0) + { + g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start); + last_start = old_n_wc; + } + } + + p = g_utf8_next_char (p); + } + + if (n_wc > 0) + { + g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start); + last_start = n_wc; + } + + wc_buffer[n_wc] = 0; + + /* All decomposed and reordered */ + + if (do_compose && n_wc > 0) + { + gsize i, j; + int last_cc = 0; + last_start = 0; + + for (i = 0; i < n_wc; i++) + { + int cc = COMBINING_CLASS (wc_buffer[i]); + + if (i > 0 && + (last_cc == 0 || last_cc < cc) && + combine (wc_buffer[last_start], wc_buffer[i], + &wc_buffer[last_start])) + { + for (j = i + 1; j < n_wc; j++) + wc_buffer[j-1] = wc_buffer[j]; + n_wc--; + i--; + + if (i == last_start) + last_cc = 0; + else + last_cc = COMBINING_CLASS (wc_buffer[i-1]); + + continue; + } + + if (cc == 0) + last_start = i; + + last_cc = cc; + } + } + + wc_buffer[n_wc] = 0; + + return wc_buffer; +} + +/** + * g_utf8_normalize: + * @str: a UTF-8 encoded string. + * @len: length of @str, in bytes, or -1 if @str is nul-terminated. + * @mode: the type of normalization to perform. + * + * Converts a string into canonical form, standardizing + * such issues as whether a character with an accent + * is represented as a base character and combining + * accent or as a single precomposed character. The + * string has to be valid UTF-8, otherwise %NULL is + * returned. You should generally call g_utf8_normalize() + * before comparing two Unicode strings. + * + * The normalization mode %G_NORMALIZE_DEFAULT only + * standardizes differences that do not affect the + * text content, such as the above-mentioned accent + * representation. %G_NORMALIZE_ALL also standardizes + * the "compatibility" characters in Unicode, such + * as SUPERSCRIPT THREE to the standard forms + * (in this case DIGIT THREE). Formatting information + * may be lost but for most text operations such + * characters should be considered the same. + * + * %G_NORMALIZE_DEFAULT_COMPOSE and %G_NORMALIZE_ALL_COMPOSE + * are like %G_NORMALIZE_DEFAULT and %G_NORMALIZE_ALL, + * but returned a result with composed forms rather + * than a maximally decomposed form. This is often + * useful if you intend to convert the string to + * a legacy encoding or pass it to a system with + * less capable Unicode handling. + * + * Return value: a newly allocated string, that is the + * normalized form of @str, or %NULL if @str is not + * valid UTF-8. + **/ +gchar * +g_utf8_normalize (const gchar *str, + gssize len, + GNormalizeMode mode) +{ + gunichar *result_wc = _g_utf8_normalize_wc (str, len, mode); + gchar *result; + + result = g_ucs4_to_utf8 (result_wc, -1, NULL, NULL, NULL); + g_free (result_wc); + + return result; +} + +static gboolean +decompose_hangul_step (gunichar ch, + gunichar *a, + gunichar *b) +{ + gint SIndex, TIndex; + + if (ch < SBase || ch >= SBase + SCount) + return FALSE; /* not a hangul syllable */ + + SIndex = ch - SBase; + TIndex = SIndex % TCount; + + if (TIndex) + { + /* split LVT -> LV,T */ + *a = ch - TIndex; + *b = TBase + TIndex; + } + else + { + /* split LV -> L,V */ + *a = LBase + SIndex / NCount; + *b = VBase + (SIndex % NCount) / TCount; + } + + return TRUE; +} + +/** + * g_unichar_decompose: + * @ch: a Unicode character + * @a: return location for the first component of @ch + * @b: return location for the second component of @ch + * + * Performs a single decomposition step of the + * Unicode canonical decomposition algorithm. + * + * This function does not include compatibility + * decompositions. It does, however, include algorithmic + * Hangul Jamo decomposition, as well as 'singleton' + * decompositions which replace a character by a single + * other character. In the case of singletons *@b will + * be set to zero. + * + * If @ch is not decomposable, *@a is set to @ch and *@b + * is set to zero. + * + * Note that the way Unicode decomposition pairs are + * defined, it is guaranteed that @b would not decompose + * further, but @a may itself decompose. To get the full + * canonical decomposition for @ch, one would need to + * recursively call this function on @a. Or use + * g_unichar_fully_decompose(). + * + * See UAX#15 + * for details. + * + * Returns: %TRUE if the character could be decomposed + * + * Since: 2.30 + */ +gboolean +g_unichar_decompose (gunichar ch, + gunichar *a, + gunichar *b) +{ + gint start = 0; + gint end = G_N_ELEMENTS (decomp_step_table); + + if (decompose_hangul_step (ch, a, b)) + return TRUE; + + /* TODO use bsearch() */ + if (ch >= decomp_step_table[start].ch && + ch <= decomp_step_table[end - 1].ch) + { + while (TRUE) + { + gint half = (start + end) / 2; + const decomposition_step *p = &(decomp_step_table[half]); + if (ch == p->ch) + { + *a = p->a; + *b = p->b; + return TRUE; + } + else if (half == start) + break; + else if (ch > p->ch) + start = half; + else + end = half; + } + } + + *a = ch; + *b = 0; + + return FALSE; +} + +/** + * g_unichar_compose: + * @a: a Unicode character + * @b: a Unicode character + * @ch: return location for the composed character + * + * Performs a single composition step of the + * Unicode canonical composition algorithm. + * + * This function includes algorithmic Hangul Jamo composition, + * but it is not exactly the inverse of g_unichar_decompose(). + * No composition can have either of @a or @b equal to zero. + * To be precise, this function composes if and only if + * there exists a Primary Composite P which is canonically + * equivalent to the sequence <@a,@b>. See the Unicode + * Standard for the definition of Primary Composite. + * + * If @a and @b do not compose a new character, @ch is set to zero. + * + * See UAX#15 + * for details. + * + * Returns: %TRUE if the characters could be composed + * + * Since: 2.30 + */ +gboolean +g_unichar_compose (gunichar a, + gunichar b, + gunichar *ch) +{ + if (combine (a, b, ch)) + return TRUE; + + *ch = 0; + return FALSE; +} + +/** + * g_unichar_fully_decompose: + * @ch: a Unicode character. + * @compat: whether perform canonical or compatibility decomposition + * @result: location to store decomposed result, or %NULL + * @result_len: length of @result + * + * Computes the canonical or compatibility decomposition of a + * Unicode character. For compatibility decomposition, + * pass %TRUE for @compat; for canonical decomposition + * pass %FALSE for @compat. + * + * The decomposed sequence is placed in @result. Only up to + * @result_len characters are written into @result. The length + * of the full decomposition (irrespective of @result_len) is + * returned by the function. For canonical decomposition, + * currently all decompositions are of length at most 4, but + * this may change in the future (very unlikely though). + * At any rate, Unicode does guarantee that a buffer of length + * 18 is always enough for both compatibility and canonical + * decompositions, so that is the size recommended. This is provided + * as %G_UNICHAR_MAX_DECOMPOSITION_LENGTH. + * + * See UAX#15 + * for details. + * + * Return value: the length of the full decomposition. + * + * Since: 2.30 + **/ +gsize +g_unichar_fully_decompose (gunichar ch, + gboolean compat, + gunichar *result, + gsize result_len) +{ + const gchar *decomp; + const gchar *p; + + /* Hangul syllable */ + if (ch >= SBase && ch < SBase + SCount) + { + gsize len, i; + gunichar buffer[3]; + decompose_hangul (ch, result ? buffer : NULL, &len); + if (result) + for (i = 0; i < len && i < result_len; i++) + result[i] = buffer[i]; + return len; + } + else if ((decomp = find_decomposition (ch, compat)) != NULL) + { + /* Found it. */ + gsize len, i; + + len = g_utf8_strlen (decomp, -1); + + for (p = decomp, i = 0; i < len && i < result_len; p = g_utf8_next_char (p), i++) + result[i] = g_utf8_get_char (p); + + return len; + } + + /* Does not decompose */ + if (result && result_len >= 1) + *result = ch; + return 1; +} diff --git a/glib/glib/gunidecomp.h b/glib/glib/gunidecomp.h new file mode 100644 index 0000000..cf41100 --- /dev/null +++ b/glib/glib/gunidecomp.h @@ -0,0 +1,13321 @@ +/* This file is automatically generated. DO NOT EDIT! */ + +#ifndef DECOMP_H +#define DECOMP_H + +#define G_UNICODE_LAST_CHAR 0x10ffff + +#define G_UNICODE_MAX_TABLE_INDEX (0x110000 / 256) + +#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF + +#define G_UNICODE_LAST_PAGE_PART1 762 + +#define G_UNICODE_NOT_PRESENT_OFFSET 65535 + +static const guchar cclass_data[][256] = { + { /* page 3, index 0 */ + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, + 220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, + 220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, + 220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, + 220, 220, 230, 230, 230, 220, 220, 0, 230, 230, 230, 220, 220, 220, 220, + 230, 232, 220, 220, 230, 233, 234, 234, 233, 234, 234, 233, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 4, index 1 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 5, index 2 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, + 230, 230, 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, + 222, 228, 230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, + 23, 0, 24, 25, 0, 230, 220, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 6, index 3 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, + 230, 230, 230, 30, 31, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34, 230, 230, 220, + 220, 230, 230, 230, 230, 230, 220, 230, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, + 230, 0, 0, 230, 230, 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, + 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 7, index 4 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, + 220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, + 220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 8, index 5 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, + 230, 230, 230, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 230, + 230, 230, 0, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 9, index 6 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 10, index 7 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 11, index 8 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 12, index 9 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 13, index 10 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 14, index 11 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 15, index 12 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 220, 0, 220, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 130, 0, + 132, 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0, 130, 0, 230, 230, 9, 0, + 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 + }, + { /* page 16, index 13 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 19, index 14 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 23, index 15 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 24, index 16 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 25, index 17 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 26, index 18 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, + 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, + 230, 230, 230, 230, 230, 230, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 27, index 19 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230, 230, 230, 230, + 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 28, index 20 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 0, 1, 220, + 220, 220, 220, 220, 230, 230, 220, 220, 220, 220, 230, 0, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0 + }, + { /* page 29, index 21 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 230, 230, 220, 230, 230, 230, 230, 230, 230, 230, 220, 230, 230, 234, + 214, 220, 202, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, 220, 230, 220 + }, + { /* page 32, index 22 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 1, 1, 230, 230, + 230, 230, 1, 1, 1, 230, 230, 0, 0, 0, 0, 230, 0, 0, 0, 1, 1, 230, 220, + 230, 1, 1, 220, 220, 220, 220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 + }, + { /* page 44, index 23 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, + 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 45, index 24 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230 + }, + { /* page 48, index 25 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 228, 232, 222, + 224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 166, index 26 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 168, index 27 */ + 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, + 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0 + }, + { /* page 169, index 28 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 170, index 29 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 230, 230, 220, 0, 0, 230, 230, 0, 0, 0, + 0, 0, 230, 230, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 171, index 30 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 251, index 31 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 254, index 32 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 257, index 33 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0 + }, + { /* page 266, index 34 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 230, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 1, 220, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 272, index 35 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 7, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 465, index 36 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216, 216, 216, 216, + 0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, 220, 220, 0, 0, + 230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0 + }, + { /* page 466, index 37 */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + } +}; + +static const gint16 combining_class_table_part1[763] = { + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 /* page 3 */, + 1 /* page 4 */, + 2 /* page 5 */, + 3 /* page 6 */, + 4 /* page 7 */, + 5 /* page 8 */, + 6 /* page 9 */, + 7 /* page 10 */, + 8 /* page 11 */, + 9 /* page 12 */, + 10 /* page 13 */, + 11 /* page 14 */, + 12 /* page 15 */, + 13 /* page 16 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 14 /* page 19 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 15 /* page 23 */, + 16 /* page 24 */, + 17 /* page 25 */, + 18 /* page 26 */, + 19 /* page 27 */, + 20 /* page 28 */, + 21 /* page 29 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 22 /* page 32 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 23 /* page 44 */, + 24 /* page 45 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 25 /* page 48 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 26 /* page 166 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 27 /* page 168 */, + 28 /* page 169 */, + 29 /* page 170 */, + 30 /* page 171 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 31 /* page 251 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 32 /* page 254 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 33 /* page 257 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 34 /* page 266 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 35 /* page 272 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 36 /* page 465 */, + 37 /* page 466 */, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX +}; + +static const gint16 combining_class_table_part2[768] = { + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX, + 0 + G_UNICODE_MAX_TABLE_INDEX +}; + +typedef struct +{ + gunichar ch; + guint16 canon_offset; + guint16 compat_offset; +} decomposition; + +static const decomposition decomp_table[] = +{ + { 0x00a0, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x00a8, G_UNICODE_NOT_PRESENT_OFFSET, 2 }, + { 0x00aa, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x00af, G_UNICODE_NOT_PRESENT_OFFSET, 8 }, + { 0x00b2, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0x00b3, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0x00b4, G_UNICODE_NOT_PRESENT_OFFSET, 16 }, + { 0x00b5, G_UNICODE_NOT_PRESENT_OFFSET, 20 }, + { 0x00b8, G_UNICODE_NOT_PRESENT_OFFSET, 23 }, + { 0x00b9, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0x00ba, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x00bc, G_UNICODE_NOT_PRESENT_OFFSET, 31 }, + { 0x00bd, G_UNICODE_NOT_PRESENT_OFFSET, 37 }, + { 0x00be, G_UNICODE_NOT_PRESENT_OFFSET, 43 }, + { 0x00c0, 49, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00c1, 53, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00c2, 57, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00c3, 61, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00c4, 65, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00c5, 69, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00c7, 73, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00c8, 77, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00c9, 81, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00ca, 85, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00cb, 89, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00cc, 93, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00cd, 97, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00ce, 101, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00cf, 105, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00d1, 109, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00d2, 113, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00d3, 117, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00d4, 121, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00d5, 125, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00d6, 129, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00d9, 133, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00da, 137, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00db, 141, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00dc, 145, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00dd, 149, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e0, 153, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e1, 157, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e2, 161, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e3, 165, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e4, 169, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e5, 173, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e7, 177, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e8, 181, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00e9, 185, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00ea, 189, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00eb, 193, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00ec, 197, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00ed, 201, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00ee, 205, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00ef, 209, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00f1, 213, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00f2, 217, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00f3, 221, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00f4, 225, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00f5, 229, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00f6, 233, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00f9, 237, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00fa, 241, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00fb, 245, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00fc, 249, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00fd, 253, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x00ff, 257, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0100, 261, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0101, 265, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0102, 269, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0103, 273, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0104, 277, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0105, 281, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0106, 285, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0107, 289, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0108, 293, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0109, 297, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x010a, 301, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x010b, 305, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x010c, 309, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x010d, 313, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x010e, 317, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x010f, 321, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0112, 325, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0113, 329, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0114, 333, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0115, 337, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0116, 341, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0117, 345, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0118, 349, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0119, 353, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x011a, 357, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x011b, 361, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x011c, 365, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x011d, 369, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x011e, 373, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x011f, 377, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0120, 381, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0121, 385, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0122, 389, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0123, 393, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0124, 397, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0125, 401, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0128, 405, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0129, 409, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x012a, 413, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x012b, 417, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x012c, 421, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x012d, 425, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x012e, 429, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x012f, 433, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0130, 437, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0132, G_UNICODE_NOT_PRESENT_OFFSET, 441 }, + { 0x0133, G_UNICODE_NOT_PRESENT_OFFSET, 444 }, + { 0x0134, 447, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0135, 451, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0136, 455, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0137, 459, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0139, 463, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x013a, 467, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x013b, 471, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x013c, 475, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x013d, 479, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x013e, 483, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x013f, G_UNICODE_NOT_PRESENT_OFFSET, 487 }, + { 0x0140, G_UNICODE_NOT_PRESENT_OFFSET, 491 }, + { 0x0143, 495, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0144, 499, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0145, 503, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0146, 507, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0147, 511, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0148, 515, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0149, G_UNICODE_NOT_PRESENT_OFFSET, 519 }, + { 0x014c, 523, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x014d, 527, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x014e, 531, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x014f, 535, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0150, 539, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0151, 543, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0154, 547, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0155, 551, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0156, 555, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0157, 559, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0158, 563, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0159, 567, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x015a, 571, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x015b, 575, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x015c, 579, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x015d, 583, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x015e, 587, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x015f, 591, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0160, 595, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0161, 599, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0162, 603, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0163, 607, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0164, 611, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0165, 615, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0168, 619, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0169, 623, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x016a, 627, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x016b, 631, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x016c, 635, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x016d, 639, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x016e, 643, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x016f, 647, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0170, 651, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0171, 655, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0172, 659, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0173, 663, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0174, 667, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0175, 671, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0176, 675, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0177, 679, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0178, 683, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0179, 687, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x017a, 691, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x017b, 695, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x017c, 699, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x017d, 703, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x017e, 707, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x017f, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x01a0, 713, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01a1, 717, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01af, 721, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01b0, 725, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01c4, G_UNICODE_NOT_PRESENT_OFFSET, 729 }, + { 0x01c5, G_UNICODE_NOT_PRESENT_OFFSET, 734 }, + { 0x01c6, G_UNICODE_NOT_PRESENT_OFFSET, 739 }, + { 0x01c7, G_UNICODE_NOT_PRESENT_OFFSET, 744 }, + { 0x01c8, G_UNICODE_NOT_PRESENT_OFFSET, 747 }, + { 0x01c9, G_UNICODE_NOT_PRESENT_OFFSET, 750 }, + { 0x01ca, G_UNICODE_NOT_PRESENT_OFFSET, 753 }, + { 0x01cb, G_UNICODE_NOT_PRESENT_OFFSET, 756 }, + { 0x01cc, G_UNICODE_NOT_PRESENT_OFFSET, 759 }, + { 0x01cd, 762, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01ce, 766, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01cf, 770, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d0, 774, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d1, 778, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d2, 782, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d3, 786, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d4, 790, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d5, 794, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d6, 800, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d7, 806, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d8, 812, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01d9, 818, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01da, 824, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01db, 830, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01dc, 836, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01de, 842, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01df, 848, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01e0, 854, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01e1, 860, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01e2, 866, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01e3, 871, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01e6, 876, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01e7, 880, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01e8, 884, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01e9, 888, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01ea, 892, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01eb, 896, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01ec, 900, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01ed, 906, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01ee, 912, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01ef, 917, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01f0, 922, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01f1, G_UNICODE_NOT_PRESENT_OFFSET, 926 }, + { 0x01f2, G_UNICODE_NOT_PRESENT_OFFSET, 929 }, + { 0x01f3, G_UNICODE_NOT_PRESENT_OFFSET, 932 }, + { 0x01f4, 935, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01f5, 939, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01f8, 943, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01f9, 947, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01fa, 951, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01fb, 957, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01fc, 963, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01fd, 968, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01fe, 973, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x01ff, 978, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0200, 983, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0201, 987, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0202, 991, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0203, 995, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0204, 999, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0205, 1003, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0206, 1007, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0207, 1011, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0208, 1015, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0209, 1019, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x020a, 1023, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x020b, 1027, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x020c, 1031, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x020d, 1035, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x020e, 1039, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x020f, 1043, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0210, 1047, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0211, 1051, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0212, 1055, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0213, 1059, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0214, 1063, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0215, 1067, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0216, 1071, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0217, 1075, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0218, 1079, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0219, 1083, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x021a, 1087, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x021b, 1091, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x021e, 1095, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x021f, 1099, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0226, 1103, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0227, 1107, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0228, 1111, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0229, 1115, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x022a, 1119, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x022b, 1125, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x022c, 1131, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x022d, 1137, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x022e, 1143, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x022f, 1147, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0230, 1151, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0231, 1157, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0232, 1163, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0233, 1167, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x02b0, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x02b1, G_UNICODE_NOT_PRESENT_OFFSET, 1173 }, + { 0x02b2, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x02b3, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x02b4, G_UNICODE_NOT_PRESENT_OFFSET, 1180 }, + { 0x02b5, G_UNICODE_NOT_PRESENT_OFFSET, 1183 }, + { 0x02b6, G_UNICODE_NOT_PRESENT_OFFSET, 1186 }, + { 0x02b7, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x02b8, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x02d8, G_UNICODE_NOT_PRESENT_OFFSET, 1193 }, + { 0x02d9, G_UNICODE_NOT_PRESENT_OFFSET, 1197 }, + { 0x02da, G_UNICODE_NOT_PRESENT_OFFSET, 1201 }, + { 0x02db, G_UNICODE_NOT_PRESENT_OFFSET, 1205 }, + { 0x02dc, G_UNICODE_NOT_PRESENT_OFFSET, 1209 }, + { 0x02dd, G_UNICODE_NOT_PRESENT_OFFSET, 1213 }, + { 0x02e0, G_UNICODE_NOT_PRESENT_OFFSET, 1217 }, + { 0x02e1, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x02e2, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x02e3, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x02e4, G_UNICODE_NOT_PRESENT_OFFSET, 1224 }, + { 0x0340, 1227, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0341, 1230, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0343, 1233, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0344, 1236, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0374, 1241, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x037a, G_UNICODE_NOT_PRESENT_OFFSET, 1244 }, + { 0x037e, 1248, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0384, G_UNICODE_NOT_PRESENT_OFFSET, 16 }, + { 0x0385, 1250, 1255 }, + { 0x0386, 1261, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0387, 1266, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0388, 1269, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0389, 1274, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x038a, 1279, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x038c, 1284, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x038e, 1289, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x038f, 1294, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0390, 1299, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03aa, 1306, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03ab, 1311, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03ac, 1316, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03ad, 1321, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03ae, 1326, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03af, 1331, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03b0, 1336, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03ca, 1343, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03cb, 1348, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03cc, 1353, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03cd, 1358, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03ce, 1363, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x03d0, G_UNICODE_NOT_PRESENT_OFFSET, 1368 }, + { 0x03d1, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x03d2, G_UNICODE_NOT_PRESENT_OFFSET, 1374 }, + { 0x03d3, 1377, 1289 }, + { 0x03d4, 1382, 1311 }, + { 0x03d5, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x03d6, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x03f0, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x03f1, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x03f2, G_UNICODE_NOT_PRESENT_OFFSET, 1399 }, + { 0x03f4, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x03f5, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x03f9, G_UNICODE_NOT_PRESENT_OFFSET, 1408 }, + { 0x0400, 1411, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0401, 1416, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0403, 1421, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0407, 1426, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x040c, 1431, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x040d, 1436, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x040e, 1441, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0419, 1446, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0439, 1451, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0450, 1456, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0451, 1461, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0453, 1466, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0457, 1471, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x045c, 1476, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x045d, 1481, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x045e, 1486, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0476, 1491, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0477, 1496, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04c1, 1501, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04c2, 1506, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04d0, 1511, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04d1, 1516, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04d2, 1521, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04d3, 1526, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04d6, 1531, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04d7, 1536, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04da, 1541, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04db, 1546, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04dc, 1551, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04dd, 1556, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04de, 1561, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04df, 1566, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04e2, 1571, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04e3, 1576, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04e4, 1581, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04e5, 1586, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04e6, 1591, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04e7, 1596, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04ea, 1601, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04eb, 1606, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04ec, 1611, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04ed, 1616, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04ee, 1621, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04ef, 1626, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04f0, 1631, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04f1, 1636, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04f2, 1641, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04f3, 1646, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04f4, 1651, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04f5, 1656, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04f8, 1661, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x04f9, 1666, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0587, G_UNICODE_NOT_PRESENT_OFFSET, 1671 }, + { 0x0622, 1676, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0623, 1681, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0624, 1686, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0625, 1691, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0626, 1696, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0675, G_UNICODE_NOT_PRESENT_OFFSET, 1701 }, + { 0x0676, G_UNICODE_NOT_PRESENT_OFFSET, 1706 }, + { 0x0677, G_UNICODE_NOT_PRESENT_OFFSET, 1711 }, + { 0x0678, G_UNICODE_NOT_PRESENT_OFFSET, 1716 }, + { 0x06c0, 1721, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x06c2, 1726, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x06d3, 1731, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0929, 1736, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0931, 1743, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0934, 1750, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0958, 1757, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0959, 1764, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x095a, 1771, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x095b, 1778, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x095c, 1785, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x095d, 1792, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x095e, 1799, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x095f, 1806, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x09cb, 1813, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x09cc, 1820, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x09dc, 1827, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x09dd, 1834, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x09df, 1841, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0a33, 1848, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0a36, 1855, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0a59, 1862, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0a5a, 1869, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0a5b, 1876, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0a5e, 1883, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0b48, 1890, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0b4b, 1897, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0b4c, 1904, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0b5c, 1911, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0b5d, 1918, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0b94, 1925, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0bca, 1932, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0bcb, 1939, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0bcc, 1946, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0c48, 1953, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0cc0, 1960, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0cc7, 1967, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0cc8, 1974, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0cca, 1981, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0ccb, 1988, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0d4a, 1998, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0d4b, 2005, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0d4c, 2012, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0dda, 2019, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0ddc, 2026, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0ddd, 2033, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0dde, 2043, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0e33, G_UNICODE_NOT_PRESENT_OFFSET, 2050 }, + { 0x0eb3, G_UNICODE_NOT_PRESENT_OFFSET, 2057 }, + { 0x0edc, G_UNICODE_NOT_PRESENT_OFFSET, 2064 }, + { 0x0edd, G_UNICODE_NOT_PRESENT_OFFSET, 2071 }, + { 0x0f0c, G_UNICODE_NOT_PRESENT_OFFSET, 2078 }, + { 0x0f43, 2082, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f4d, 2089, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f52, 2096, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f57, 2103, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f5c, 2110, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f69, 2117, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f73, 2124, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f75, 2131, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f76, 2138, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f77, G_UNICODE_NOT_PRESENT_OFFSET, 2145 }, + { 0x0f78, 2155, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f79, G_UNICODE_NOT_PRESENT_OFFSET, 2162 }, + { 0x0f81, 2172, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f93, 2179, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0f9d, 2186, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0fa2, 2193, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0fa7, 2200, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0fac, 2207, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x0fb9, 2214, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1026, 2221, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x10fc, G_UNICODE_NOT_PRESENT_OFFSET, 2228 }, + { 0x1b06, 2232, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b08, 2239, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b0a, 2246, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b0c, 2253, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b0e, 2260, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b12, 2267, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b3b, 2274, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b3d, 2281, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b40, 2288, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b41, 2295, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1b43, 2302, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d2c, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d2d, G_UNICODE_NOT_PRESENT_OFFSET, 2311 }, + { 0x1d2e, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d30, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d31, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d32, G_UNICODE_NOT_PRESENT_OFFSET, 2320 }, + { 0x1d33, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d34, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d35, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d36, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d37, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d38, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d39, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d3a, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d3c, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d3d, G_UNICODE_NOT_PRESENT_OFFSET, 2341 }, + { 0x1d3e, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d3f, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d40, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d41, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d42, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d43, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d44, G_UNICODE_NOT_PRESENT_OFFSET, 2354 }, + { 0x1d45, G_UNICODE_NOT_PRESENT_OFFSET, 2357 }, + { 0x1d46, G_UNICODE_NOT_PRESENT_OFFSET, 2360 }, + { 0x1d47, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d48, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d49, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d4a, G_UNICODE_NOT_PRESENT_OFFSET, 2370 }, + { 0x1d4b, G_UNICODE_NOT_PRESENT_OFFSET, 2373 }, + { 0x1d4c, G_UNICODE_NOT_PRESENT_OFFSET, 2376 }, + { 0x1d4d, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d4f, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d50, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d51, G_UNICODE_NOT_PRESENT_OFFSET, 2385 }, + { 0x1d52, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d53, G_UNICODE_NOT_PRESENT_OFFSET, 2388 }, + { 0x1d54, G_UNICODE_NOT_PRESENT_OFFSET, 2391 }, + { 0x1d55, G_UNICODE_NOT_PRESENT_OFFSET, 2395 }, + { 0x1d56, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d57, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d58, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d59, G_UNICODE_NOT_PRESENT_OFFSET, 2405 }, + { 0x1d5a, G_UNICODE_NOT_PRESENT_OFFSET, 2409 }, + { 0x1d5b, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d5c, G_UNICODE_NOT_PRESENT_OFFSET, 2414 }, + { 0x1d5d, G_UNICODE_NOT_PRESENT_OFFSET, 1368 }, + { 0x1d5e, G_UNICODE_NOT_PRESENT_OFFSET, 2418 }, + { 0x1d5f, G_UNICODE_NOT_PRESENT_OFFSET, 2421 }, + { 0x1d60, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d61, G_UNICODE_NOT_PRESENT_OFFSET, 2424 }, + { 0x1d62, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d63, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d64, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d65, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d66, G_UNICODE_NOT_PRESENT_OFFSET, 1368 }, + { 0x1d67, G_UNICODE_NOT_PRESENT_OFFSET, 2418 }, + { 0x1d68, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d69, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d6a, G_UNICODE_NOT_PRESENT_OFFSET, 2424 }, + { 0x1d78, G_UNICODE_NOT_PRESENT_OFFSET, 2429 }, + { 0x1d9b, G_UNICODE_NOT_PRESENT_OFFSET, 2432 }, + { 0x1d9c, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d9d, G_UNICODE_NOT_PRESENT_OFFSET, 2437 }, + { 0x1d9e, G_UNICODE_NOT_PRESENT_OFFSET, 2440 }, + { 0x1d9f, G_UNICODE_NOT_PRESENT_OFFSET, 2376 }, + { 0x1da0, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1da1, G_UNICODE_NOT_PRESENT_OFFSET, 2445 }, + { 0x1da2, G_UNICODE_NOT_PRESENT_OFFSET, 2448 }, + { 0x1da3, G_UNICODE_NOT_PRESENT_OFFSET, 2451 }, + { 0x1da4, G_UNICODE_NOT_PRESENT_OFFSET, 2454 }, + { 0x1da5, G_UNICODE_NOT_PRESENT_OFFSET, 2457 }, + { 0x1da6, G_UNICODE_NOT_PRESENT_OFFSET, 2460 }, + { 0x1da7, G_UNICODE_NOT_PRESENT_OFFSET, 2463 }, + { 0x1da8, G_UNICODE_NOT_PRESENT_OFFSET, 2467 }, + { 0x1da9, G_UNICODE_NOT_PRESENT_OFFSET, 2470 }, + { 0x1daa, G_UNICODE_NOT_PRESENT_OFFSET, 2473 }, + { 0x1dab, G_UNICODE_NOT_PRESENT_OFFSET, 2477 }, + { 0x1dac, G_UNICODE_NOT_PRESENT_OFFSET, 2480 }, + { 0x1dad, G_UNICODE_NOT_PRESENT_OFFSET, 2483 }, + { 0x1dae, G_UNICODE_NOT_PRESENT_OFFSET, 2486 }, + { 0x1daf, G_UNICODE_NOT_PRESENT_OFFSET, 2489 }, + { 0x1db0, G_UNICODE_NOT_PRESENT_OFFSET, 2492 }, + { 0x1db1, G_UNICODE_NOT_PRESENT_OFFSET, 2495 }, + { 0x1db2, G_UNICODE_NOT_PRESENT_OFFSET, 2498 }, + { 0x1db3, G_UNICODE_NOT_PRESENT_OFFSET, 2501 }, + { 0x1db4, G_UNICODE_NOT_PRESENT_OFFSET, 2504 }, + { 0x1db5, G_UNICODE_NOT_PRESENT_OFFSET, 2507 }, + { 0x1db6, G_UNICODE_NOT_PRESENT_OFFSET, 2510 }, + { 0x1db7, G_UNICODE_NOT_PRESENT_OFFSET, 2513 }, + { 0x1db8, G_UNICODE_NOT_PRESENT_OFFSET, 2516 }, + { 0x1db9, G_UNICODE_NOT_PRESENT_OFFSET, 2520 }, + { 0x1dba, G_UNICODE_NOT_PRESENT_OFFSET, 2523 }, + { 0x1dbb, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1dbc, G_UNICODE_NOT_PRESENT_OFFSET, 2528 }, + { 0x1dbd, G_UNICODE_NOT_PRESENT_OFFSET, 2531 }, + { 0x1dbe, G_UNICODE_NOT_PRESENT_OFFSET, 2534 }, + { 0x1dbf, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1e00, 2537, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e01, 2541, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e02, 2545, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e03, 2549, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e04, 2553, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e05, 2557, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e06, 2561, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e07, 2565, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e08, 2569, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e09, 2575, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e0a, 2581, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e0b, 2585, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e0c, 2589, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e0d, 2593, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e0e, 2597, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e0f, 2601, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e10, 2605, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e11, 2609, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e12, 2613, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e13, 2617, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e14, 2621, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e15, 2627, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e16, 2633, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e17, 2639, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e18, 2645, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e19, 2649, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e1a, 2653, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e1b, 2657, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e1c, 2661, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e1d, 2667, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e1e, 2673, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e1f, 2677, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e20, 2681, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e21, 2685, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e22, 2689, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e23, 2693, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e24, 2697, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e25, 2701, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e26, 2705, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e27, 2709, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e28, 2713, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e29, 2717, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e2a, 2721, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e2b, 2725, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e2c, 2729, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e2d, 2733, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e2e, 2737, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e2f, 2743, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e30, 2749, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e31, 2753, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e32, 2757, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e33, 2761, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e34, 2765, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e35, 2769, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e36, 2773, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e37, 2777, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e38, 2781, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e39, 2787, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e3a, 2793, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e3b, 2797, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e3c, 2801, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e3d, 2805, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e3e, 2809, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e3f, 2813, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e40, 2817, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e41, 2821, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e42, 2825, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e43, 2829, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e44, 2833, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e45, 2837, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e46, 2841, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e47, 2845, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e48, 2849, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e49, 2853, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e4a, 2857, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e4b, 2861, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e4c, 2865, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e4d, 2871, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e4e, 2877, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e4f, 2883, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e50, 2889, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e51, 2895, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e52, 2901, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e53, 2907, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e54, 2913, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e55, 2917, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e56, 2921, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e57, 2925, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e58, 2929, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e59, 2933, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e5a, 2937, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e5b, 2941, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e5c, 2945, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e5d, 2951, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e5e, 2957, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e5f, 2961, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e60, 2965, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e61, 2969, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e62, 2973, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e63, 2977, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e64, 2981, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e65, 2987, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e66, 2993, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e67, 2999, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e68, 3005, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e69, 3011, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e6a, 3017, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e6b, 3021, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e6c, 3025, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e6d, 3029, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e6e, 3033, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e6f, 3037, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e70, 3041, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e71, 3045, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e72, 3049, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e73, 3053, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e74, 3057, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e75, 3061, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e76, 3065, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e77, 3069, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e78, 3073, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e79, 3079, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e7a, 3085, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e7b, 3091, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e7c, 3097, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e7d, 3101, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e7e, 3105, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e7f, 3109, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e80, 3113, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e81, 3117, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e82, 3121, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e83, 3125, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e84, 3129, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e85, 3133, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e86, 3137, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e87, 3141, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e88, 3145, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e89, 3149, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e8a, 3153, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e8b, 3157, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e8c, 3161, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e8d, 3165, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e8e, 3169, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e8f, 3173, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e90, 3177, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e91, 3181, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e92, 3185, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e93, 3189, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e94, 3193, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e95, 3197, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e96, 3201, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e97, 3205, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e98, 3209, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e99, 3213, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1e9a, G_UNICODE_NOT_PRESENT_OFFSET, 3217 }, + { 0x1e9b, 3221, 2969 }, + { 0x1ea0, 3226, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea1, 3230, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea2, 3234, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea3, 3238, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea4, 3242, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea5, 3248, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea6, 3254, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea7, 3260, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea8, 3266, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ea9, 3272, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eaa, 3278, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eab, 3284, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eac, 3290, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ead, 3296, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eae, 3302, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eaf, 3308, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb0, 3314, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb1, 3320, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb2, 3326, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb3, 3332, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb4, 3338, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb5, 3344, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb6, 3350, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb7, 3356, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb8, 3362, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eb9, 3366, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eba, 3370, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ebb, 3374, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ebc, 3378, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ebd, 3382, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ebe, 3386, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ebf, 3392, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec0, 3398, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec1, 3404, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec2, 3410, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec3, 3416, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec4, 3422, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec5, 3428, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec6, 3434, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec7, 3440, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec8, 3446, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ec9, 3450, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eca, 3454, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ecb, 3458, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ecc, 3462, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ecd, 3466, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ece, 3470, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ecf, 3474, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed0, 3478, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed1, 3484, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed2, 3490, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed3, 3496, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed4, 3502, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed5, 3508, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed6, 3514, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed7, 3520, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed8, 3526, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ed9, 3532, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eda, 3538, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1edb, 3544, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1edc, 3550, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1edd, 3556, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ede, 3562, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1edf, 3568, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee0, 3574, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee1, 3580, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee2, 3586, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee3, 3592, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee4, 3598, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee5, 3602, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee6, 3606, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee7, 3610, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee8, 3614, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ee9, 3620, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eea, 3626, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eeb, 3632, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eec, 3638, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eed, 3644, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eee, 3650, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1eef, 3656, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef0, 3662, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef1, 3668, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef2, 3674, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef3, 3678, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef4, 3682, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef5, 3686, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef6, 3690, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef7, 3694, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef8, 3698, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ef9, 3702, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f00, 3706, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f01, 3711, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f02, 3716, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f03, 3723, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f04, 3730, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f05, 3737, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f06, 3744, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f07, 3751, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f08, 3758, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f09, 3763, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f0a, 3768, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f0b, 3775, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f0c, 3782, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f0d, 3789, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f0e, 3796, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f0f, 3803, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f10, 3810, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f11, 3815, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f12, 3820, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f13, 3827, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f14, 3834, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f15, 3841, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f18, 3848, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f19, 3853, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f1a, 3858, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f1b, 3865, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f1c, 3872, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f1d, 3879, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f20, 3886, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f21, 3891, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f22, 3896, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f23, 3903, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f24, 3910, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f25, 3917, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f26, 3924, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f27, 3931, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f28, 3938, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f29, 3943, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f2a, 3948, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f2b, 3955, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f2c, 3962, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f2d, 3969, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f2e, 3976, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f2f, 3983, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f30, 3990, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f31, 3995, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f32, 4000, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f33, 4007, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f34, 4014, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f35, 4021, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f36, 4028, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f37, 4035, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f38, 4042, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f39, 4047, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f3a, 4052, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f3b, 4059, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f3c, 4066, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f3d, 4073, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f3e, 4080, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f3f, 4087, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f40, 4094, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f41, 4099, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f42, 4104, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f43, 4111, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f44, 4118, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f45, 4125, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f48, 4132, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f49, 4137, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f4a, 4142, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f4b, 4149, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f4c, 4156, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f4d, 4163, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f50, 4170, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f51, 4175, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f52, 4180, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f53, 4187, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f54, 4194, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f55, 4201, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f56, 4208, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f57, 4215, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f59, 4222, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f5b, 4227, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f5d, 4234, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f5f, 4241, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f60, 4248, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f61, 4253, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f62, 4258, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f63, 4265, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f64, 4272, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f65, 4279, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f66, 4286, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f67, 4293, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f68, 4300, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f69, 4305, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f6a, 4310, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f6b, 4317, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f6c, 4324, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f6d, 4331, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f6e, 4338, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f6f, 4345, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f70, 4352, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f71, 1316, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f72, 4357, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f73, 1321, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f74, 4362, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f75, 1326, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f76, 4367, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f77, 1331, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f78, 4372, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f79, 1353, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f7a, 4377, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f7b, 1358, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f7c, 4382, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f7d, 1363, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f80, 4387, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f81, 4394, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f82, 4401, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f83, 4410, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f84, 4419, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f85, 4428, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f86, 4437, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f87, 4446, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f88, 4455, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f89, 4462, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f8a, 4469, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f8b, 4478, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f8c, 4487, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f8d, 4496, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f8e, 4505, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f8f, 4514, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f90, 4523, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f91, 4530, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f92, 4537, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f93, 4546, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f94, 4555, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f95, 4564, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f96, 4573, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f97, 4582, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f98, 4591, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f99, 4598, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f9a, 4605, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f9b, 4614, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f9c, 4623, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f9d, 4632, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f9e, 4641, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1f9f, 4650, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa0, 4659, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa1, 4666, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa2, 4673, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa3, 4682, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa4, 4691, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa5, 4700, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa6, 4709, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa7, 4718, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa8, 4727, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fa9, 4734, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1faa, 4741, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fab, 4750, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fac, 4759, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fad, 4768, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fae, 4777, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1faf, 4786, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb0, 4795, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb1, 4800, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb2, 4805, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb3, 4812, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb4, 4817, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb6, 4824, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb7, 4829, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb8, 4836, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fb9, 4841, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fba, 4846, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fbb, 1261, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fbc, 4851, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fbd, G_UNICODE_NOT_PRESENT_OFFSET, 4856 }, + { 0x1fbe, 4860, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fbf, G_UNICODE_NOT_PRESENT_OFFSET, 4856 }, + { 0x1fc0, G_UNICODE_NOT_PRESENT_OFFSET, 4863 }, + { 0x1fc1, 4867, 4872 }, + { 0x1fc2, 4878, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fc3, 4885, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fc4, 4890, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fc6, 4897, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fc7, 4902, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fc8, 4909, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fc9, 1269, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fca, 4914, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fcb, 1274, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fcc, 4919, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fcd, 4924, 4930 }, + { 0x1fce, 4936, 4942 }, + { 0x1fcf, 4948, 4954 }, + { 0x1fd0, 4960, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fd1, 4965, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fd2, 4970, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fd3, 1299, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fd6, 4977, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fd7, 4982, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fd8, 4989, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fd9, 4994, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fda, 4999, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fdb, 1279, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fdd, 5004, 5010 }, + { 0x1fde, 5016, 5022 }, + { 0x1fdf, 5028, 5034 }, + { 0x1fe0, 5040, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe1, 5045, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe2, 5050, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe3, 1336, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe4, 5057, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe5, 5062, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe6, 5067, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe7, 5072, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe8, 5079, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fe9, 5084, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fea, 5089, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1feb, 1289, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fec, 5094, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1fed, 5099, 5104 }, + { 0x1fee, 1250, 1255 }, + { 0x1fef, 5110, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ff2, 5112, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ff3, 5119, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ff4, 5124, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ff6, 5131, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ff7, 5136, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ff8, 5143, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ff9, 1284, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ffa, 5148, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ffb, 1294, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ffc, 5153, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1ffd, 5158, 16 }, + { 0x1ffe, G_UNICODE_NOT_PRESENT_OFFSET, 5161 }, + { 0x2000, 5165, 0 }, + { 0x2001, 5169, 0 }, + { 0x2002, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2003, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2004, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2005, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2006, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2007, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2008, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2009, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x200a, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2011, G_UNICODE_NOT_PRESENT_OFFSET, 5173 }, + { 0x2017, G_UNICODE_NOT_PRESENT_OFFSET, 5177 }, + { 0x2024, G_UNICODE_NOT_PRESENT_OFFSET, 5181 }, + { 0x2025, G_UNICODE_NOT_PRESENT_OFFSET, 5183 }, + { 0x2026, G_UNICODE_NOT_PRESENT_OFFSET, 5186 }, + { 0x202f, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2033, G_UNICODE_NOT_PRESENT_OFFSET, 5190 }, + { 0x2034, G_UNICODE_NOT_PRESENT_OFFSET, 5197 }, + { 0x2036, G_UNICODE_NOT_PRESENT_OFFSET, 5207 }, + { 0x2037, G_UNICODE_NOT_PRESENT_OFFSET, 5214 }, + { 0x203c, G_UNICODE_NOT_PRESENT_OFFSET, 5224 }, + { 0x203e, G_UNICODE_NOT_PRESENT_OFFSET, 5227 }, + { 0x2047, G_UNICODE_NOT_PRESENT_OFFSET, 5231 }, + { 0x2048, G_UNICODE_NOT_PRESENT_OFFSET, 5234 }, + { 0x2049, G_UNICODE_NOT_PRESENT_OFFSET, 5237 }, + { 0x2057, G_UNICODE_NOT_PRESENT_OFFSET, 5240 }, + { 0x205f, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x2070, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0x2071, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x2074, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0x2075, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0x2076, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0x2077, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0x2078, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0x2079, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0x207a, G_UNICODE_NOT_PRESENT_OFFSET, 5267 }, + { 0x207b, G_UNICODE_NOT_PRESENT_OFFSET, 5269 }, + { 0x207c, G_UNICODE_NOT_PRESENT_OFFSET, 5273 }, + { 0x207d, G_UNICODE_NOT_PRESENT_OFFSET, 5275 }, + { 0x207e, G_UNICODE_NOT_PRESENT_OFFSET, 5277 }, + { 0x207f, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x2080, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0x2081, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0x2082, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0x2083, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0x2084, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0x2085, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0x2086, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0x2087, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0x2088, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0x2089, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0x208a, G_UNICODE_NOT_PRESENT_OFFSET, 5267 }, + { 0x208b, G_UNICODE_NOT_PRESENT_OFFSET, 5269 }, + { 0x208c, G_UNICODE_NOT_PRESENT_OFFSET, 5273 }, + { 0x208d, G_UNICODE_NOT_PRESENT_OFFSET, 5275 }, + { 0x208e, G_UNICODE_NOT_PRESENT_OFFSET, 5277 }, + { 0x2090, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x2091, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x2092, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x2093, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x2094, G_UNICODE_NOT_PRESENT_OFFSET, 2370 }, + { 0x2095, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x2096, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x2097, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x2098, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x2099, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x209a, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x209b, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x209c, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x20a8, G_UNICODE_NOT_PRESENT_OFFSET, 5281 }, + { 0x2100, G_UNICODE_NOT_PRESENT_OFFSET, 5284 }, + { 0x2101, G_UNICODE_NOT_PRESENT_OFFSET, 5288 }, + { 0x2102, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x2103, G_UNICODE_NOT_PRESENT_OFFSET, 5294 }, + { 0x2105, G_UNICODE_NOT_PRESENT_OFFSET, 5298 }, + { 0x2106, G_UNICODE_NOT_PRESENT_OFFSET, 5302 }, + { 0x2107, G_UNICODE_NOT_PRESENT_OFFSET, 5306 }, + { 0x2109, G_UNICODE_NOT_PRESENT_OFFSET, 5309 }, + { 0x210a, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x210b, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x210c, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x210d, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x210e, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x210f, G_UNICODE_NOT_PRESENT_OFFSET, 5313 }, + { 0x2110, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x2111, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x2112, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x2113, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x2115, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x2116, G_UNICODE_NOT_PRESENT_OFFSET, 5316 }, + { 0x2119, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x211a, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x211b, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x211c, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x211d, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x2120, G_UNICODE_NOT_PRESENT_OFFSET, 5321 }, + { 0x2121, G_UNICODE_NOT_PRESENT_OFFSET, 5324 }, + { 0x2122, G_UNICODE_NOT_PRESENT_OFFSET, 5328 }, + { 0x2124, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x2126, 5333, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2128, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x212a, 2331, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x212b, 69, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x212c, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x212d, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x212f, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x2130, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x2131, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x2133, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x2134, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x2135, G_UNICODE_NOT_PRESENT_OFFSET, 5338 }, + { 0x2136, G_UNICODE_NOT_PRESENT_OFFSET, 5341 }, + { 0x2137, G_UNICODE_NOT_PRESENT_OFFSET, 5344 }, + { 0x2138, G_UNICODE_NOT_PRESENT_OFFSET, 5347 }, + { 0x2139, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x213b, G_UNICODE_NOT_PRESENT_OFFSET, 5350 }, + { 0x213c, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x213d, G_UNICODE_NOT_PRESENT_OFFSET, 2418 }, + { 0x213e, G_UNICODE_NOT_PRESENT_OFFSET, 5354 }, + { 0x213f, G_UNICODE_NOT_PRESENT_OFFSET, 5357 }, + { 0x2140, G_UNICODE_NOT_PRESENT_OFFSET, 5360 }, + { 0x2145, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x2146, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x2147, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x2148, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x2149, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x2150, G_UNICODE_NOT_PRESENT_OFFSET, 5364 }, + { 0x2151, G_UNICODE_NOT_PRESENT_OFFSET, 5370 }, + { 0x2152, G_UNICODE_NOT_PRESENT_OFFSET, 5376 }, + { 0x2153, G_UNICODE_NOT_PRESENT_OFFSET, 5383 }, + { 0x2154, G_UNICODE_NOT_PRESENT_OFFSET, 5389 }, + { 0x2155, G_UNICODE_NOT_PRESENT_OFFSET, 5395 }, + { 0x2156, G_UNICODE_NOT_PRESENT_OFFSET, 5401 }, + { 0x2157, G_UNICODE_NOT_PRESENT_OFFSET, 5407 }, + { 0x2158, G_UNICODE_NOT_PRESENT_OFFSET, 5413 }, + { 0x2159, G_UNICODE_NOT_PRESENT_OFFSET, 5419 }, + { 0x215a, G_UNICODE_NOT_PRESENT_OFFSET, 5425 }, + { 0x215b, G_UNICODE_NOT_PRESENT_OFFSET, 5431 }, + { 0x215c, G_UNICODE_NOT_PRESENT_OFFSET, 5437 }, + { 0x215d, G_UNICODE_NOT_PRESENT_OFFSET, 5443 }, + { 0x215e, G_UNICODE_NOT_PRESENT_OFFSET, 5449 }, + { 0x215f, G_UNICODE_NOT_PRESENT_OFFSET, 5455 }, + { 0x2160, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x2161, G_UNICODE_NOT_PRESENT_OFFSET, 5460 }, + { 0x2162, G_UNICODE_NOT_PRESENT_OFFSET, 5463 }, + { 0x2163, G_UNICODE_NOT_PRESENT_OFFSET, 5467 }, + { 0x2164, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x2165, G_UNICODE_NOT_PRESENT_OFFSET, 5472 }, + { 0x2166, G_UNICODE_NOT_PRESENT_OFFSET, 5475 }, + { 0x2167, G_UNICODE_NOT_PRESENT_OFFSET, 5479 }, + { 0x2168, G_UNICODE_NOT_PRESENT_OFFSET, 5484 }, + { 0x2169, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x216a, G_UNICODE_NOT_PRESENT_OFFSET, 5489 }, + { 0x216b, G_UNICODE_NOT_PRESENT_OFFSET, 5492 }, + { 0x216c, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x216d, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x216e, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x216f, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x2170, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x2171, G_UNICODE_NOT_PRESENT_OFFSET, 5496 }, + { 0x2172, G_UNICODE_NOT_PRESENT_OFFSET, 5499 }, + { 0x2173, G_UNICODE_NOT_PRESENT_OFFSET, 5503 }, + { 0x2174, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x2175, G_UNICODE_NOT_PRESENT_OFFSET, 5506 }, + { 0x2176, G_UNICODE_NOT_PRESENT_OFFSET, 5509 }, + { 0x2177, G_UNICODE_NOT_PRESENT_OFFSET, 5513 }, + { 0x2178, G_UNICODE_NOT_PRESENT_OFFSET, 5518 }, + { 0x2179, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x217a, G_UNICODE_NOT_PRESENT_OFFSET, 5521 }, + { 0x217b, G_UNICODE_NOT_PRESENT_OFFSET, 5524 }, + { 0x217c, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x217d, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x217e, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x217f, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x2189, G_UNICODE_NOT_PRESENT_OFFSET, 5528 }, + { 0x219a, 5534, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x219b, 5540, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x21ae, 5546, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x21cd, 5552, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x21ce, 5558, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x21cf, 5564, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2204, 5570, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2209, 5576, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x220c, 5582, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2224, 5588, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2226, 5594, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x222c, G_UNICODE_NOT_PRESENT_OFFSET, 5600 }, + { 0x222d, G_UNICODE_NOT_PRESENT_OFFSET, 5607 }, + { 0x222f, G_UNICODE_NOT_PRESENT_OFFSET, 5617 }, + { 0x2230, G_UNICODE_NOT_PRESENT_OFFSET, 5624 }, + { 0x2241, 5634, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2244, 5640, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2247, 5646, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2249, 5652, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2260, 5658, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2262, 5662, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x226d, 5668, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x226e, 5674, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x226f, 5678, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2270, 5682, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2271, 5688, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2274, 5694, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2275, 5700, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2278, 5706, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2279, 5712, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2280, 5718, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2281, 5724, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2284, 5730, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2285, 5736, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2288, 5742, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2289, 5748, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22ac, 5754, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22ad, 5760, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22ae, 5766, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22af, 5772, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22e0, 5778, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22e1, 5784, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22e2, 5790, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22e3, 5796, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22ea, 5802, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22eb, 5808, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22ec, 5814, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x22ed, 5820, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2329, 5826, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x232a, 5830, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2460, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0x2461, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0x2462, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0x2463, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0x2464, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0x2465, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0x2466, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0x2467, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0x2468, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0x2469, G_UNICODE_NOT_PRESENT_OFFSET, 5834 }, + { 0x246a, G_UNICODE_NOT_PRESENT_OFFSET, 5837 }, + { 0x246b, G_UNICODE_NOT_PRESENT_OFFSET, 5840 }, + { 0x246c, G_UNICODE_NOT_PRESENT_OFFSET, 5843 }, + { 0x246d, G_UNICODE_NOT_PRESENT_OFFSET, 5846 }, + { 0x246e, G_UNICODE_NOT_PRESENT_OFFSET, 5849 }, + { 0x246f, G_UNICODE_NOT_PRESENT_OFFSET, 5852 }, + { 0x2470, G_UNICODE_NOT_PRESENT_OFFSET, 5855 }, + { 0x2471, G_UNICODE_NOT_PRESENT_OFFSET, 5858 }, + { 0x2472, G_UNICODE_NOT_PRESENT_OFFSET, 5861 }, + { 0x2473, G_UNICODE_NOT_PRESENT_OFFSET, 5864 }, + { 0x2474, G_UNICODE_NOT_PRESENT_OFFSET, 5867 }, + { 0x2475, G_UNICODE_NOT_PRESENT_OFFSET, 5871 }, + { 0x2476, G_UNICODE_NOT_PRESENT_OFFSET, 5875 }, + { 0x2477, G_UNICODE_NOT_PRESENT_OFFSET, 5879 }, + { 0x2478, G_UNICODE_NOT_PRESENT_OFFSET, 5883 }, + { 0x2479, G_UNICODE_NOT_PRESENT_OFFSET, 5887 }, + { 0x247a, G_UNICODE_NOT_PRESENT_OFFSET, 5891 }, + { 0x247b, G_UNICODE_NOT_PRESENT_OFFSET, 5895 }, + { 0x247c, G_UNICODE_NOT_PRESENT_OFFSET, 5899 }, + { 0x247d, G_UNICODE_NOT_PRESENT_OFFSET, 5903 }, + { 0x247e, G_UNICODE_NOT_PRESENT_OFFSET, 5908 }, + { 0x247f, G_UNICODE_NOT_PRESENT_OFFSET, 5913 }, + { 0x2480, G_UNICODE_NOT_PRESENT_OFFSET, 5918 }, + { 0x2481, G_UNICODE_NOT_PRESENT_OFFSET, 5923 }, + { 0x2482, G_UNICODE_NOT_PRESENT_OFFSET, 5928 }, + { 0x2483, G_UNICODE_NOT_PRESENT_OFFSET, 5933 }, + { 0x2484, G_UNICODE_NOT_PRESENT_OFFSET, 5938 }, + { 0x2485, G_UNICODE_NOT_PRESENT_OFFSET, 5943 }, + { 0x2486, G_UNICODE_NOT_PRESENT_OFFSET, 5948 }, + { 0x2487, G_UNICODE_NOT_PRESENT_OFFSET, 5953 }, + { 0x2488, G_UNICODE_NOT_PRESENT_OFFSET, 5958 }, + { 0x2489, G_UNICODE_NOT_PRESENT_OFFSET, 5961 }, + { 0x248a, G_UNICODE_NOT_PRESENT_OFFSET, 5964 }, + { 0x248b, G_UNICODE_NOT_PRESENT_OFFSET, 5967 }, + { 0x248c, G_UNICODE_NOT_PRESENT_OFFSET, 5970 }, + { 0x248d, G_UNICODE_NOT_PRESENT_OFFSET, 5973 }, + { 0x248e, G_UNICODE_NOT_PRESENT_OFFSET, 5976 }, + { 0x248f, G_UNICODE_NOT_PRESENT_OFFSET, 5979 }, + { 0x2490, G_UNICODE_NOT_PRESENT_OFFSET, 5982 }, + { 0x2491, G_UNICODE_NOT_PRESENT_OFFSET, 5985 }, + { 0x2492, G_UNICODE_NOT_PRESENT_OFFSET, 5989 }, + { 0x2493, G_UNICODE_NOT_PRESENT_OFFSET, 5993 }, + { 0x2494, G_UNICODE_NOT_PRESENT_OFFSET, 5997 }, + { 0x2495, G_UNICODE_NOT_PRESENT_OFFSET, 6001 }, + { 0x2496, G_UNICODE_NOT_PRESENT_OFFSET, 6005 }, + { 0x2497, G_UNICODE_NOT_PRESENT_OFFSET, 6009 }, + { 0x2498, G_UNICODE_NOT_PRESENT_OFFSET, 6013 }, + { 0x2499, G_UNICODE_NOT_PRESENT_OFFSET, 6017 }, + { 0x249a, G_UNICODE_NOT_PRESENT_OFFSET, 6021 }, + { 0x249b, G_UNICODE_NOT_PRESENT_OFFSET, 6025 }, + { 0x249c, G_UNICODE_NOT_PRESENT_OFFSET, 6029 }, + { 0x249d, G_UNICODE_NOT_PRESENT_OFFSET, 6033 }, + { 0x249e, G_UNICODE_NOT_PRESENT_OFFSET, 6037 }, + { 0x249f, G_UNICODE_NOT_PRESENT_OFFSET, 6041 }, + { 0x24a0, G_UNICODE_NOT_PRESENT_OFFSET, 6045 }, + { 0x24a1, G_UNICODE_NOT_PRESENT_OFFSET, 6049 }, + { 0x24a2, G_UNICODE_NOT_PRESENT_OFFSET, 6053 }, + { 0x24a3, G_UNICODE_NOT_PRESENT_OFFSET, 6057 }, + { 0x24a4, G_UNICODE_NOT_PRESENT_OFFSET, 6061 }, + { 0x24a5, G_UNICODE_NOT_PRESENT_OFFSET, 6065 }, + { 0x24a6, G_UNICODE_NOT_PRESENT_OFFSET, 6069 }, + { 0x24a7, G_UNICODE_NOT_PRESENT_OFFSET, 6073 }, + { 0x24a8, G_UNICODE_NOT_PRESENT_OFFSET, 6077 }, + { 0x24a9, G_UNICODE_NOT_PRESENT_OFFSET, 6081 }, + { 0x24aa, G_UNICODE_NOT_PRESENT_OFFSET, 6085 }, + { 0x24ab, G_UNICODE_NOT_PRESENT_OFFSET, 6089 }, + { 0x24ac, G_UNICODE_NOT_PRESENT_OFFSET, 6093 }, + { 0x24ad, G_UNICODE_NOT_PRESENT_OFFSET, 6097 }, + { 0x24ae, G_UNICODE_NOT_PRESENT_OFFSET, 6101 }, + { 0x24af, G_UNICODE_NOT_PRESENT_OFFSET, 6105 }, + { 0x24b0, G_UNICODE_NOT_PRESENT_OFFSET, 6109 }, + { 0x24b1, G_UNICODE_NOT_PRESENT_OFFSET, 6113 }, + { 0x24b2, G_UNICODE_NOT_PRESENT_OFFSET, 6117 }, + { 0x24b3, G_UNICODE_NOT_PRESENT_OFFSET, 6121 }, + { 0x24b4, G_UNICODE_NOT_PRESENT_OFFSET, 6125 }, + { 0x24b5, G_UNICODE_NOT_PRESENT_OFFSET, 6129 }, + { 0x24b6, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x24b7, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x24b8, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x24b9, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x24ba, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x24bb, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x24bc, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x24bd, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x24be, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x24bf, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x24c0, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x24c1, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x24c2, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x24c3, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x24c4, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x24c5, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x24c6, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x24c7, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x24c8, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x24c9, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x24ca, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x24cb, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x24cc, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x24cd, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x24ce, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x24cf, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x24d0, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x24d1, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x24d2, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x24d3, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x24d4, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x24d5, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x24d6, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x24d7, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x24d8, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x24d9, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x24da, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x24db, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x24dc, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x24dd, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x24de, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x24df, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x24e0, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x24e1, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x24e2, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x24e3, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x24e4, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x24e5, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x24e6, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x24e7, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x24e8, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x24e9, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x24ea, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0x2a0c, G_UNICODE_NOT_PRESENT_OFFSET, 6139 }, + { 0x2a74, G_UNICODE_NOT_PRESENT_OFFSET, 6152 }, + { 0x2a75, G_UNICODE_NOT_PRESENT_OFFSET, 6156 }, + { 0x2a76, G_UNICODE_NOT_PRESENT_OFFSET, 6159 }, + { 0x2adc, 6163, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2c7c, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x2c7d, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x2d6f, G_UNICODE_NOT_PRESENT_OFFSET, 6169 }, + { 0x2e9f, G_UNICODE_NOT_PRESENT_OFFSET, 6173 }, + { 0x2ef3, G_UNICODE_NOT_PRESENT_OFFSET, 6177 }, + { 0x2f00, G_UNICODE_NOT_PRESENT_OFFSET, 6181 }, + { 0x2f01, G_UNICODE_NOT_PRESENT_OFFSET, 6185 }, + { 0x2f02, G_UNICODE_NOT_PRESENT_OFFSET, 6189 }, + { 0x2f03, G_UNICODE_NOT_PRESENT_OFFSET, 6193 }, + { 0x2f04, G_UNICODE_NOT_PRESENT_OFFSET, 6197 }, + { 0x2f05, G_UNICODE_NOT_PRESENT_OFFSET, 6201 }, + { 0x2f06, G_UNICODE_NOT_PRESENT_OFFSET, 6205 }, + { 0x2f07, G_UNICODE_NOT_PRESENT_OFFSET, 6209 }, + { 0x2f08, G_UNICODE_NOT_PRESENT_OFFSET, 6213 }, + { 0x2f09, G_UNICODE_NOT_PRESENT_OFFSET, 6217 }, + { 0x2f0a, G_UNICODE_NOT_PRESENT_OFFSET, 6221 }, + { 0x2f0b, G_UNICODE_NOT_PRESENT_OFFSET, 6225 }, + { 0x2f0c, G_UNICODE_NOT_PRESENT_OFFSET, 6229 }, + { 0x2f0d, G_UNICODE_NOT_PRESENT_OFFSET, 6233 }, + { 0x2f0e, G_UNICODE_NOT_PRESENT_OFFSET, 6237 }, + { 0x2f0f, G_UNICODE_NOT_PRESENT_OFFSET, 6241 }, + { 0x2f10, G_UNICODE_NOT_PRESENT_OFFSET, 6245 }, + { 0x2f11, G_UNICODE_NOT_PRESENT_OFFSET, 6249 }, + { 0x2f12, G_UNICODE_NOT_PRESENT_OFFSET, 6253 }, + { 0x2f13, G_UNICODE_NOT_PRESENT_OFFSET, 6257 }, + { 0x2f14, G_UNICODE_NOT_PRESENT_OFFSET, 6261 }, + { 0x2f15, G_UNICODE_NOT_PRESENT_OFFSET, 6265 }, + { 0x2f16, G_UNICODE_NOT_PRESENT_OFFSET, 6269 }, + { 0x2f17, G_UNICODE_NOT_PRESENT_OFFSET, 6273 }, + { 0x2f18, G_UNICODE_NOT_PRESENT_OFFSET, 6277 }, + { 0x2f19, G_UNICODE_NOT_PRESENT_OFFSET, 6281 }, + { 0x2f1a, G_UNICODE_NOT_PRESENT_OFFSET, 6285 }, + { 0x2f1b, G_UNICODE_NOT_PRESENT_OFFSET, 6289 }, + { 0x2f1c, G_UNICODE_NOT_PRESENT_OFFSET, 6293 }, + { 0x2f1d, G_UNICODE_NOT_PRESENT_OFFSET, 6297 }, + { 0x2f1e, G_UNICODE_NOT_PRESENT_OFFSET, 6301 }, + { 0x2f1f, G_UNICODE_NOT_PRESENT_OFFSET, 6305 }, + { 0x2f20, G_UNICODE_NOT_PRESENT_OFFSET, 6309 }, + { 0x2f21, G_UNICODE_NOT_PRESENT_OFFSET, 6313 }, + { 0x2f22, G_UNICODE_NOT_PRESENT_OFFSET, 6317 }, + { 0x2f23, G_UNICODE_NOT_PRESENT_OFFSET, 6321 }, + { 0x2f24, G_UNICODE_NOT_PRESENT_OFFSET, 6325 }, + { 0x2f25, G_UNICODE_NOT_PRESENT_OFFSET, 6329 }, + { 0x2f26, G_UNICODE_NOT_PRESENT_OFFSET, 6333 }, + { 0x2f27, G_UNICODE_NOT_PRESENT_OFFSET, 6337 }, + { 0x2f28, G_UNICODE_NOT_PRESENT_OFFSET, 6341 }, + { 0x2f29, G_UNICODE_NOT_PRESENT_OFFSET, 6345 }, + { 0x2f2a, G_UNICODE_NOT_PRESENT_OFFSET, 6349 }, + { 0x2f2b, G_UNICODE_NOT_PRESENT_OFFSET, 6353 }, + { 0x2f2c, G_UNICODE_NOT_PRESENT_OFFSET, 6357 }, + { 0x2f2d, G_UNICODE_NOT_PRESENT_OFFSET, 6361 }, + { 0x2f2e, G_UNICODE_NOT_PRESENT_OFFSET, 6365 }, + { 0x2f2f, G_UNICODE_NOT_PRESENT_OFFSET, 6369 }, + { 0x2f30, G_UNICODE_NOT_PRESENT_OFFSET, 6373 }, + { 0x2f31, G_UNICODE_NOT_PRESENT_OFFSET, 6377 }, + { 0x2f32, G_UNICODE_NOT_PRESENT_OFFSET, 6381 }, + { 0x2f33, G_UNICODE_NOT_PRESENT_OFFSET, 6385 }, + { 0x2f34, G_UNICODE_NOT_PRESENT_OFFSET, 6389 }, + { 0x2f35, G_UNICODE_NOT_PRESENT_OFFSET, 6393 }, + { 0x2f36, G_UNICODE_NOT_PRESENT_OFFSET, 6397 }, + { 0x2f37, G_UNICODE_NOT_PRESENT_OFFSET, 6401 }, + { 0x2f38, G_UNICODE_NOT_PRESENT_OFFSET, 6405 }, + { 0x2f39, G_UNICODE_NOT_PRESENT_OFFSET, 6409 }, + { 0x2f3a, G_UNICODE_NOT_PRESENT_OFFSET, 6413 }, + { 0x2f3b, G_UNICODE_NOT_PRESENT_OFFSET, 6417 }, + { 0x2f3c, G_UNICODE_NOT_PRESENT_OFFSET, 6421 }, + { 0x2f3d, G_UNICODE_NOT_PRESENT_OFFSET, 6425 }, + { 0x2f3e, G_UNICODE_NOT_PRESENT_OFFSET, 6429 }, + { 0x2f3f, G_UNICODE_NOT_PRESENT_OFFSET, 6433 }, + { 0x2f40, G_UNICODE_NOT_PRESENT_OFFSET, 6437 }, + { 0x2f41, G_UNICODE_NOT_PRESENT_OFFSET, 6441 }, + { 0x2f42, G_UNICODE_NOT_PRESENT_OFFSET, 6445 }, + { 0x2f43, G_UNICODE_NOT_PRESENT_OFFSET, 6449 }, + { 0x2f44, G_UNICODE_NOT_PRESENT_OFFSET, 6453 }, + { 0x2f45, G_UNICODE_NOT_PRESENT_OFFSET, 6457 }, + { 0x2f46, G_UNICODE_NOT_PRESENT_OFFSET, 6461 }, + { 0x2f47, G_UNICODE_NOT_PRESENT_OFFSET, 6465 }, + { 0x2f48, G_UNICODE_NOT_PRESENT_OFFSET, 6469 }, + { 0x2f49, G_UNICODE_NOT_PRESENT_OFFSET, 6473 }, + { 0x2f4a, G_UNICODE_NOT_PRESENT_OFFSET, 6477 }, + { 0x2f4b, G_UNICODE_NOT_PRESENT_OFFSET, 6481 }, + { 0x2f4c, G_UNICODE_NOT_PRESENT_OFFSET, 6485 }, + { 0x2f4d, G_UNICODE_NOT_PRESENT_OFFSET, 6489 }, + { 0x2f4e, G_UNICODE_NOT_PRESENT_OFFSET, 6493 }, + { 0x2f4f, G_UNICODE_NOT_PRESENT_OFFSET, 6497 }, + { 0x2f50, G_UNICODE_NOT_PRESENT_OFFSET, 6501 }, + { 0x2f51, G_UNICODE_NOT_PRESENT_OFFSET, 6505 }, + { 0x2f52, G_UNICODE_NOT_PRESENT_OFFSET, 6509 }, + { 0x2f53, G_UNICODE_NOT_PRESENT_OFFSET, 6513 }, + { 0x2f54, G_UNICODE_NOT_PRESENT_OFFSET, 6517 }, + { 0x2f55, G_UNICODE_NOT_PRESENT_OFFSET, 6521 }, + { 0x2f56, G_UNICODE_NOT_PRESENT_OFFSET, 6525 }, + { 0x2f57, G_UNICODE_NOT_PRESENT_OFFSET, 6529 }, + { 0x2f58, G_UNICODE_NOT_PRESENT_OFFSET, 6533 }, + { 0x2f59, G_UNICODE_NOT_PRESENT_OFFSET, 6537 }, + { 0x2f5a, G_UNICODE_NOT_PRESENT_OFFSET, 6541 }, + { 0x2f5b, G_UNICODE_NOT_PRESENT_OFFSET, 6545 }, + { 0x2f5c, G_UNICODE_NOT_PRESENT_OFFSET, 6549 }, + { 0x2f5d, G_UNICODE_NOT_PRESENT_OFFSET, 6553 }, + { 0x2f5e, G_UNICODE_NOT_PRESENT_OFFSET, 6557 }, + { 0x2f5f, G_UNICODE_NOT_PRESENT_OFFSET, 6561 }, + { 0x2f60, G_UNICODE_NOT_PRESENT_OFFSET, 6565 }, + { 0x2f61, G_UNICODE_NOT_PRESENT_OFFSET, 6569 }, + { 0x2f62, G_UNICODE_NOT_PRESENT_OFFSET, 6573 }, + { 0x2f63, G_UNICODE_NOT_PRESENT_OFFSET, 6577 }, + { 0x2f64, G_UNICODE_NOT_PRESENT_OFFSET, 6581 }, + { 0x2f65, G_UNICODE_NOT_PRESENT_OFFSET, 6585 }, + { 0x2f66, G_UNICODE_NOT_PRESENT_OFFSET, 6589 }, + { 0x2f67, G_UNICODE_NOT_PRESENT_OFFSET, 6593 }, + { 0x2f68, G_UNICODE_NOT_PRESENT_OFFSET, 6597 }, + { 0x2f69, G_UNICODE_NOT_PRESENT_OFFSET, 6601 }, + { 0x2f6a, G_UNICODE_NOT_PRESENT_OFFSET, 6605 }, + { 0x2f6b, G_UNICODE_NOT_PRESENT_OFFSET, 6609 }, + { 0x2f6c, G_UNICODE_NOT_PRESENT_OFFSET, 6613 }, + { 0x2f6d, G_UNICODE_NOT_PRESENT_OFFSET, 6617 }, + { 0x2f6e, G_UNICODE_NOT_PRESENT_OFFSET, 6621 }, + { 0x2f6f, G_UNICODE_NOT_PRESENT_OFFSET, 6625 }, + { 0x2f70, G_UNICODE_NOT_PRESENT_OFFSET, 6629 }, + { 0x2f71, G_UNICODE_NOT_PRESENT_OFFSET, 6633 }, + { 0x2f72, G_UNICODE_NOT_PRESENT_OFFSET, 6637 }, + { 0x2f73, G_UNICODE_NOT_PRESENT_OFFSET, 6641 }, + { 0x2f74, G_UNICODE_NOT_PRESENT_OFFSET, 6645 }, + { 0x2f75, G_UNICODE_NOT_PRESENT_OFFSET, 6649 }, + { 0x2f76, G_UNICODE_NOT_PRESENT_OFFSET, 6653 }, + { 0x2f77, G_UNICODE_NOT_PRESENT_OFFSET, 6657 }, + { 0x2f78, G_UNICODE_NOT_PRESENT_OFFSET, 6661 }, + { 0x2f79, G_UNICODE_NOT_PRESENT_OFFSET, 6665 }, + { 0x2f7a, G_UNICODE_NOT_PRESENT_OFFSET, 6669 }, + { 0x2f7b, G_UNICODE_NOT_PRESENT_OFFSET, 6673 }, + { 0x2f7c, G_UNICODE_NOT_PRESENT_OFFSET, 6677 }, + { 0x2f7d, G_UNICODE_NOT_PRESENT_OFFSET, 6681 }, + { 0x2f7e, G_UNICODE_NOT_PRESENT_OFFSET, 6685 }, + { 0x2f7f, G_UNICODE_NOT_PRESENT_OFFSET, 6689 }, + { 0x2f80, G_UNICODE_NOT_PRESENT_OFFSET, 6693 }, + { 0x2f81, G_UNICODE_NOT_PRESENT_OFFSET, 6697 }, + { 0x2f82, G_UNICODE_NOT_PRESENT_OFFSET, 6701 }, + { 0x2f83, G_UNICODE_NOT_PRESENT_OFFSET, 6705 }, + { 0x2f84, G_UNICODE_NOT_PRESENT_OFFSET, 6709 }, + { 0x2f85, G_UNICODE_NOT_PRESENT_OFFSET, 6713 }, + { 0x2f86, G_UNICODE_NOT_PRESENT_OFFSET, 6717 }, + { 0x2f87, G_UNICODE_NOT_PRESENT_OFFSET, 6721 }, + { 0x2f88, G_UNICODE_NOT_PRESENT_OFFSET, 6725 }, + { 0x2f89, G_UNICODE_NOT_PRESENT_OFFSET, 6729 }, + { 0x2f8a, G_UNICODE_NOT_PRESENT_OFFSET, 6733 }, + { 0x2f8b, G_UNICODE_NOT_PRESENT_OFFSET, 6737 }, + { 0x2f8c, G_UNICODE_NOT_PRESENT_OFFSET, 6741 }, + { 0x2f8d, G_UNICODE_NOT_PRESENT_OFFSET, 6745 }, + { 0x2f8e, G_UNICODE_NOT_PRESENT_OFFSET, 6749 }, + { 0x2f8f, G_UNICODE_NOT_PRESENT_OFFSET, 6753 }, + { 0x2f90, G_UNICODE_NOT_PRESENT_OFFSET, 6757 }, + { 0x2f91, G_UNICODE_NOT_PRESENT_OFFSET, 6761 }, + { 0x2f92, G_UNICODE_NOT_PRESENT_OFFSET, 6765 }, + { 0x2f93, G_UNICODE_NOT_PRESENT_OFFSET, 6769 }, + { 0x2f94, G_UNICODE_NOT_PRESENT_OFFSET, 6773 }, + { 0x2f95, G_UNICODE_NOT_PRESENT_OFFSET, 6777 }, + { 0x2f96, G_UNICODE_NOT_PRESENT_OFFSET, 6781 }, + { 0x2f97, G_UNICODE_NOT_PRESENT_OFFSET, 6785 }, + { 0x2f98, G_UNICODE_NOT_PRESENT_OFFSET, 6789 }, + { 0x2f99, G_UNICODE_NOT_PRESENT_OFFSET, 6793 }, + { 0x2f9a, G_UNICODE_NOT_PRESENT_OFFSET, 6797 }, + { 0x2f9b, G_UNICODE_NOT_PRESENT_OFFSET, 6801 }, + { 0x2f9c, G_UNICODE_NOT_PRESENT_OFFSET, 6805 }, + { 0x2f9d, G_UNICODE_NOT_PRESENT_OFFSET, 6809 }, + { 0x2f9e, G_UNICODE_NOT_PRESENT_OFFSET, 6813 }, + { 0x2f9f, G_UNICODE_NOT_PRESENT_OFFSET, 6817 }, + { 0x2fa0, G_UNICODE_NOT_PRESENT_OFFSET, 6821 }, + { 0x2fa1, G_UNICODE_NOT_PRESENT_OFFSET, 6825 }, + { 0x2fa2, G_UNICODE_NOT_PRESENT_OFFSET, 6829 }, + { 0x2fa3, G_UNICODE_NOT_PRESENT_OFFSET, 6833 }, + { 0x2fa4, G_UNICODE_NOT_PRESENT_OFFSET, 6837 }, + { 0x2fa5, G_UNICODE_NOT_PRESENT_OFFSET, 6841 }, + { 0x2fa6, G_UNICODE_NOT_PRESENT_OFFSET, 6845 }, + { 0x2fa7, G_UNICODE_NOT_PRESENT_OFFSET, 6849 }, + { 0x2fa8, G_UNICODE_NOT_PRESENT_OFFSET, 6853 }, + { 0x2fa9, G_UNICODE_NOT_PRESENT_OFFSET, 6857 }, + { 0x2faa, G_UNICODE_NOT_PRESENT_OFFSET, 6861 }, + { 0x2fab, G_UNICODE_NOT_PRESENT_OFFSET, 6865 }, + { 0x2fac, G_UNICODE_NOT_PRESENT_OFFSET, 6869 }, + { 0x2fad, G_UNICODE_NOT_PRESENT_OFFSET, 6873 }, + { 0x2fae, G_UNICODE_NOT_PRESENT_OFFSET, 6877 }, + { 0x2faf, G_UNICODE_NOT_PRESENT_OFFSET, 6881 }, + { 0x2fb0, G_UNICODE_NOT_PRESENT_OFFSET, 6885 }, + { 0x2fb1, G_UNICODE_NOT_PRESENT_OFFSET, 6889 }, + { 0x2fb2, G_UNICODE_NOT_PRESENT_OFFSET, 6893 }, + { 0x2fb3, G_UNICODE_NOT_PRESENT_OFFSET, 6897 }, + { 0x2fb4, G_UNICODE_NOT_PRESENT_OFFSET, 6901 }, + { 0x2fb5, G_UNICODE_NOT_PRESENT_OFFSET, 6905 }, + { 0x2fb6, G_UNICODE_NOT_PRESENT_OFFSET, 6909 }, + { 0x2fb7, G_UNICODE_NOT_PRESENT_OFFSET, 6913 }, + { 0x2fb8, G_UNICODE_NOT_PRESENT_OFFSET, 6917 }, + { 0x2fb9, G_UNICODE_NOT_PRESENT_OFFSET, 6921 }, + { 0x2fba, G_UNICODE_NOT_PRESENT_OFFSET, 6925 }, + { 0x2fbb, G_UNICODE_NOT_PRESENT_OFFSET, 6929 }, + { 0x2fbc, G_UNICODE_NOT_PRESENT_OFFSET, 6933 }, + { 0x2fbd, G_UNICODE_NOT_PRESENT_OFFSET, 6937 }, + { 0x2fbe, G_UNICODE_NOT_PRESENT_OFFSET, 6941 }, + { 0x2fbf, G_UNICODE_NOT_PRESENT_OFFSET, 6945 }, + { 0x2fc0, G_UNICODE_NOT_PRESENT_OFFSET, 6949 }, + { 0x2fc1, G_UNICODE_NOT_PRESENT_OFFSET, 6953 }, + { 0x2fc2, G_UNICODE_NOT_PRESENT_OFFSET, 6957 }, + { 0x2fc3, G_UNICODE_NOT_PRESENT_OFFSET, 6961 }, + { 0x2fc4, G_UNICODE_NOT_PRESENT_OFFSET, 6965 }, + { 0x2fc5, G_UNICODE_NOT_PRESENT_OFFSET, 6969 }, + { 0x2fc6, G_UNICODE_NOT_PRESENT_OFFSET, 6973 }, + { 0x2fc7, G_UNICODE_NOT_PRESENT_OFFSET, 6977 }, + { 0x2fc8, G_UNICODE_NOT_PRESENT_OFFSET, 6981 }, + { 0x2fc9, G_UNICODE_NOT_PRESENT_OFFSET, 6985 }, + { 0x2fca, G_UNICODE_NOT_PRESENT_OFFSET, 6989 }, + { 0x2fcb, G_UNICODE_NOT_PRESENT_OFFSET, 6993 }, + { 0x2fcc, G_UNICODE_NOT_PRESENT_OFFSET, 6997 }, + { 0x2fcd, G_UNICODE_NOT_PRESENT_OFFSET, 7001 }, + { 0x2fce, G_UNICODE_NOT_PRESENT_OFFSET, 7005 }, + { 0x2fcf, G_UNICODE_NOT_PRESENT_OFFSET, 7009 }, + { 0x2fd0, G_UNICODE_NOT_PRESENT_OFFSET, 7013 }, + { 0x2fd1, G_UNICODE_NOT_PRESENT_OFFSET, 7017 }, + { 0x2fd2, G_UNICODE_NOT_PRESENT_OFFSET, 7021 }, + { 0x2fd3, G_UNICODE_NOT_PRESENT_OFFSET, 7025 }, + { 0x2fd4, G_UNICODE_NOT_PRESENT_OFFSET, 7029 }, + { 0x2fd5, G_UNICODE_NOT_PRESENT_OFFSET, 7033 }, + { 0x3000, G_UNICODE_NOT_PRESENT_OFFSET, 0 }, + { 0x3036, G_UNICODE_NOT_PRESENT_OFFSET, 7037 }, + { 0x3038, G_UNICODE_NOT_PRESENT_OFFSET, 6273 }, + { 0x3039, G_UNICODE_NOT_PRESENT_OFFSET, 7041 }, + { 0x303a, G_UNICODE_NOT_PRESENT_OFFSET, 7045 }, + { 0x304c, 7049, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x304e, 7056, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3050, 7063, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3052, 7070, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3054, 7077, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3056, 7084, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3058, 7091, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x305a, 7098, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x305c, 7105, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x305e, 7112, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3060, 7119, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3062, 7126, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3065, 7133, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3067, 7140, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3069, 7147, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3070, 7154, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3071, 7161, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3073, 7168, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3074, 7175, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3076, 7182, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3077, 7189, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3079, 7196, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x307a, 7203, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x307c, 7210, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x307d, 7217, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x3094, 7224, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x309b, G_UNICODE_NOT_PRESENT_OFFSET, 7231 }, + { 0x309c, G_UNICODE_NOT_PRESENT_OFFSET, 7236 }, + { 0x309e, 7241, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x309f, G_UNICODE_NOT_PRESENT_OFFSET, 7248 }, + { 0x30ac, 7255, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30ae, 7262, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30b0, 7269, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30b2, 7276, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30b4, 7283, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30b6, 7290, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30b8, 7297, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30ba, 7304, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30bc, 7311, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30be, 7318, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30c0, 7325, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30c2, 7332, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30c5, 7339, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30c7, 7346, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30c9, 7353, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30d0, 7360, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30d1, 7367, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30d3, 7374, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30d4, 7381, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30d6, 7388, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30d7, 7395, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30d9, 7402, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30da, 7409, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30dc, 7416, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30dd, 7423, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30f4, 7430, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30f7, 7437, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30f8, 7444, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30f9, 7451, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30fa, 7458, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30fe, 7465, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x30ff, G_UNICODE_NOT_PRESENT_OFFSET, 7472 }, + { 0x3131, G_UNICODE_NOT_PRESENT_OFFSET, 7479 }, + { 0x3132, G_UNICODE_NOT_PRESENT_OFFSET, 7483 }, + { 0x3133, G_UNICODE_NOT_PRESENT_OFFSET, 7487 }, + { 0x3134, G_UNICODE_NOT_PRESENT_OFFSET, 7491 }, + { 0x3135, G_UNICODE_NOT_PRESENT_OFFSET, 7495 }, + { 0x3136, G_UNICODE_NOT_PRESENT_OFFSET, 7499 }, + { 0x3137, G_UNICODE_NOT_PRESENT_OFFSET, 7503 }, + { 0x3138, G_UNICODE_NOT_PRESENT_OFFSET, 7507 }, + { 0x3139, G_UNICODE_NOT_PRESENT_OFFSET, 7511 }, + { 0x313a, G_UNICODE_NOT_PRESENT_OFFSET, 7515 }, + { 0x313b, G_UNICODE_NOT_PRESENT_OFFSET, 7519 }, + { 0x313c, G_UNICODE_NOT_PRESENT_OFFSET, 7523 }, + { 0x313d, G_UNICODE_NOT_PRESENT_OFFSET, 7527 }, + { 0x313e, G_UNICODE_NOT_PRESENT_OFFSET, 7531 }, + { 0x313f, G_UNICODE_NOT_PRESENT_OFFSET, 7535 }, + { 0x3140, G_UNICODE_NOT_PRESENT_OFFSET, 7539 }, + { 0x3141, G_UNICODE_NOT_PRESENT_OFFSET, 7543 }, + { 0x3142, G_UNICODE_NOT_PRESENT_OFFSET, 7547 }, + { 0x3143, G_UNICODE_NOT_PRESENT_OFFSET, 7551 }, + { 0x3144, G_UNICODE_NOT_PRESENT_OFFSET, 7555 }, + { 0x3145, G_UNICODE_NOT_PRESENT_OFFSET, 7559 }, + { 0x3146, G_UNICODE_NOT_PRESENT_OFFSET, 7563 }, + { 0x3147, G_UNICODE_NOT_PRESENT_OFFSET, 7567 }, + { 0x3148, G_UNICODE_NOT_PRESENT_OFFSET, 7571 }, + { 0x3149, G_UNICODE_NOT_PRESENT_OFFSET, 7575 }, + { 0x314a, G_UNICODE_NOT_PRESENT_OFFSET, 7579 }, + { 0x314b, G_UNICODE_NOT_PRESENT_OFFSET, 7583 }, + { 0x314c, G_UNICODE_NOT_PRESENT_OFFSET, 7587 }, + { 0x314d, G_UNICODE_NOT_PRESENT_OFFSET, 7591 }, + { 0x314e, G_UNICODE_NOT_PRESENT_OFFSET, 7595 }, + { 0x314f, G_UNICODE_NOT_PRESENT_OFFSET, 7599 }, + { 0x3150, G_UNICODE_NOT_PRESENT_OFFSET, 7603 }, + { 0x3151, G_UNICODE_NOT_PRESENT_OFFSET, 7607 }, + { 0x3152, G_UNICODE_NOT_PRESENT_OFFSET, 7611 }, + { 0x3153, G_UNICODE_NOT_PRESENT_OFFSET, 7615 }, + { 0x3154, G_UNICODE_NOT_PRESENT_OFFSET, 7619 }, + { 0x3155, G_UNICODE_NOT_PRESENT_OFFSET, 7623 }, + { 0x3156, G_UNICODE_NOT_PRESENT_OFFSET, 7627 }, + { 0x3157, G_UNICODE_NOT_PRESENT_OFFSET, 7631 }, + { 0x3158, G_UNICODE_NOT_PRESENT_OFFSET, 7635 }, + { 0x3159, G_UNICODE_NOT_PRESENT_OFFSET, 7639 }, + { 0x315a, G_UNICODE_NOT_PRESENT_OFFSET, 7643 }, + { 0x315b, G_UNICODE_NOT_PRESENT_OFFSET, 7647 }, + { 0x315c, G_UNICODE_NOT_PRESENT_OFFSET, 7651 }, + { 0x315d, G_UNICODE_NOT_PRESENT_OFFSET, 7655 }, + { 0x315e, G_UNICODE_NOT_PRESENT_OFFSET, 7659 }, + { 0x315f, G_UNICODE_NOT_PRESENT_OFFSET, 7663 }, + { 0x3160, G_UNICODE_NOT_PRESENT_OFFSET, 7667 }, + { 0x3161, G_UNICODE_NOT_PRESENT_OFFSET, 7671 }, + { 0x3162, G_UNICODE_NOT_PRESENT_OFFSET, 7675 }, + { 0x3163, G_UNICODE_NOT_PRESENT_OFFSET, 7679 }, + { 0x3164, G_UNICODE_NOT_PRESENT_OFFSET, 7683 }, + { 0x3165, G_UNICODE_NOT_PRESENT_OFFSET, 7687 }, + { 0x3166, G_UNICODE_NOT_PRESENT_OFFSET, 7691 }, + { 0x3167, G_UNICODE_NOT_PRESENT_OFFSET, 7695 }, + { 0x3168, G_UNICODE_NOT_PRESENT_OFFSET, 7699 }, + { 0x3169, G_UNICODE_NOT_PRESENT_OFFSET, 7703 }, + { 0x316a, G_UNICODE_NOT_PRESENT_OFFSET, 7707 }, + { 0x316b, G_UNICODE_NOT_PRESENT_OFFSET, 7711 }, + { 0x316c, G_UNICODE_NOT_PRESENT_OFFSET, 7715 }, + { 0x316d, G_UNICODE_NOT_PRESENT_OFFSET, 7719 }, + { 0x316e, G_UNICODE_NOT_PRESENT_OFFSET, 7723 }, + { 0x316f, G_UNICODE_NOT_PRESENT_OFFSET, 7727 }, + { 0x3170, G_UNICODE_NOT_PRESENT_OFFSET, 7731 }, + { 0x3171, G_UNICODE_NOT_PRESENT_OFFSET, 7735 }, + { 0x3172, G_UNICODE_NOT_PRESENT_OFFSET, 7739 }, + { 0x3173, G_UNICODE_NOT_PRESENT_OFFSET, 7743 }, + { 0x3174, G_UNICODE_NOT_PRESENT_OFFSET, 7747 }, + { 0x3175, G_UNICODE_NOT_PRESENT_OFFSET, 7751 }, + { 0x3176, G_UNICODE_NOT_PRESENT_OFFSET, 7755 }, + { 0x3177, G_UNICODE_NOT_PRESENT_OFFSET, 7759 }, + { 0x3178, G_UNICODE_NOT_PRESENT_OFFSET, 7763 }, + { 0x3179, G_UNICODE_NOT_PRESENT_OFFSET, 7767 }, + { 0x317a, G_UNICODE_NOT_PRESENT_OFFSET, 7771 }, + { 0x317b, G_UNICODE_NOT_PRESENT_OFFSET, 7775 }, + { 0x317c, G_UNICODE_NOT_PRESENT_OFFSET, 7779 }, + { 0x317d, G_UNICODE_NOT_PRESENT_OFFSET, 7783 }, + { 0x317e, G_UNICODE_NOT_PRESENT_OFFSET, 7787 }, + { 0x317f, G_UNICODE_NOT_PRESENT_OFFSET, 7791 }, + { 0x3180, G_UNICODE_NOT_PRESENT_OFFSET, 7795 }, + { 0x3181, G_UNICODE_NOT_PRESENT_OFFSET, 7799 }, + { 0x3182, G_UNICODE_NOT_PRESENT_OFFSET, 7803 }, + { 0x3183, G_UNICODE_NOT_PRESENT_OFFSET, 7807 }, + { 0x3184, G_UNICODE_NOT_PRESENT_OFFSET, 7811 }, + { 0x3185, G_UNICODE_NOT_PRESENT_OFFSET, 7815 }, + { 0x3186, G_UNICODE_NOT_PRESENT_OFFSET, 7819 }, + { 0x3187, G_UNICODE_NOT_PRESENT_OFFSET, 7823 }, + { 0x3188, G_UNICODE_NOT_PRESENT_OFFSET, 7827 }, + { 0x3189, G_UNICODE_NOT_PRESENT_OFFSET, 7831 }, + { 0x318a, G_UNICODE_NOT_PRESENT_OFFSET, 7835 }, + { 0x318b, G_UNICODE_NOT_PRESENT_OFFSET, 7839 }, + { 0x318c, G_UNICODE_NOT_PRESENT_OFFSET, 7843 }, + { 0x318d, G_UNICODE_NOT_PRESENT_OFFSET, 7847 }, + { 0x318e, G_UNICODE_NOT_PRESENT_OFFSET, 7851 }, + { 0x3192, G_UNICODE_NOT_PRESENT_OFFSET, 6181 }, + { 0x3193, G_UNICODE_NOT_PRESENT_OFFSET, 6205 }, + { 0x3194, G_UNICODE_NOT_PRESENT_OFFSET, 7855 }, + { 0x3195, G_UNICODE_NOT_PRESENT_OFFSET, 7859 }, + { 0x3196, G_UNICODE_NOT_PRESENT_OFFSET, 7863 }, + { 0x3197, G_UNICODE_NOT_PRESENT_OFFSET, 7867 }, + { 0x3198, G_UNICODE_NOT_PRESENT_OFFSET, 7871 }, + { 0x3199, G_UNICODE_NOT_PRESENT_OFFSET, 7875 }, + { 0x319a, G_UNICODE_NOT_PRESENT_OFFSET, 6197 }, + { 0x319b, G_UNICODE_NOT_PRESENT_OFFSET, 7879 }, + { 0x319c, G_UNICODE_NOT_PRESENT_OFFSET, 7883 }, + { 0x319d, G_UNICODE_NOT_PRESENT_OFFSET, 7887 }, + { 0x319e, G_UNICODE_NOT_PRESENT_OFFSET, 7891 }, + { 0x319f, G_UNICODE_NOT_PRESENT_OFFSET, 6213 }, + { 0x3200, G_UNICODE_NOT_PRESENT_OFFSET, 7895 }, + { 0x3201, G_UNICODE_NOT_PRESENT_OFFSET, 7901 }, + { 0x3202, G_UNICODE_NOT_PRESENT_OFFSET, 7907 }, + { 0x3203, G_UNICODE_NOT_PRESENT_OFFSET, 7913 }, + { 0x3204, G_UNICODE_NOT_PRESENT_OFFSET, 7919 }, + { 0x3205, G_UNICODE_NOT_PRESENT_OFFSET, 7925 }, + { 0x3206, G_UNICODE_NOT_PRESENT_OFFSET, 7931 }, + { 0x3207, G_UNICODE_NOT_PRESENT_OFFSET, 7937 }, + { 0x3208, G_UNICODE_NOT_PRESENT_OFFSET, 7943 }, + { 0x3209, G_UNICODE_NOT_PRESENT_OFFSET, 7949 }, + { 0x320a, G_UNICODE_NOT_PRESENT_OFFSET, 7955 }, + { 0x320b, G_UNICODE_NOT_PRESENT_OFFSET, 7961 }, + { 0x320c, G_UNICODE_NOT_PRESENT_OFFSET, 7967 }, + { 0x320d, G_UNICODE_NOT_PRESENT_OFFSET, 7973 }, + { 0x320e, G_UNICODE_NOT_PRESENT_OFFSET, 7979 }, + { 0x320f, G_UNICODE_NOT_PRESENT_OFFSET, 7988 }, + { 0x3210, G_UNICODE_NOT_PRESENT_OFFSET, 7997 }, + { 0x3211, G_UNICODE_NOT_PRESENT_OFFSET, 8006 }, + { 0x3212, G_UNICODE_NOT_PRESENT_OFFSET, 8015 }, + { 0x3213, G_UNICODE_NOT_PRESENT_OFFSET, 8024 }, + { 0x3214, G_UNICODE_NOT_PRESENT_OFFSET, 8033 }, + { 0x3215, G_UNICODE_NOT_PRESENT_OFFSET, 8042 }, + { 0x3216, G_UNICODE_NOT_PRESENT_OFFSET, 8051 }, + { 0x3217, G_UNICODE_NOT_PRESENT_OFFSET, 8060 }, + { 0x3218, G_UNICODE_NOT_PRESENT_OFFSET, 8069 }, + { 0x3219, G_UNICODE_NOT_PRESENT_OFFSET, 8078 }, + { 0x321a, G_UNICODE_NOT_PRESENT_OFFSET, 8087 }, + { 0x321b, G_UNICODE_NOT_PRESENT_OFFSET, 8096 }, + { 0x321c, G_UNICODE_NOT_PRESENT_OFFSET, 8105 }, + { 0x321d, G_UNICODE_NOT_PRESENT_OFFSET, 8114 }, + { 0x321e, G_UNICODE_NOT_PRESENT_OFFSET, 8132 }, + { 0x3220, G_UNICODE_NOT_PRESENT_OFFSET, 8147 }, + { 0x3221, G_UNICODE_NOT_PRESENT_OFFSET, 8153 }, + { 0x3222, G_UNICODE_NOT_PRESENT_OFFSET, 8159 }, + { 0x3223, G_UNICODE_NOT_PRESENT_OFFSET, 8165 }, + { 0x3224, G_UNICODE_NOT_PRESENT_OFFSET, 8171 }, + { 0x3225, G_UNICODE_NOT_PRESENT_OFFSET, 8177 }, + { 0x3226, G_UNICODE_NOT_PRESENT_OFFSET, 8183 }, + { 0x3227, G_UNICODE_NOT_PRESENT_OFFSET, 8189 }, + { 0x3228, G_UNICODE_NOT_PRESENT_OFFSET, 8195 }, + { 0x3229, G_UNICODE_NOT_PRESENT_OFFSET, 8201 }, + { 0x322a, G_UNICODE_NOT_PRESENT_OFFSET, 8207 }, + { 0x322b, G_UNICODE_NOT_PRESENT_OFFSET, 8213 }, + { 0x322c, G_UNICODE_NOT_PRESENT_OFFSET, 8219 }, + { 0x322d, G_UNICODE_NOT_PRESENT_OFFSET, 8225 }, + { 0x322e, G_UNICODE_NOT_PRESENT_OFFSET, 8231 }, + { 0x322f, G_UNICODE_NOT_PRESENT_OFFSET, 8237 }, + { 0x3230, G_UNICODE_NOT_PRESENT_OFFSET, 8243 }, + { 0x3231, G_UNICODE_NOT_PRESENT_OFFSET, 8249 }, + { 0x3232, G_UNICODE_NOT_PRESENT_OFFSET, 8255 }, + { 0x3233, G_UNICODE_NOT_PRESENT_OFFSET, 8261 }, + { 0x3234, G_UNICODE_NOT_PRESENT_OFFSET, 8267 }, + { 0x3235, G_UNICODE_NOT_PRESENT_OFFSET, 8273 }, + { 0x3236, G_UNICODE_NOT_PRESENT_OFFSET, 8279 }, + { 0x3237, G_UNICODE_NOT_PRESENT_OFFSET, 8285 }, + { 0x3238, G_UNICODE_NOT_PRESENT_OFFSET, 8291 }, + { 0x3239, G_UNICODE_NOT_PRESENT_OFFSET, 8297 }, + { 0x323a, G_UNICODE_NOT_PRESENT_OFFSET, 8303 }, + { 0x323b, G_UNICODE_NOT_PRESENT_OFFSET, 8309 }, + { 0x323c, G_UNICODE_NOT_PRESENT_OFFSET, 8315 }, + { 0x323d, G_UNICODE_NOT_PRESENT_OFFSET, 8321 }, + { 0x323e, G_UNICODE_NOT_PRESENT_OFFSET, 8327 }, + { 0x323f, G_UNICODE_NOT_PRESENT_OFFSET, 8333 }, + { 0x3240, G_UNICODE_NOT_PRESENT_OFFSET, 8339 }, + { 0x3241, G_UNICODE_NOT_PRESENT_OFFSET, 8345 }, + { 0x3242, G_UNICODE_NOT_PRESENT_OFFSET, 8351 }, + { 0x3243, G_UNICODE_NOT_PRESENT_OFFSET, 8357 }, + { 0x3244, G_UNICODE_NOT_PRESENT_OFFSET, 8363 }, + { 0x3245, G_UNICODE_NOT_PRESENT_OFFSET, 8367 }, + { 0x3246, G_UNICODE_NOT_PRESENT_OFFSET, 6445 }, + { 0x3247, G_UNICODE_NOT_PRESENT_OFFSET, 8371 }, + { 0x3250, G_UNICODE_NOT_PRESENT_OFFSET, 8375 }, + { 0x3251, G_UNICODE_NOT_PRESENT_OFFSET, 8379 }, + { 0x3252, G_UNICODE_NOT_PRESENT_OFFSET, 8382 }, + { 0x3253, G_UNICODE_NOT_PRESENT_OFFSET, 8385 }, + { 0x3254, G_UNICODE_NOT_PRESENT_OFFSET, 8388 }, + { 0x3255, G_UNICODE_NOT_PRESENT_OFFSET, 8391 }, + { 0x3256, G_UNICODE_NOT_PRESENT_OFFSET, 8394 }, + { 0x3257, G_UNICODE_NOT_PRESENT_OFFSET, 8397 }, + { 0x3258, G_UNICODE_NOT_PRESENT_OFFSET, 8400 }, + { 0x3259, G_UNICODE_NOT_PRESENT_OFFSET, 8403 }, + { 0x325a, G_UNICODE_NOT_PRESENT_OFFSET, 8406 }, + { 0x325b, G_UNICODE_NOT_PRESENT_OFFSET, 8409 }, + { 0x325c, G_UNICODE_NOT_PRESENT_OFFSET, 8412 }, + { 0x325d, G_UNICODE_NOT_PRESENT_OFFSET, 8415 }, + { 0x325e, G_UNICODE_NOT_PRESENT_OFFSET, 8418 }, + { 0x325f, G_UNICODE_NOT_PRESENT_OFFSET, 8421 }, + { 0x3260, G_UNICODE_NOT_PRESENT_OFFSET, 7479 }, + { 0x3261, G_UNICODE_NOT_PRESENT_OFFSET, 7491 }, + { 0x3262, G_UNICODE_NOT_PRESENT_OFFSET, 7503 }, + { 0x3263, G_UNICODE_NOT_PRESENT_OFFSET, 7511 }, + { 0x3264, G_UNICODE_NOT_PRESENT_OFFSET, 7543 }, + { 0x3265, G_UNICODE_NOT_PRESENT_OFFSET, 7547 }, + { 0x3266, G_UNICODE_NOT_PRESENT_OFFSET, 7559 }, + { 0x3267, G_UNICODE_NOT_PRESENT_OFFSET, 7567 }, + { 0x3268, G_UNICODE_NOT_PRESENT_OFFSET, 7571 }, + { 0x3269, G_UNICODE_NOT_PRESENT_OFFSET, 7579 }, + { 0x326a, G_UNICODE_NOT_PRESENT_OFFSET, 7583 }, + { 0x326b, G_UNICODE_NOT_PRESENT_OFFSET, 7587 }, + { 0x326c, G_UNICODE_NOT_PRESENT_OFFSET, 7591 }, + { 0x326d, G_UNICODE_NOT_PRESENT_OFFSET, 7595 }, + { 0x326e, G_UNICODE_NOT_PRESENT_OFFSET, 8424 }, + { 0x326f, G_UNICODE_NOT_PRESENT_OFFSET, 8431 }, + { 0x3270, G_UNICODE_NOT_PRESENT_OFFSET, 8438 }, + { 0x3271, G_UNICODE_NOT_PRESENT_OFFSET, 8445 }, + { 0x3272, G_UNICODE_NOT_PRESENT_OFFSET, 8452 }, + { 0x3273, G_UNICODE_NOT_PRESENT_OFFSET, 8459 }, + { 0x3274, G_UNICODE_NOT_PRESENT_OFFSET, 8466 }, + { 0x3275, G_UNICODE_NOT_PRESENT_OFFSET, 8473 }, + { 0x3276, G_UNICODE_NOT_PRESENT_OFFSET, 8480 }, + { 0x3277, G_UNICODE_NOT_PRESENT_OFFSET, 8487 }, + { 0x3278, G_UNICODE_NOT_PRESENT_OFFSET, 8494 }, + { 0x3279, G_UNICODE_NOT_PRESENT_OFFSET, 8501 }, + { 0x327a, G_UNICODE_NOT_PRESENT_OFFSET, 8508 }, + { 0x327b, G_UNICODE_NOT_PRESENT_OFFSET, 8515 }, + { 0x327c, G_UNICODE_NOT_PRESENT_OFFSET, 8522 }, + { 0x327d, G_UNICODE_NOT_PRESENT_OFFSET, 8538 }, + { 0x327e, G_UNICODE_NOT_PRESENT_OFFSET, 8551 }, + { 0x3280, G_UNICODE_NOT_PRESENT_OFFSET, 6181 }, + { 0x3281, G_UNICODE_NOT_PRESENT_OFFSET, 6205 }, + { 0x3282, G_UNICODE_NOT_PRESENT_OFFSET, 7855 }, + { 0x3283, G_UNICODE_NOT_PRESENT_OFFSET, 7859 }, + { 0x3284, G_UNICODE_NOT_PRESENT_OFFSET, 8558 }, + { 0x3285, G_UNICODE_NOT_PRESENT_OFFSET, 8562 }, + { 0x3286, G_UNICODE_NOT_PRESENT_OFFSET, 8566 }, + { 0x3287, G_UNICODE_NOT_PRESENT_OFFSET, 6225 }, + { 0x3288, G_UNICODE_NOT_PRESENT_OFFSET, 8570 }, + { 0x3289, G_UNICODE_NOT_PRESENT_OFFSET, 6273 }, + { 0x328a, G_UNICODE_NOT_PRESENT_OFFSET, 6473 }, + { 0x328b, G_UNICODE_NOT_PRESENT_OFFSET, 6521 }, + { 0x328c, G_UNICODE_NOT_PRESENT_OFFSET, 6517 }, + { 0x328d, G_UNICODE_NOT_PRESENT_OFFSET, 6477 }, + { 0x328e, G_UNICODE_NOT_PRESENT_OFFSET, 6845 }, + { 0x328f, G_UNICODE_NOT_PRESENT_OFFSET, 6305 }, + { 0x3290, G_UNICODE_NOT_PRESENT_OFFSET, 6465 }, + { 0x3291, G_UNICODE_NOT_PRESENT_OFFSET, 8574 }, + { 0x3292, G_UNICODE_NOT_PRESENT_OFFSET, 8578 }, + { 0x3293, G_UNICODE_NOT_PRESENT_OFFSET, 8582 }, + { 0x3294, G_UNICODE_NOT_PRESENT_OFFSET, 8586 }, + { 0x3295, G_UNICODE_NOT_PRESENT_OFFSET, 8590 }, + { 0x3296, G_UNICODE_NOT_PRESENT_OFFSET, 8594 }, + { 0x3297, G_UNICODE_NOT_PRESENT_OFFSET, 8598 }, + { 0x3298, G_UNICODE_NOT_PRESENT_OFFSET, 8602 }, + { 0x3299, G_UNICODE_NOT_PRESENT_OFFSET, 8606 }, + { 0x329a, G_UNICODE_NOT_PRESENT_OFFSET, 8610 }, + { 0x329b, G_UNICODE_NOT_PRESENT_OFFSET, 6329 }, + { 0x329c, G_UNICODE_NOT_PRESENT_OFFSET, 8614 }, + { 0x329d, G_UNICODE_NOT_PRESENT_OFFSET, 8618 }, + { 0x329e, G_UNICODE_NOT_PRESENT_OFFSET, 8622 }, + { 0x329f, G_UNICODE_NOT_PRESENT_OFFSET, 8626 }, + { 0x32a0, G_UNICODE_NOT_PRESENT_OFFSET, 8630 }, + { 0x32a1, G_UNICODE_NOT_PRESENT_OFFSET, 8634 }, + { 0x32a2, G_UNICODE_NOT_PRESENT_OFFSET, 8638 }, + { 0x32a3, G_UNICODE_NOT_PRESENT_OFFSET, 8642 }, + { 0x32a4, G_UNICODE_NOT_PRESENT_OFFSET, 7863 }, + { 0x32a5, G_UNICODE_NOT_PRESENT_OFFSET, 7867 }, + { 0x32a6, G_UNICODE_NOT_PRESENT_OFFSET, 7871 }, + { 0x32a7, G_UNICODE_NOT_PRESENT_OFFSET, 8646 }, + { 0x32a8, G_UNICODE_NOT_PRESENT_OFFSET, 8650 }, + { 0x32a9, G_UNICODE_NOT_PRESENT_OFFSET, 8654 }, + { 0x32aa, G_UNICODE_NOT_PRESENT_OFFSET, 8658 }, + { 0x32ab, G_UNICODE_NOT_PRESENT_OFFSET, 8662 }, + { 0x32ac, G_UNICODE_NOT_PRESENT_OFFSET, 8666 }, + { 0x32ad, G_UNICODE_NOT_PRESENT_OFFSET, 8670 }, + { 0x32ae, G_UNICODE_NOT_PRESENT_OFFSET, 8674 }, + { 0x32af, G_UNICODE_NOT_PRESENT_OFFSET, 8678 }, + { 0x32b0, G_UNICODE_NOT_PRESENT_OFFSET, 8682 }, + { 0x32b1, G_UNICODE_NOT_PRESENT_OFFSET, 8686 }, + { 0x32b2, G_UNICODE_NOT_PRESENT_OFFSET, 8689 }, + { 0x32b3, G_UNICODE_NOT_PRESENT_OFFSET, 8692 }, + { 0x32b4, G_UNICODE_NOT_PRESENT_OFFSET, 8695 }, + { 0x32b5, G_UNICODE_NOT_PRESENT_OFFSET, 8698 }, + { 0x32b6, G_UNICODE_NOT_PRESENT_OFFSET, 8701 }, + { 0x32b7, G_UNICODE_NOT_PRESENT_OFFSET, 8704 }, + { 0x32b8, G_UNICODE_NOT_PRESENT_OFFSET, 8707 }, + { 0x32b9, G_UNICODE_NOT_PRESENT_OFFSET, 8710 }, + { 0x32ba, G_UNICODE_NOT_PRESENT_OFFSET, 8713 }, + { 0x32bb, G_UNICODE_NOT_PRESENT_OFFSET, 8716 }, + { 0x32bc, G_UNICODE_NOT_PRESENT_OFFSET, 8719 }, + { 0x32bd, G_UNICODE_NOT_PRESENT_OFFSET, 8722 }, + { 0x32be, G_UNICODE_NOT_PRESENT_OFFSET, 8725 }, + { 0x32bf, G_UNICODE_NOT_PRESENT_OFFSET, 8728 }, + { 0x32c0, G_UNICODE_NOT_PRESENT_OFFSET, 8731 }, + { 0x32c1, G_UNICODE_NOT_PRESENT_OFFSET, 8736 }, + { 0x32c2, G_UNICODE_NOT_PRESENT_OFFSET, 8741 }, + { 0x32c3, G_UNICODE_NOT_PRESENT_OFFSET, 8746 }, + { 0x32c4, G_UNICODE_NOT_PRESENT_OFFSET, 8751 }, + { 0x32c5, G_UNICODE_NOT_PRESENT_OFFSET, 8756 }, + { 0x32c6, G_UNICODE_NOT_PRESENT_OFFSET, 8761 }, + { 0x32c7, G_UNICODE_NOT_PRESENT_OFFSET, 8766 }, + { 0x32c8, G_UNICODE_NOT_PRESENT_OFFSET, 8771 }, + { 0x32c9, G_UNICODE_NOT_PRESENT_OFFSET, 8776 }, + { 0x32ca, G_UNICODE_NOT_PRESENT_OFFSET, 8782 }, + { 0x32cb, G_UNICODE_NOT_PRESENT_OFFSET, 8788 }, + { 0x32cc, G_UNICODE_NOT_PRESENT_OFFSET, 8794 }, + { 0x32cd, G_UNICODE_NOT_PRESENT_OFFSET, 8797 }, + { 0x32ce, G_UNICODE_NOT_PRESENT_OFFSET, 8801 }, + { 0x32cf, G_UNICODE_NOT_PRESENT_OFFSET, 8804 }, + { 0x32d0, G_UNICODE_NOT_PRESENT_OFFSET, 8808 }, + { 0x32d1, G_UNICODE_NOT_PRESENT_OFFSET, 8812 }, + { 0x32d2, G_UNICODE_NOT_PRESENT_OFFSET, 8816 }, + { 0x32d3, G_UNICODE_NOT_PRESENT_OFFSET, 8820 }, + { 0x32d4, G_UNICODE_NOT_PRESENT_OFFSET, 8824 }, + { 0x32d5, G_UNICODE_NOT_PRESENT_OFFSET, 8828 }, + { 0x32d6, G_UNICODE_NOT_PRESENT_OFFSET, 8832 }, + { 0x32d7, G_UNICODE_NOT_PRESENT_OFFSET, 8836 }, + { 0x32d8, G_UNICODE_NOT_PRESENT_OFFSET, 8840 }, + { 0x32d9, G_UNICODE_NOT_PRESENT_OFFSET, 8844 }, + { 0x32da, G_UNICODE_NOT_PRESENT_OFFSET, 8848 }, + { 0x32db, G_UNICODE_NOT_PRESENT_OFFSET, 8852 }, + { 0x32dc, G_UNICODE_NOT_PRESENT_OFFSET, 8856 }, + { 0x32dd, G_UNICODE_NOT_PRESENT_OFFSET, 8860 }, + { 0x32de, G_UNICODE_NOT_PRESENT_OFFSET, 8864 }, + { 0x32df, G_UNICODE_NOT_PRESENT_OFFSET, 8868 }, + { 0x32e0, G_UNICODE_NOT_PRESENT_OFFSET, 8872 }, + { 0x32e1, G_UNICODE_NOT_PRESENT_OFFSET, 8876 }, + { 0x32e2, G_UNICODE_NOT_PRESENT_OFFSET, 8880 }, + { 0x32e3, G_UNICODE_NOT_PRESENT_OFFSET, 8884 }, + { 0x32e4, G_UNICODE_NOT_PRESENT_OFFSET, 8888 }, + { 0x32e5, G_UNICODE_NOT_PRESENT_OFFSET, 8892 }, + { 0x32e6, G_UNICODE_NOT_PRESENT_OFFSET, 8896 }, + { 0x32e7, G_UNICODE_NOT_PRESENT_OFFSET, 8900 }, + { 0x32e8, G_UNICODE_NOT_PRESENT_OFFSET, 8904 }, + { 0x32e9, G_UNICODE_NOT_PRESENT_OFFSET, 8908 }, + { 0x32ea, G_UNICODE_NOT_PRESENT_OFFSET, 8912 }, + { 0x32eb, G_UNICODE_NOT_PRESENT_OFFSET, 8916 }, + { 0x32ec, G_UNICODE_NOT_PRESENT_OFFSET, 8920 }, + { 0x32ed, G_UNICODE_NOT_PRESENT_OFFSET, 8924 }, + { 0x32ee, G_UNICODE_NOT_PRESENT_OFFSET, 8928 }, + { 0x32ef, G_UNICODE_NOT_PRESENT_OFFSET, 8932 }, + { 0x32f0, G_UNICODE_NOT_PRESENT_OFFSET, 8936 }, + { 0x32f1, G_UNICODE_NOT_PRESENT_OFFSET, 8940 }, + { 0x32f2, G_UNICODE_NOT_PRESENT_OFFSET, 8944 }, + { 0x32f3, G_UNICODE_NOT_PRESENT_OFFSET, 8948 }, + { 0x32f4, G_UNICODE_NOT_PRESENT_OFFSET, 8952 }, + { 0x32f5, G_UNICODE_NOT_PRESENT_OFFSET, 8956 }, + { 0x32f6, G_UNICODE_NOT_PRESENT_OFFSET, 8960 }, + { 0x32f7, G_UNICODE_NOT_PRESENT_OFFSET, 8964 }, + { 0x32f8, G_UNICODE_NOT_PRESENT_OFFSET, 8968 }, + { 0x32f9, G_UNICODE_NOT_PRESENT_OFFSET, 8972 }, + { 0x32fa, G_UNICODE_NOT_PRESENT_OFFSET, 8976 }, + { 0x32fb, G_UNICODE_NOT_PRESENT_OFFSET, 8980 }, + { 0x32fc, G_UNICODE_NOT_PRESENT_OFFSET, 8984 }, + { 0x32fd, G_UNICODE_NOT_PRESENT_OFFSET, 8988 }, + { 0x32fe, G_UNICODE_NOT_PRESENT_OFFSET, 8992 }, + { 0x3300, G_UNICODE_NOT_PRESENT_OFFSET, 8996 }, + { 0x3301, G_UNICODE_NOT_PRESENT_OFFSET, 9012 }, + { 0x3302, G_UNICODE_NOT_PRESENT_OFFSET, 9025 }, + { 0x3303, G_UNICODE_NOT_PRESENT_OFFSET, 9041 }, + { 0x3304, G_UNICODE_NOT_PRESENT_OFFSET, 9051 }, + { 0x3305, G_UNICODE_NOT_PRESENT_OFFSET, 9067 }, + { 0x3306, G_UNICODE_NOT_PRESENT_OFFSET, 9077 }, + { 0x3307, G_UNICODE_NOT_PRESENT_OFFSET, 9087 }, + { 0x3308, G_UNICODE_NOT_PRESENT_OFFSET, 9106 }, + { 0x3309, G_UNICODE_NOT_PRESENT_OFFSET, 9119 }, + { 0x330a, G_UNICODE_NOT_PRESENT_OFFSET, 9129 }, + { 0x330b, G_UNICODE_NOT_PRESENT_OFFSET, 9139 }, + { 0x330c, G_UNICODE_NOT_PRESENT_OFFSET, 9149 }, + { 0x330d, G_UNICODE_NOT_PRESENT_OFFSET, 9162 }, + { 0x330e, G_UNICODE_NOT_PRESENT_OFFSET, 9175 }, + { 0x330f, G_UNICODE_NOT_PRESENT_OFFSET, 9188 }, + { 0x3310, G_UNICODE_NOT_PRESENT_OFFSET, 9201 }, + { 0x3311, G_UNICODE_NOT_PRESENT_OFFSET, 9214 }, + { 0x3312, G_UNICODE_NOT_PRESENT_OFFSET, 9227 }, + { 0x3313, G_UNICODE_NOT_PRESENT_OFFSET, 9240 }, + { 0x3314, G_UNICODE_NOT_PRESENT_OFFSET, 9259 }, + { 0x3315, G_UNICODE_NOT_PRESENT_OFFSET, 9266 }, + { 0x3316, G_UNICODE_NOT_PRESENT_OFFSET, 9285 }, + { 0x3317, G_UNICODE_NOT_PRESENT_OFFSET, 9304 }, + { 0x3318, G_UNICODE_NOT_PRESENT_OFFSET, 9320 }, + { 0x3319, G_UNICODE_NOT_PRESENT_OFFSET, 9333 }, + { 0x331a, G_UNICODE_NOT_PRESENT_OFFSET, 9352 }, + { 0x331b, G_UNICODE_NOT_PRESENT_OFFSET, 9371 }, + { 0x331c, G_UNICODE_NOT_PRESENT_OFFSET, 9384 }, + { 0x331d, G_UNICODE_NOT_PRESENT_OFFSET, 9394 }, + { 0x331e, G_UNICODE_NOT_PRESENT_OFFSET, 9404 }, + { 0x331f, G_UNICODE_NOT_PRESENT_OFFSET, 9417 }, + { 0x3320, G_UNICODE_NOT_PRESENT_OFFSET, 9430 }, + { 0x3321, G_UNICODE_NOT_PRESENT_OFFSET, 9446 }, + { 0x3322, G_UNICODE_NOT_PRESENT_OFFSET, 9462 }, + { 0x3323, G_UNICODE_NOT_PRESENT_OFFSET, 9472 }, + { 0x3324, G_UNICODE_NOT_PRESENT_OFFSET, 9482 }, + { 0x3325, G_UNICODE_NOT_PRESENT_OFFSET, 9495 }, + { 0x3326, G_UNICODE_NOT_PRESENT_OFFSET, 9505 }, + { 0x3327, G_UNICODE_NOT_PRESENT_OFFSET, 9515 }, + { 0x3328, G_UNICODE_NOT_PRESENT_OFFSET, 9522 }, + { 0x3329, G_UNICODE_NOT_PRESENT_OFFSET, 9529 }, + { 0x332a, G_UNICODE_NOT_PRESENT_OFFSET, 9539 }, + { 0x332b, G_UNICODE_NOT_PRESENT_OFFSET, 9549 }, + { 0x332c, G_UNICODE_NOT_PRESENT_OFFSET, 9568 }, + { 0x332d, G_UNICODE_NOT_PRESENT_OFFSET, 9581 }, + { 0x332e, G_UNICODE_NOT_PRESENT_OFFSET, 9597 }, + { 0x332f, G_UNICODE_NOT_PRESENT_OFFSET, 9616 }, + { 0x3330, G_UNICODE_NOT_PRESENT_OFFSET, 9629 }, + { 0x3331, G_UNICODE_NOT_PRESENT_OFFSET, 9639 }, + { 0x3332, G_UNICODE_NOT_PRESENT_OFFSET, 9649 }, + { 0x3333, G_UNICODE_NOT_PRESENT_OFFSET, 9668 }, + { 0x3334, G_UNICODE_NOT_PRESENT_OFFSET, 9681 }, + { 0x3335, G_UNICODE_NOT_PRESENT_OFFSET, 9700 }, + { 0x3336, G_UNICODE_NOT_PRESENT_OFFSET, 9710 }, + { 0x3337, G_UNICODE_NOT_PRESENT_OFFSET, 9726 }, + { 0x3338, G_UNICODE_NOT_PRESENT_OFFSET, 9736 }, + { 0x3339, G_UNICODE_NOT_PRESENT_OFFSET, 9749 }, + { 0x333a, G_UNICODE_NOT_PRESENT_OFFSET, 9759 }, + { 0x333b, G_UNICODE_NOT_PRESENT_OFFSET, 9772 }, + { 0x333c, G_UNICODE_NOT_PRESENT_OFFSET, 9788 }, + { 0x333d, G_UNICODE_NOT_PRESENT_OFFSET, 9801 }, + { 0x333e, G_UNICODE_NOT_PRESENT_OFFSET, 9817 }, + { 0x333f, G_UNICODE_NOT_PRESENT_OFFSET, 9830 }, + { 0x3340, G_UNICODE_NOT_PRESENT_OFFSET, 9837 }, + { 0x3341, G_UNICODE_NOT_PRESENT_OFFSET, 9853 }, + { 0x3342, G_UNICODE_NOT_PRESENT_OFFSET, 9863 }, + { 0x3343, G_UNICODE_NOT_PRESENT_OFFSET, 9873 }, + { 0x3344, G_UNICODE_NOT_PRESENT_OFFSET, 9886 }, + { 0x3345, G_UNICODE_NOT_PRESENT_OFFSET, 9896 }, + { 0x3346, G_UNICODE_NOT_PRESENT_OFFSET, 9906 }, + { 0x3347, G_UNICODE_NOT_PRESENT_OFFSET, 9916 }, + { 0x3348, G_UNICODE_NOT_PRESENT_OFFSET, 9932 }, + { 0x3349, G_UNICODE_NOT_PRESENT_OFFSET, 9945 }, + { 0x334a, G_UNICODE_NOT_PRESENT_OFFSET, 9952 }, + { 0x334b, G_UNICODE_NOT_PRESENT_OFFSET, 9971 }, + { 0x334c, G_UNICODE_NOT_PRESENT_OFFSET, 9981 }, + { 0x334d, G_UNICODE_NOT_PRESENT_OFFSET, 9997 }, + { 0x334e, G_UNICODE_NOT_PRESENT_OFFSET, 10010 }, + { 0x334f, G_UNICODE_NOT_PRESENT_OFFSET, 10023 }, + { 0x3350, G_UNICODE_NOT_PRESENT_OFFSET, 10033 }, + { 0x3351, G_UNICODE_NOT_PRESENT_OFFSET, 10043 }, + { 0x3352, G_UNICODE_NOT_PRESENT_OFFSET, 10056 }, + { 0x3353, G_UNICODE_NOT_PRESENT_OFFSET, 10063 }, + { 0x3354, G_UNICODE_NOT_PRESENT_OFFSET, 10076 }, + { 0x3355, G_UNICODE_NOT_PRESENT_OFFSET, 10092 }, + { 0x3356, G_UNICODE_NOT_PRESENT_OFFSET, 10099 }, + { 0x3357, G_UNICODE_NOT_PRESENT_OFFSET, 10118 }, + { 0x3358, G_UNICODE_NOT_PRESENT_OFFSET, 10128 }, + { 0x3359, G_UNICODE_NOT_PRESENT_OFFSET, 10133 }, + { 0x335a, G_UNICODE_NOT_PRESENT_OFFSET, 10138 }, + { 0x335b, G_UNICODE_NOT_PRESENT_OFFSET, 10143 }, + { 0x335c, G_UNICODE_NOT_PRESENT_OFFSET, 10148 }, + { 0x335d, G_UNICODE_NOT_PRESENT_OFFSET, 10153 }, + { 0x335e, G_UNICODE_NOT_PRESENT_OFFSET, 10158 }, + { 0x335f, G_UNICODE_NOT_PRESENT_OFFSET, 10163 }, + { 0x3360, G_UNICODE_NOT_PRESENT_OFFSET, 10168 }, + { 0x3361, G_UNICODE_NOT_PRESENT_OFFSET, 10173 }, + { 0x3362, G_UNICODE_NOT_PRESENT_OFFSET, 10178 }, + { 0x3363, G_UNICODE_NOT_PRESENT_OFFSET, 10184 }, + { 0x3364, G_UNICODE_NOT_PRESENT_OFFSET, 10190 }, + { 0x3365, G_UNICODE_NOT_PRESENT_OFFSET, 10196 }, + { 0x3366, G_UNICODE_NOT_PRESENT_OFFSET, 10202 }, + { 0x3367, G_UNICODE_NOT_PRESENT_OFFSET, 10208 }, + { 0x3368, G_UNICODE_NOT_PRESENT_OFFSET, 10214 }, + { 0x3369, G_UNICODE_NOT_PRESENT_OFFSET, 10220 }, + { 0x336a, G_UNICODE_NOT_PRESENT_OFFSET, 10226 }, + { 0x336b, G_UNICODE_NOT_PRESENT_OFFSET, 10232 }, + { 0x336c, G_UNICODE_NOT_PRESENT_OFFSET, 10238 }, + { 0x336d, G_UNICODE_NOT_PRESENT_OFFSET, 10244 }, + { 0x336e, G_UNICODE_NOT_PRESENT_OFFSET, 10250 }, + { 0x336f, G_UNICODE_NOT_PRESENT_OFFSET, 10256 }, + { 0x3370, G_UNICODE_NOT_PRESENT_OFFSET, 10262 }, + { 0x3371, G_UNICODE_NOT_PRESENT_OFFSET, 10268 }, + { 0x3372, G_UNICODE_NOT_PRESENT_OFFSET, 10272 }, + { 0x3373, G_UNICODE_NOT_PRESENT_OFFSET, 10275 }, + { 0x3374, G_UNICODE_NOT_PRESENT_OFFSET, 10278 }, + { 0x3375, G_UNICODE_NOT_PRESENT_OFFSET, 10282 }, + { 0x3376, G_UNICODE_NOT_PRESENT_OFFSET, 10285 }, + { 0x3377, G_UNICODE_NOT_PRESENT_OFFSET, 10288 }, + { 0x3378, G_UNICODE_NOT_PRESENT_OFFSET, 10291 }, + { 0x3379, G_UNICODE_NOT_PRESENT_OFFSET, 10295 }, + { 0x337a, G_UNICODE_NOT_PRESENT_OFFSET, 10299 }, + { 0x337b, G_UNICODE_NOT_PRESENT_OFFSET, 10302 }, + { 0x337c, G_UNICODE_NOT_PRESENT_OFFSET, 10309 }, + { 0x337d, G_UNICODE_NOT_PRESENT_OFFSET, 10316 }, + { 0x337e, G_UNICODE_NOT_PRESENT_OFFSET, 10323 }, + { 0x337f, G_UNICODE_NOT_PRESENT_OFFSET, 10330 }, + { 0x3380, G_UNICODE_NOT_PRESENT_OFFSET, 10343 }, + { 0x3381, G_UNICODE_NOT_PRESENT_OFFSET, 10346 }, + { 0x3382, G_UNICODE_NOT_PRESENT_OFFSET, 10349 }, + { 0x3383, G_UNICODE_NOT_PRESENT_OFFSET, 10353 }, + { 0x3384, G_UNICODE_NOT_PRESENT_OFFSET, 10356 }, + { 0x3385, G_UNICODE_NOT_PRESENT_OFFSET, 10359 }, + { 0x3386, G_UNICODE_NOT_PRESENT_OFFSET, 10362 }, + { 0x3387, G_UNICODE_NOT_PRESENT_OFFSET, 10365 }, + { 0x3388, G_UNICODE_NOT_PRESENT_OFFSET, 10368 }, + { 0x3389, G_UNICODE_NOT_PRESENT_OFFSET, 10372 }, + { 0x338a, G_UNICODE_NOT_PRESENT_OFFSET, 10377 }, + { 0x338b, G_UNICODE_NOT_PRESENT_OFFSET, 10380 }, + { 0x338c, G_UNICODE_NOT_PRESENT_OFFSET, 10383 }, + { 0x338d, G_UNICODE_NOT_PRESENT_OFFSET, 10387 }, + { 0x338e, G_UNICODE_NOT_PRESENT_OFFSET, 10391 }, + { 0x338f, G_UNICODE_NOT_PRESENT_OFFSET, 10394 }, + { 0x3390, G_UNICODE_NOT_PRESENT_OFFSET, 10397 }, + { 0x3391, G_UNICODE_NOT_PRESENT_OFFSET, 10400 }, + { 0x3392, G_UNICODE_NOT_PRESENT_OFFSET, 10404 }, + { 0x3393, G_UNICODE_NOT_PRESENT_OFFSET, 10408 }, + { 0x3394, G_UNICODE_NOT_PRESENT_OFFSET, 10412 }, + { 0x3395, G_UNICODE_NOT_PRESENT_OFFSET, 10416 }, + { 0x3396, G_UNICODE_NOT_PRESENT_OFFSET, 10420 }, + { 0x3397, G_UNICODE_NOT_PRESENT_OFFSET, 10423 }, + { 0x3398, G_UNICODE_NOT_PRESENT_OFFSET, 10426 }, + { 0x3399, G_UNICODE_NOT_PRESENT_OFFSET, 10429 }, + { 0x339a, G_UNICODE_NOT_PRESENT_OFFSET, 10432 }, + { 0x339b, G_UNICODE_NOT_PRESENT_OFFSET, 10435 }, + { 0x339c, G_UNICODE_NOT_PRESENT_OFFSET, 10439 }, + { 0x339d, G_UNICODE_NOT_PRESENT_OFFSET, 10442 }, + { 0x339e, G_UNICODE_NOT_PRESENT_OFFSET, 10445 }, + { 0x339f, G_UNICODE_NOT_PRESENT_OFFSET, 10448 }, + { 0x33a0, G_UNICODE_NOT_PRESENT_OFFSET, 10452 }, + { 0x33a1, G_UNICODE_NOT_PRESENT_OFFSET, 10456 }, + { 0x33a2, G_UNICODE_NOT_PRESENT_OFFSET, 10459 }, + { 0x33a3, G_UNICODE_NOT_PRESENT_OFFSET, 10463 }, + { 0x33a4, G_UNICODE_NOT_PRESENT_OFFSET, 10467 }, + { 0x33a5, G_UNICODE_NOT_PRESENT_OFFSET, 10471 }, + { 0x33a6, G_UNICODE_NOT_PRESENT_OFFSET, 10474 }, + { 0x33a7, G_UNICODE_NOT_PRESENT_OFFSET, 10478 }, + { 0x33a8, G_UNICODE_NOT_PRESENT_OFFSET, 10484 }, + { 0x33a9, G_UNICODE_NOT_PRESENT_OFFSET, 10491 }, + { 0x33aa, G_UNICODE_NOT_PRESENT_OFFSET, 10494 }, + { 0x33ab, G_UNICODE_NOT_PRESENT_OFFSET, 10498 }, + { 0x33ac, G_UNICODE_NOT_PRESENT_OFFSET, 10502 }, + { 0x33ad, G_UNICODE_NOT_PRESENT_OFFSET, 10506 }, + { 0x33ae, G_UNICODE_NOT_PRESENT_OFFSET, 10510 }, + { 0x33af, G_UNICODE_NOT_PRESENT_OFFSET, 10518 }, + { 0x33b0, G_UNICODE_NOT_PRESENT_OFFSET, 10527 }, + { 0x33b1, G_UNICODE_NOT_PRESENT_OFFSET, 10530 }, + { 0x33b2, G_UNICODE_NOT_PRESENT_OFFSET, 10533 }, + { 0x33b3, G_UNICODE_NOT_PRESENT_OFFSET, 10537 }, + { 0x33b4, G_UNICODE_NOT_PRESENT_OFFSET, 10540 }, + { 0x33b5, G_UNICODE_NOT_PRESENT_OFFSET, 10543 }, + { 0x33b6, G_UNICODE_NOT_PRESENT_OFFSET, 10546 }, + { 0x33b7, G_UNICODE_NOT_PRESENT_OFFSET, 10550 }, + { 0x33b8, G_UNICODE_NOT_PRESENT_OFFSET, 10553 }, + { 0x33b9, G_UNICODE_NOT_PRESENT_OFFSET, 10556 }, + { 0x33ba, G_UNICODE_NOT_PRESENT_OFFSET, 10559 }, + { 0x33bb, G_UNICODE_NOT_PRESENT_OFFSET, 10562 }, + { 0x33bc, G_UNICODE_NOT_PRESENT_OFFSET, 10565 }, + { 0x33bd, G_UNICODE_NOT_PRESENT_OFFSET, 10569 }, + { 0x33be, G_UNICODE_NOT_PRESENT_OFFSET, 10572 }, + { 0x33bf, G_UNICODE_NOT_PRESENT_OFFSET, 10575 }, + { 0x33c0, G_UNICODE_NOT_PRESENT_OFFSET, 10578 }, + { 0x33c1, G_UNICODE_NOT_PRESENT_OFFSET, 10582 }, + { 0x33c2, G_UNICODE_NOT_PRESENT_OFFSET, 10586 }, + { 0x33c3, G_UNICODE_NOT_PRESENT_OFFSET, 10591 }, + { 0x33c4, G_UNICODE_NOT_PRESENT_OFFSET, 10594 }, + { 0x33c5, G_UNICODE_NOT_PRESENT_OFFSET, 10597 }, + { 0x33c6, G_UNICODE_NOT_PRESENT_OFFSET, 10600 }, + { 0x33c7, G_UNICODE_NOT_PRESENT_OFFSET, 10607 }, + { 0x33c8, G_UNICODE_NOT_PRESENT_OFFSET, 10611 }, + { 0x33c9, G_UNICODE_NOT_PRESENT_OFFSET, 10614 }, + { 0x33ca, G_UNICODE_NOT_PRESENT_OFFSET, 10617 }, + { 0x33cb, G_UNICODE_NOT_PRESENT_OFFSET, 10620 }, + { 0x33cc, G_UNICODE_NOT_PRESENT_OFFSET, 10623 }, + { 0x33cd, G_UNICODE_NOT_PRESENT_OFFSET, 10626 }, + { 0x33ce, G_UNICODE_NOT_PRESENT_OFFSET, 10629 }, + { 0x33cf, G_UNICODE_NOT_PRESENT_OFFSET, 10632 }, + { 0x33d0, G_UNICODE_NOT_PRESENT_OFFSET, 10635 }, + { 0x33d1, G_UNICODE_NOT_PRESENT_OFFSET, 10638 }, + { 0x33d2, G_UNICODE_NOT_PRESENT_OFFSET, 10641 }, + { 0x33d3, G_UNICODE_NOT_PRESENT_OFFSET, 10645 }, + { 0x33d4, G_UNICODE_NOT_PRESENT_OFFSET, 10648 }, + { 0x33d5, G_UNICODE_NOT_PRESENT_OFFSET, 10651 }, + { 0x33d6, G_UNICODE_NOT_PRESENT_OFFSET, 10655 }, + { 0x33d7, G_UNICODE_NOT_PRESENT_OFFSET, 10659 }, + { 0x33d8, G_UNICODE_NOT_PRESENT_OFFSET, 10662 }, + { 0x33d9, G_UNICODE_NOT_PRESENT_OFFSET, 10667 }, + { 0x33da, G_UNICODE_NOT_PRESENT_OFFSET, 10671 }, + { 0x33db, G_UNICODE_NOT_PRESENT_OFFSET, 10674 }, + { 0x33dc, G_UNICODE_NOT_PRESENT_OFFSET, 10677 }, + { 0x33dd, G_UNICODE_NOT_PRESENT_OFFSET, 10680 }, + { 0x33de, G_UNICODE_NOT_PRESENT_OFFSET, 10683 }, + { 0x33df, G_UNICODE_NOT_PRESENT_OFFSET, 10689 }, + { 0x33e0, G_UNICODE_NOT_PRESENT_OFFSET, 10695 }, + { 0x33e1, G_UNICODE_NOT_PRESENT_OFFSET, 10700 }, + { 0x33e2, G_UNICODE_NOT_PRESENT_OFFSET, 10705 }, + { 0x33e3, G_UNICODE_NOT_PRESENT_OFFSET, 10710 }, + { 0x33e4, G_UNICODE_NOT_PRESENT_OFFSET, 10715 }, + { 0x33e5, G_UNICODE_NOT_PRESENT_OFFSET, 10720 }, + { 0x33e6, G_UNICODE_NOT_PRESENT_OFFSET, 10725 }, + { 0x33e7, G_UNICODE_NOT_PRESENT_OFFSET, 10730 }, + { 0x33e8, G_UNICODE_NOT_PRESENT_OFFSET, 10735 }, + { 0x33e9, G_UNICODE_NOT_PRESENT_OFFSET, 10740 }, + { 0x33ea, G_UNICODE_NOT_PRESENT_OFFSET, 10746 }, + { 0x33eb, G_UNICODE_NOT_PRESENT_OFFSET, 10752 }, + { 0x33ec, G_UNICODE_NOT_PRESENT_OFFSET, 10758 }, + { 0x33ed, G_UNICODE_NOT_PRESENT_OFFSET, 10764 }, + { 0x33ee, G_UNICODE_NOT_PRESENT_OFFSET, 10770 }, + { 0x33ef, G_UNICODE_NOT_PRESENT_OFFSET, 10776 }, + { 0x33f0, G_UNICODE_NOT_PRESENT_OFFSET, 10782 }, + { 0x33f1, G_UNICODE_NOT_PRESENT_OFFSET, 10788 }, + { 0x33f2, G_UNICODE_NOT_PRESENT_OFFSET, 10794 }, + { 0x33f3, G_UNICODE_NOT_PRESENT_OFFSET, 10800 }, + { 0x33f4, G_UNICODE_NOT_PRESENT_OFFSET, 10806 }, + { 0x33f5, G_UNICODE_NOT_PRESENT_OFFSET, 10812 }, + { 0x33f6, G_UNICODE_NOT_PRESENT_OFFSET, 10818 }, + { 0x33f7, G_UNICODE_NOT_PRESENT_OFFSET, 10824 }, + { 0x33f8, G_UNICODE_NOT_PRESENT_OFFSET, 10830 }, + { 0x33f9, G_UNICODE_NOT_PRESENT_OFFSET, 10836 }, + { 0x33fa, G_UNICODE_NOT_PRESENT_OFFSET, 10842 }, + { 0x33fb, G_UNICODE_NOT_PRESENT_OFFSET, 10848 }, + { 0x33fc, G_UNICODE_NOT_PRESENT_OFFSET, 10854 }, + { 0x33fd, G_UNICODE_NOT_PRESENT_OFFSET, 10860 }, + { 0x33fe, G_UNICODE_NOT_PRESENT_OFFSET, 10866 }, + { 0x33ff, G_UNICODE_NOT_PRESENT_OFFSET, 10872 }, + { 0xa770, G_UNICODE_NOT_PRESENT_OFFSET, 10876 }, + { 0xf900, 10880, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf901, 10884, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf902, 6813, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf903, 10888, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf904, 10892, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf905, 10896, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf906, 10900, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf907, 7029, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf908, 7029, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf909, 10904, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf90a, 6845, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf90b, 10908, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf90c, 10912, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf90d, 10916, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf90e, 10920, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf90f, 10924, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf910, 10928, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf911, 10932, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf912, 10936, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf913, 10940, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf914, 10944, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf915, 10948, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf916, 10952, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf917, 10956, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf918, 10960, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf919, 10964, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf91a, 10968, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf91b, 10972, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf91c, 10976, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf91d, 10980, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf91e, 10984, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf91f, 10988, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf920, 10992, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf921, 10996, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf922, 11000, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf923, 11004, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf924, 11008, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf925, 11012, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf926, 11016, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf927, 11020, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf928, 11024, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf929, 11028, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf92a, 11032, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf92b, 11036, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf92c, 11040, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf92d, 11044, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf92e, 11048, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf92f, 11052, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf930, 11056, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf931, 11060, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf932, 11064, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf933, 11068, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf934, 6677, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf935, 11072, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf936, 11076, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf937, 11080, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf938, 11084, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf939, 11088, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf93a, 11092, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf93b, 11096, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf93c, 11100, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf93d, 11104, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf93e, 11108, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf93f, 11112, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf940, 6969, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf941, 11116, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf942, 11120, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf943, 11124, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf944, 11128, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf945, 11132, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf946, 11136, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf947, 11140, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf948, 11144, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf949, 11148, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf94a, 11152, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf94b, 11156, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf94c, 11160, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf94d, 11164, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf94e, 11168, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf94f, 11172, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf950, 11176, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf951, 11180, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf952, 11184, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf953, 11188, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf954, 11192, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf955, 11196, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf956, 11200, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf957, 11204, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf958, 11208, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf959, 11212, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf95a, 11216, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf95b, 11220, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf95c, 10944, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf95d, 11224, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf95e, 11228, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf95f, 11232, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf960, 11236, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf961, 11240, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf962, 11244, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf963, 11248, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf964, 11252, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf965, 11256, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf966, 11260, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf967, 11264, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf968, 11268, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf969, 11272, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf96a, 11276, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf96b, 11280, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf96c, 11284, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf96d, 11288, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf96e, 11292, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf96f, 11296, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf970, 11300, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf971, 6821, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf972, 11304, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf973, 11308, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf974, 11312, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf975, 11316, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf976, 11320, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf977, 11324, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf978, 11328, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf979, 11332, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf97a, 11336, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf97b, 11340, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf97c, 11344, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf97d, 11348, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf97e, 11352, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf97f, 11356, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf980, 11360, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf981, 6329, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf982, 11364, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf983, 11368, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf984, 11372, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf985, 11376, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf986, 11380, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf987, 11384, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf988, 11388, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf989, 11392, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf98a, 6253, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf98b, 11396, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf98c, 11400, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf98d, 11404, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf98e, 11408, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf98f, 11412, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf990, 11416, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf991, 11420, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf992, 11424, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf993, 11428, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf994, 11432, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf995, 11436, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf996, 11440, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf997, 11444, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf998, 11448, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf999, 11452, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf99a, 11456, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf99b, 11460, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf99c, 11464, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf99d, 11468, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf99e, 11472, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf99f, 11476, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a0, 11480, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a1, 11296, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a2, 11484, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a3, 11488, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a4, 11492, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a5, 11496, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a6, 11500, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a7, 11504, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a8, 11508, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9a9, 11512, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9aa, 11232, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ab, 11516, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ac, 11520, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ad, 11524, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ae, 11528, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9af, 11532, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b0, 11536, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b1, 11540, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b2, 11544, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b3, 11548, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b4, 11552, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b5, 11556, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b6, 11560, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b7, 11564, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b8, 11568, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9b9, 11572, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ba, 11576, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9bb, 11580, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9bc, 11584, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9bd, 11588, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9be, 11592, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9bf, 10944, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c0, 11596, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c1, 11600, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c2, 11604, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c3, 11608, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c4, 7025, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c5, 11612, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c6, 11616, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c7, 11620, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c8, 11624, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9c9, 11628, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ca, 11632, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9cb, 11636, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9cc, 11640, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9cd, 11644, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ce, 11648, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9cf, 11652, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d0, 11656, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d1, 8562, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d2, 11660, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d3, 11664, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d4, 11668, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d5, 11672, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d6, 11676, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d7, 11680, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d8, 11684, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9d9, 11688, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9da, 11692, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9db, 11240, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9dc, 11696, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9dd, 11700, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9de, 11704, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9df, 11708, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e0, 11712, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e1, 11716, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e2, 11720, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e3, 11724, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e4, 11728, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e5, 11732, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e6, 11736, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e7, 11740, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e8, 11744, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9e9, 6841, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ea, 11748, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9eb, 11752, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ec, 11756, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ed, 11760, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ee, 11764, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ef, 11768, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f0, 11772, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f1, 11776, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f2, 11780, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f3, 11784, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f4, 11788, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f5, 11792, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f6, 11796, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f7, 6645, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f8, 11800, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9f9, 11804, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9fa, 11808, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9fb, 11812, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9fc, 11816, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9fd, 11820, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9fe, 11824, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xf9ff, 11828, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa00, 11832, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa01, 11836, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa02, 11840, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa03, 11844, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa04, 11848, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa05, 11852, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa06, 11856, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa07, 11860, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa08, 6753, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa09, 11864, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa0a, 6765, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa0b, 11868, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa0c, 11872, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa0d, 11876, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa10, 11880, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa12, 11884, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa15, 11888, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa16, 11892, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa17, 11896, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa18, 11900, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa19, 11904, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa1a, 11908, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa1b, 11912, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa1c, 11916, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa1d, 11920, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa1e, 6673, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa20, 11924, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa22, 11928, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa25, 11932, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa26, 11936, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa2a, 11940, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa2b, 11944, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa2c, 11948, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa2d, 11952, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa30, 11956, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa31, 11960, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa32, 11964, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa33, 11968, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa34, 11972, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa35, 11976, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa36, 11980, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa37, 11984, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa38, 11988, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa39, 11992, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa3a, 11996, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa3b, 12000, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa3c, 6357, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa3d, 12004, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa3e, 12008, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa3f, 12012, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa40, 12016, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa41, 12020, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa42, 12024, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa43, 12028, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa44, 12032, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa45, 12036, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa46, 12040, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa47, 12044, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa48, 12048, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa49, 12052, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa4a, 12056, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa4b, 12060, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa4c, 8582, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa4d, 12064, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa4e, 12068, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa4f, 12072, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa50, 12076, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa51, 8598, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa52, 12080, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa53, 12084, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa54, 12088, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa55, 12092, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa56, 12096, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa57, 11440, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa58, 12100, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa59, 12104, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa5a, 12108, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa5b, 12112, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa5c, 12116, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa5d, 12120, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa5e, 12120, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa5f, 12124, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa60, 12128, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa61, 12132, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa62, 12136, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa63, 12140, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa64, 12144, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa65, 12148, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa66, 12152, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa67, 11932, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa68, 12156, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa69, 12160, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa6a, 12164, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa6b, 12168, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa6c, 12172, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa6d, 12177, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa70, 12181, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa71, 12185, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa72, 12189, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa73, 12193, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa74, 12197, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa75, 12201, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa76, 12205, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa77, 12209, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa78, 11980, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa79, 12213, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa7a, 12217, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa7b, 12221, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa7c, 11880, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa7d, 12225, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa7e, 12229, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa7f, 12233, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa80, 12237, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa81, 12241, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa82, 12245, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa83, 12249, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa84, 12253, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa85, 12257, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa86, 12261, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa87, 12265, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa88, 12269, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa89, 12012, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa8a, 12273, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa8b, 12016, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa8c, 12277, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa8d, 12281, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa8e, 12285, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa8f, 12289, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa90, 12293, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa91, 11884, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa92, 11028, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa93, 12297, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa94, 12301, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa95, 6489, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa96, 11300, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa97, 11632, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa98, 12305, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa99, 12309, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa9a, 12044, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa9b, 12313, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa9c, 12048, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa9d, 12317, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa9e, 12321, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfa9f, 12325, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa0, 11892, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa1, 12329, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa2, 12333, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa3, 12337, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa4, 12341, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa5, 12345, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa6, 11896, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa7, 12349, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa8, 12353, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaa9, 12357, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaaa, 12361, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaab, 12365, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaac, 12369, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaad, 12096, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaae, 12373, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaaf, 12377, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab0, 11440, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab1, 12381, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab2, 12112, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab3, 12385, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab4, 12389, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab5, 12393, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab6, 12397, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab7, 12401, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab8, 12132, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfab9, 12405, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaba, 11928, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfabb, 12409, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfabc, 12136, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfabd, 11224, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfabe, 12413, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfabf, 12140, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac0, 12417, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac1, 12148, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac2, 12421, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac3, 12425, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac4, 12429, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac5, 12433, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac6, 12437, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac7, 12156, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac8, 11916, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfac9, 12441, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfaca, 12160, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfacb, 12445, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfacc, 12164, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfacd, 12449, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xface, 7029, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfacf, 12453, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad0, 12458, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad1, 12463, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad2, 12468, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad3, 12472, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad4, 12476, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad5, 12480, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad6, 12485, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad7, 12490, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad8, 12495, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfad9, 12499, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb00, G_UNICODE_NOT_PRESENT_OFFSET, 12503 }, + { 0xfb01, G_UNICODE_NOT_PRESENT_OFFSET, 12506 }, + { 0xfb02, G_UNICODE_NOT_PRESENT_OFFSET, 12509 }, + { 0xfb03, G_UNICODE_NOT_PRESENT_OFFSET, 12512 }, + { 0xfb04, G_UNICODE_NOT_PRESENT_OFFSET, 12516 }, + { 0xfb05, G_UNICODE_NOT_PRESENT_OFFSET, 12520 }, + { 0xfb06, G_UNICODE_NOT_PRESENT_OFFSET, 12520 }, + { 0xfb13, G_UNICODE_NOT_PRESENT_OFFSET, 12523 }, + { 0xfb14, G_UNICODE_NOT_PRESENT_OFFSET, 12528 }, + { 0xfb15, G_UNICODE_NOT_PRESENT_OFFSET, 12533 }, + { 0xfb16, G_UNICODE_NOT_PRESENT_OFFSET, 12538 }, + { 0xfb17, G_UNICODE_NOT_PRESENT_OFFSET, 12543 }, + { 0xfb1d, 12548, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb1f, 12553, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb20, G_UNICODE_NOT_PRESENT_OFFSET, 12558 }, + { 0xfb21, G_UNICODE_NOT_PRESENT_OFFSET, 5338 }, + { 0xfb22, G_UNICODE_NOT_PRESENT_OFFSET, 5347 }, + { 0xfb23, G_UNICODE_NOT_PRESENT_OFFSET, 12561 }, + { 0xfb24, G_UNICODE_NOT_PRESENT_OFFSET, 12564 }, + { 0xfb25, G_UNICODE_NOT_PRESENT_OFFSET, 12567 }, + { 0xfb26, G_UNICODE_NOT_PRESENT_OFFSET, 12570 }, + { 0xfb27, G_UNICODE_NOT_PRESENT_OFFSET, 12573 }, + { 0xfb28, G_UNICODE_NOT_PRESENT_OFFSET, 12576 }, + { 0xfb29, G_UNICODE_NOT_PRESENT_OFFSET, 5267 }, + { 0xfb2a, 12579, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb2b, 12584, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb2c, 12589, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb2d, 12596, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb2e, 12603, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb2f, 12608, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb30, 12613, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb31, 12618, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb32, 12623, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb33, 12628, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb34, 12633, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb35, 12638, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb36, 12643, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb38, 12648, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb39, 12653, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb3a, 12658, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb3b, 12663, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb3c, 12668, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb3e, 12673, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb40, 12678, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb41, 12683, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb43, 12688, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb44, 12693, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb46, 12698, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb47, 12703, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb48, 12708, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb49, 12713, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb4a, 12718, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb4b, 12723, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb4c, 12728, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb4d, 12733, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb4e, 12738, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0xfb4f, G_UNICODE_NOT_PRESENT_OFFSET, 12743 }, + { 0xfb50, G_UNICODE_NOT_PRESENT_OFFSET, 12748 }, + { 0xfb51, G_UNICODE_NOT_PRESENT_OFFSET, 12748 }, + { 0xfb52, G_UNICODE_NOT_PRESENT_OFFSET, 12751 }, + { 0xfb53, G_UNICODE_NOT_PRESENT_OFFSET, 12751 }, + { 0xfb54, G_UNICODE_NOT_PRESENT_OFFSET, 12751 }, + { 0xfb55, G_UNICODE_NOT_PRESENT_OFFSET, 12751 }, + { 0xfb56, G_UNICODE_NOT_PRESENT_OFFSET, 12754 }, + { 0xfb57, G_UNICODE_NOT_PRESENT_OFFSET, 12754 }, + { 0xfb58, G_UNICODE_NOT_PRESENT_OFFSET, 12754 }, + { 0xfb59, G_UNICODE_NOT_PRESENT_OFFSET, 12754 }, + { 0xfb5a, G_UNICODE_NOT_PRESENT_OFFSET, 12757 }, + { 0xfb5b, G_UNICODE_NOT_PRESENT_OFFSET, 12757 }, + { 0xfb5c, G_UNICODE_NOT_PRESENT_OFFSET, 12757 }, + { 0xfb5d, G_UNICODE_NOT_PRESENT_OFFSET, 12757 }, + { 0xfb5e, G_UNICODE_NOT_PRESENT_OFFSET, 12760 }, + { 0xfb5f, G_UNICODE_NOT_PRESENT_OFFSET, 12760 }, + { 0xfb60, G_UNICODE_NOT_PRESENT_OFFSET, 12760 }, + { 0xfb61, G_UNICODE_NOT_PRESENT_OFFSET, 12760 }, + { 0xfb62, G_UNICODE_NOT_PRESENT_OFFSET, 12763 }, + { 0xfb63, G_UNICODE_NOT_PRESENT_OFFSET, 12763 }, + { 0xfb64, G_UNICODE_NOT_PRESENT_OFFSET, 12763 }, + { 0xfb65, G_UNICODE_NOT_PRESENT_OFFSET, 12763 }, + { 0xfb66, G_UNICODE_NOT_PRESENT_OFFSET, 12766 }, + { 0xfb67, G_UNICODE_NOT_PRESENT_OFFSET, 12766 }, + { 0xfb68, G_UNICODE_NOT_PRESENT_OFFSET, 12766 }, + { 0xfb69, G_UNICODE_NOT_PRESENT_OFFSET, 12766 }, + { 0xfb6a, G_UNICODE_NOT_PRESENT_OFFSET, 12769 }, + { 0xfb6b, G_UNICODE_NOT_PRESENT_OFFSET, 12769 }, + { 0xfb6c, G_UNICODE_NOT_PRESENT_OFFSET, 12769 }, + { 0xfb6d, G_UNICODE_NOT_PRESENT_OFFSET, 12769 }, + { 0xfb6e, G_UNICODE_NOT_PRESENT_OFFSET, 12772 }, + { 0xfb6f, G_UNICODE_NOT_PRESENT_OFFSET, 12772 }, + { 0xfb70, G_UNICODE_NOT_PRESENT_OFFSET, 12772 }, + { 0xfb71, G_UNICODE_NOT_PRESENT_OFFSET, 12772 }, + { 0xfb72, G_UNICODE_NOT_PRESENT_OFFSET, 12775 }, + { 0xfb73, G_UNICODE_NOT_PRESENT_OFFSET, 12775 }, + { 0xfb74, G_UNICODE_NOT_PRESENT_OFFSET, 12775 }, + { 0xfb75, G_UNICODE_NOT_PRESENT_OFFSET, 12775 }, + { 0xfb76, G_UNICODE_NOT_PRESENT_OFFSET, 12778 }, + { 0xfb77, G_UNICODE_NOT_PRESENT_OFFSET, 12778 }, + { 0xfb78, G_UNICODE_NOT_PRESENT_OFFSET, 12778 }, + { 0xfb79, G_UNICODE_NOT_PRESENT_OFFSET, 12778 }, + { 0xfb7a, G_UNICODE_NOT_PRESENT_OFFSET, 12781 }, + { 0xfb7b, G_UNICODE_NOT_PRESENT_OFFSET, 12781 }, + { 0xfb7c, G_UNICODE_NOT_PRESENT_OFFSET, 12781 }, + { 0xfb7d, G_UNICODE_NOT_PRESENT_OFFSET, 12781 }, + { 0xfb7e, G_UNICODE_NOT_PRESENT_OFFSET, 12784 }, + { 0xfb7f, G_UNICODE_NOT_PRESENT_OFFSET, 12784 }, + { 0xfb80, G_UNICODE_NOT_PRESENT_OFFSET, 12784 }, + { 0xfb81, G_UNICODE_NOT_PRESENT_OFFSET, 12784 }, + { 0xfb82, G_UNICODE_NOT_PRESENT_OFFSET, 12787 }, + { 0xfb83, G_UNICODE_NOT_PRESENT_OFFSET, 12787 }, + { 0xfb84, G_UNICODE_NOT_PRESENT_OFFSET, 12790 }, + { 0xfb85, G_UNICODE_NOT_PRESENT_OFFSET, 12790 }, + { 0xfb86, G_UNICODE_NOT_PRESENT_OFFSET, 12793 }, + { 0xfb87, G_UNICODE_NOT_PRESENT_OFFSET, 12793 }, + { 0xfb88, G_UNICODE_NOT_PRESENT_OFFSET, 12796 }, + { 0xfb89, G_UNICODE_NOT_PRESENT_OFFSET, 12796 }, + { 0xfb8a, G_UNICODE_NOT_PRESENT_OFFSET, 12799 }, + { 0xfb8b, G_UNICODE_NOT_PRESENT_OFFSET, 12799 }, + { 0xfb8c, G_UNICODE_NOT_PRESENT_OFFSET, 12802 }, + { 0xfb8d, G_UNICODE_NOT_PRESENT_OFFSET, 12802 }, + { 0xfb8e, G_UNICODE_NOT_PRESENT_OFFSET, 12805 }, + { 0xfb8f, G_UNICODE_NOT_PRESENT_OFFSET, 12805 }, + { 0xfb90, G_UNICODE_NOT_PRESENT_OFFSET, 12805 }, + { 0xfb91, G_UNICODE_NOT_PRESENT_OFFSET, 12805 }, + { 0xfb92, G_UNICODE_NOT_PRESENT_OFFSET, 12808 }, + { 0xfb93, G_UNICODE_NOT_PRESENT_OFFSET, 12808 }, + { 0xfb94, G_UNICODE_NOT_PRESENT_OFFSET, 12808 }, + { 0xfb95, G_UNICODE_NOT_PRESENT_OFFSET, 12808 }, + { 0xfb96, G_UNICODE_NOT_PRESENT_OFFSET, 12811 }, + { 0xfb97, G_UNICODE_NOT_PRESENT_OFFSET, 12811 }, + { 0xfb98, G_UNICODE_NOT_PRESENT_OFFSET, 12811 }, + { 0xfb99, G_UNICODE_NOT_PRESENT_OFFSET, 12811 }, + { 0xfb9a, G_UNICODE_NOT_PRESENT_OFFSET, 12814 }, + { 0xfb9b, G_UNICODE_NOT_PRESENT_OFFSET, 12814 }, + { 0xfb9c, G_UNICODE_NOT_PRESENT_OFFSET, 12814 }, + { 0xfb9d, G_UNICODE_NOT_PRESENT_OFFSET, 12814 }, + { 0xfb9e, G_UNICODE_NOT_PRESENT_OFFSET, 12817 }, + { 0xfb9f, G_UNICODE_NOT_PRESENT_OFFSET, 12817 }, + { 0xfba0, G_UNICODE_NOT_PRESENT_OFFSET, 12820 }, + { 0xfba1, G_UNICODE_NOT_PRESENT_OFFSET, 12820 }, + { 0xfba2, G_UNICODE_NOT_PRESENT_OFFSET, 12820 }, + { 0xfba3, G_UNICODE_NOT_PRESENT_OFFSET, 12820 }, + { 0xfba4, G_UNICODE_NOT_PRESENT_OFFSET, 1721 }, + { 0xfba5, G_UNICODE_NOT_PRESENT_OFFSET, 1721 }, + { 0xfba6, G_UNICODE_NOT_PRESENT_OFFSET, 12823 }, + { 0xfba7, G_UNICODE_NOT_PRESENT_OFFSET, 12823 }, + { 0xfba8, G_UNICODE_NOT_PRESENT_OFFSET, 12823 }, + { 0xfba9, G_UNICODE_NOT_PRESENT_OFFSET, 12823 }, + { 0xfbaa, G_UNICODE_NOT_PRESENT_OFFSET, 12826 }, + { 0xfbab, G_UNICODE_NOT_PRESENT_OFFSET, 12826 }, + { 0xfbac, G_UNICODE_NOT_PRESENT_OFFSET, 12826 }, + { 0xfbad, G_UNICODE_NOT_PRESENT_OFFSET, 12826 }, + { 0xfbae, G_UNICODE_NOT_PRESENT_OFFSET, 12829 }, + { 0xfbaf, G_UNICODE_NOT_PRESENT_OFFSET, 12829 }, + { 0xfbb0, G_UNICODE_NOT_PRESENT_OFFSET, 1731 }, + { 0xfbb1, G_UNICODE_NOT_PRESENT_OFFSET, 1731 }, + { 0xfbd3, G_UNICODE_NOT_PRESENT_OFFSET, 12832 }, + { 0xfbd4, G_UNICODE_NOT_PRESENT_OFFSET, 12832 }, + { 0xfbd5, G_UNICODE_NOT_PRESENT_OFFSET, 12832 }, + { 0xfbd6, G_UNICODE_NOT_PRESENT_OFFSET, 12832 }, + { 0xfbd7, G_UNICODE_NOT_PRESENT_OFFSET, 12835 }, + { 0xfbd8, G_UNICODE_NOT_PRESENT_OFFSET, 12835 }, + { 0xfbd9, G_UNICODE_NOT_PRESENT_OFFSET, 12838 }, + { 0xfbda, G_UNICODE_NOT_PRESENT_OFFSET, 12838 }, + { 0xfbdb, G_UNICODE_NOT_PRESENT_OFFSET, 12841 }, + { 0xfbdc, G_UNICODE_NOT_PRESENT_OFFSET, 12841 }, + { 0xfbdd, G_UNICODE_NOT_PRESENT_OFFSET, 1711 }, + { 0xfbde, G_UNICODE_NOT_PRESENT_OFFSET, 12844 }, + { 0xfbdf, G_UNICODE_NOT_PRESENT_OFFSET, 12844 }, + { 0xfbe0, G_UNICODE_NOT_PRESENT_OFFSET, 12847 }, + { 0xfbe1, G_UNICODE_NOT_PRESENT_OFFSET, 12847 }, + { 0xfbe2, G_UNICODE_NOT_PRESENT_OFFSET, 12850 }, + { 0xfbe3, G_UNICODE_NOT_PRESENT_OFFSET, 12850 }, + { 0xfbe4, G_UNICODE_NOT_PRESENT_OFFSET, 12853 }, + { 0xfbe5, G_UNICODE_NOT_PRESENT_OFFSET, 12853 }, + { 0xfbe6, G_UNICODE_NOT_PRESENT_OFFSET, 12853 }, + { 0xfbe7, G_UNICODE_NOT_PRESENT_OFFSET, 12853 }, + { 0xfbe8, G_UNICODE_NOT_PRESENT_OFFSET, 12856 }, + { 0xfbe9, G_UNICODE_NOT_PRESENT_OFFSET, 12856 }, + { 0xfbea, G_UNICODE_NOT_PRESENT_OFFSET, 12859 }, + { 0xfbeb, G_UNICODE_NOT_PRESENT_OFFSET, 12859 }, + { 0xfbec, G_UNICODE_NOT_PRESENT_OFFSET, 12866 }, + { 0xfbed, G_UNICODE_NOT_PRESENT_OFFSET, 12866 }, + { 0xfbee, G_UNICODE_NOT_PRESENT_OFFSET, 12873 }, + { 0xfbef, G_UNICODE_NOT_PRESENT_OFFSET, 12873 }, + { 0xfbf0, G_UNICODE_NOT_PRESENT_OFFSET, 12880 }, + { 0xfbf1, G_UNICODE_NOT_PRESENT_OFFSET, 12880 }, + { 0xfbf2, G_UNICODE_NOT_PRESENT_OFFSET, 12887 }, + { 0xfbf3, G_UNICODE_NOT_PRESENT_OFFSET, 12887 }, + { 0xfbf4, G_UNICODE_NOT_PRESENT_OFFSET, 12894 }, + { 0xfbf5, G_UNICODE_NOT_PRESENT_OFFSET, 12894 }, + { 0xfbf6, G_UNICODE_NOT_PRESENT_OFFSET, 12901 }, + { 0xfbf7, G_UNICODE_NOT_PRESENT_OFFSET, 12901 }, + { 0xfbf8, G_UNICODE_NOT_PRESENT_OFFSET, 12901 }, + { 0xfbf9, G_UNICODE_NOT_PRESENT_OFFSET, 12908 }, + { 0xfbfa, G_UNICODE_NOT_PRESENT_OFFSET, 12908 }, + { 0xfbfb, G_UNICODE_NOT_PRESENT_OFFSET, 12908 }, + { 0xfbfc, G_UNICODE_NOT_PRESENT_OFFSET, 12915 }, + { 0xfbfd, G_UNICODE_NOT_PRESENT_OFFSET, 12915 }, + { 0xfbfe, G_UNICODE_NOT_PRESENT_OFFSET, 12915 }, + { 0xfbff, G_UNICODE_NOT_PRESENT_OFFSET, 12915 }, + { 0xfc00, G_UNICODE_NOT_PRESENT_OFFSET, 12918 }, + { 0xfc01, G_UNICODE_NOT_PRESENT_OFFSET, 12925 }, + { 0xfc02, G_UNICODE_NOT_PRESENT_OFFSET, 12932 }, + { 0xfc03, G_UNICODE_NOT_PRESENT_OFFSET, 12908 }, + { 0xfc04, G_UNICODE_NOT_PRESENT_OFFSET, 12939 }, + { 0xfc05, G_UNICODE_NOT_PRESENT_OFFSET, 12946 }, + { 0xfc06, G_UNICODE_NOT_PRESENT_OFFSET, 12951 }, + { 0xfc07, G_UNICODE_NOT_PRESENT_OFFSET, 12956 }, + { 0xfc08, G_UNICODE_NOT_PRESENT_OFFSET, 12961 }, + { 0xfc09, G_UNICODE_NOT_PRESENT_OFFSET, 12966 }, + { 0xfc0a, G_UNICODE_NOT_PRESENT_OFFSET, 12971 }, + { 0xfc0b, G_UNICODE_NOT_PRESENT_OFFSET, 12976 }, + { 0xfc0c, G_UNICODE_NOT_PRESENT_OFFSET, 12981 }, + { 0xfc0d, G_UNICODE_NOT_PRESENT_OFFSET, 12986 }, + { 0xfc0e, G_UNICODE_NOT_PRESENT_OFFSET, 12991 }, + { 0xfc0f, G_UNICODE_NOT_PRESENT_OFFSET, 12996 }, + { 0xfc10, G_UNICODE_NOT_PRESENT_OFFSET, 13001 }, + { 0xfc11, G_UNICODE_NOT_PRESENT_OFFSET, 13006 }, + { 0xfc12, G_UNICODE_NOT_PRESENT_OFFSET, 13011 }, + { 0xfc13, G_UNICODE_NOT_PRESENT_OFFSET, 13016 }, + { 0xfc14, G_UNICODE_NOT_PRESENT_OFFSET, 13021 }, + { 0xfc15, G_UNICODE_NOT_PRESENT_OFFSET, 13026 }, + { 0xfc16, G_UNICODE_NOT_PRESENT_OFFSET, 13031 }, + { 0xfc17, G_UNICODE_NOT_PRESENT_OFFSET, 13036 }, + { 0xfc18, G_UNICODE_NOT_PRESENT_OFFSET, 13041 }, + { 0xfc19, G_UNICODE_NOT_PRESENT_OFFSET, 13046 }, + { 0xfc1a, G_UNICODE_NOT_PRESENT_OFFSET, 13051 }, + { 0xfc1b, G_UNICODE_NOT_PRESENT_OFFSET, 13056 }, + { 0xfc1c, G_UNICODE_NOT_PRESENT_OFFSET, 13061 }, + { 0xfc1d, G_UNICODE_NOT_PRESENT_OFFSET, 13066 }, + { 0xfc1e, G_UNICODE_NOT_PRESENT_OFFSET, 13071 }, + { 0xfc1f, G_UNICODE_NOT_PRESENT_OFFSET, 13076 }, + { 0xfc20, G_UNICODE_NOT_PRESENT_OFFSET, 13081 }, + { 0xfc21, G_UNICODE_NOT_PRESENT_OFFSET, 13086 }, + { 0xfc22, G_UNICODE_NOT_PRESENT_OFFSET, 13091 }, + { 0xfc23, G_UNICODE_NOT_PRESENT_OFFSET, 13096 }, + { 0xfc24, G_UNICODE_NOT_PRESENT_OFFSET, 13101 }, + { 0xfc25, G_UNICODE_NOT_PRESENT_OFFSET, 13106 }, + { 0xfc26, G_UNICODE_NOT_PRESENT_OFFSET, 13111 }, + { 0xfc27, G_UNICODE_NOT_PRESENT_OFFSET, 13116 }, + { 0xfc28, G_UNICODE_NOT_PRESENT_OFFSET, 13121 }, + { 0xfc29, G_UNICODE_NOT_PRESENT_OFFSET, 13126 }, + { 0xfc2a, G_UNICODE_NOT_PRESENT_OFFSET, 13131 }, + { 0xfc2b, G_UNICODE_NOT_PRESENT_OFFSET, 13136 }, + { 0xfc2c, G_UNICODE_NOT_PRESENT_OFFSET, 13141 }, + { 0xfc2d, G_UNICODE_NOT_PRESENT_OFFSET, 13146 }, + { 0xfc2e, G_UNICODE_NOT_PRESENT_OFFSET, 13151 }, + { 0xfc2f, G_UNICODE_NOT_PRESENT_OFFSET, 13156 }, + { 0xfc30, G_UNICODE_NOT_PRESENT_OFFSET, 13161 }, + { 0xfc31, G_UNICODE_NOT_PRESENT_OFFSET, 13166 }, + { 0xfc32, G_UNICODE_NOT_PRESENT_OFFSET, 13171 }, + { 0xfc33, G_UNICODE_NOT_PRESENT_OFFSET, 13176 }, + { 0xfc34, G_UNICODE_NOT_PRESENT_OFFSET, 13181 }, + { 0xfc35, G_UNICODE_NOT_PRESENT_OFFSET, 13186 }, + { 0xfc36, G_UNICODE_NOT_PRESENT_OFFSET, 13191 }, + { 0xfc37, G_UNICODE_NOT_PRESENT_OFFSET, 13196 }, + { 0xfc38, G_UNICODE_NOT_PRESENT_OFFSET, 13201 }, + { 0xfc39, G_UNICODE_NOT_PRESENT_OFFSET, 13206 }, + { 0xfc3a, G_UNICODE_NOT_PRESENT_OFFSET, 13211 }, + { 0xfc3b, G_UNICODE_NOT_PRESENT_OFFSET, 13216 }, + { 0xfc3c, G_UNICODE_NOT_PRESENT_OFFSET, 13221 }, + { 0xfc3d, G_UNICODE_NOT_PRESENT_OFFSET, 13226 }, + { 0xfc3e, G_UNICODE_NOT_PRESENT_OFFSET, 13231 }, + { 0xfc3f, G_UNICODE_NOT_PRESENT_OFFSET, 13236 }, + { 0xfc40, G_UNICODE_NOT_PRESENT_OFFSET, 13241 }, + { 0xfc41, G_UNICODE_NOT_PRESENT_OFFSET, 13246 }, + { 0xfc42, G_UNICODE_NOT_PRESENT_OFFSET, 13251 }, + { 0xfc43, G_UNICODE_NOT_PRESENT_OFFSET, 13256 }, + { 0xfc44, G_UNICODE_NOT_PRESENT_OFFSET, 13261 }, + { 0xfc45, G_UNICODE_NOT_PRESENT_OFFSET, 13266 }, + { 0xfc46, G_UNICODE_NOT_PRESENT_OFFSET, 13271 }, + { 0xfc47, G_UNICODE_NOT_PRESENT_OFFSET, 13276 }, + { 0xfc48, G_UNICODE_NOT_PRESENT_OFFSET, 13281 }, + { 0xfc49, G_UNICODE_NOT_PRESENT_OFFSET, 13286 }, + { 0xfc4a, G_UNICODE_NOT_PRESENT_OFFSET, 13291 }, + { 0xfc4b, G_UNICODE_NOT_PRESENT_OFFSET, 13296 }, + { 0xfc4c, G_UNICODE_NOT_PRESENT_OFFSET, 13301 }, + { 0xfc4d, G_UNICODE_NOT_PRESENT_OFFSET, 13306 }, + { 0xfc4e, G_UNICODE_NOT_PRESENT_OFFSET, 13311 }, + { 0xfc4f, G_UNICODE_NOT_PRESENT_OFFSET, 13316 }, + { 0xfc50, G_UNICODE_NOT_PRESENT_OFFSET, 13321 }, + { 0xfc51, G_UNICODE_NOT_PRESENT_OFFSET, 13326 }, + { 0xfc52, G_UNICODE_NOT_PRESENT_OFFSET, 13331 }, + { 0xfc53, G_UNICODE_NOT_PRESENT_OFFSET, 13336 }, + { 0xfc54, G_UNICODE_NOT_PRESENT_OFFSET, 13341 }, + { 0xfc55, G_UNICODE_NOT_PRESENT_OFFSET, 13346 }, + { 0xfc56, G_UNICODE_NOT_PRESENT_OFFSET, 13351 }, + { 0xfc57, G_UNICODE_NOT_PRESENT_OFFSET, 13356 }, + { 0xfc58, G_UNICODE_NOT_PRESENT_OFFSET, 13361 }, + { 0xfc59, G_UNICODE_NOT_PRESENT_OFFSET, 13366 }, + { 0xfc5a, G_UNICODE_NOT_PRESENT_OFFSET, 13371 }, + { 0xfc5b, G_UNICODE_NOT_PRESENT_OFFSET, 13376 }, + { 0xfc5c, G_UNICODE_NOT_PRESENT_OFFSET, 13381 }, + { 0xfc5d, G_UNICODE_NOT_PRESENT_OFFSET, 13386 }, + { 0xfc5e, G_UNICODE_NOT_PRESENT_OFFSET, 13391 }, + { 0xfc5f, G_UNICODE_NOT_PRESENT_OFFSET, 13397 }, + { 0xfc60, G_UNICODE_NOT_PRESENT_OFFSET, 13403 }, + { 0xfc61, G_UNICODE_NOT_PRESENT_OFFSET, 13409 }, + { 0xfc62, G_UNICODE_NOT_PRESENT_OFFSET, 13415 }, + { 0xfc63, G_UNICODE_NOT_PRESENT_OFFSET, 13421 }, + { 0xfc64, G_UNICODE_NOT_PRESENT_OFFSET, 13427 }, + { 0xfc65, G_UNICODE_NOT_PRESENT_OFFSET, 13434 }, + { 0xfc66, G_UNICODE_NOT_PRESENT_OFFSET, 12932 }, + { 0xfc67, G_UNICODE_NOT_PRESENT_OFFSET, 13441 }, + { 0xfc68, G_UNICODE_NOT_PRESENT_OFFSET, 12908 }, + { 0xfc69, G_UNICODE_NOT_PRESENT_OFFSET, 12939 }, + { 0xfc6a, G_UNICODE_NOT_PRESENT_OFFSET, 13448 }, + { 0xfc6b, G_UNICODE_NOT_PRESENT_OFFSET, 13453 }, + { 0xfc6c, G_UNICODE_NOT_PRESENT_OFFSET, 12961 }, + { 0xfc6d, G_UNICODE_NOT_PRESENT_OFFSET, 13458 }, + { 0xfc6e, G_UNICODE_NOT_PRESENT_OFFSET, 12966 }, + { 0xfc6f, G_UNICODE_NOT_PRESENT_OFFSET, 12971 }, + { 0xfc70, G_UNICODE_NOT_PRESENT_OFFSET, 13463 }, + { 0xfc71, G_UNICODE_NOT_PRESENT_OFFSET, 13468 }, + { 0xfc72, G_UNICODE_NOT_PRESENT_OFFSET, 12991 }, + { 0xfc73, G_UNICODE_NOT_PRESENT_OFFSET, 13473 }, + { 0xfc74, G_UNICODE_NOT_PRESENT_OFFSET, 12996 }, + { 0xfc75, G_UNICODE_NOT_PRESENT_OFFSET, 13001 }, + { 0xfc76, G_UNICODE_NOT_PRESENT_OFFSET, 13478 }, + { 0xfc77, G_UNICODE_NOT_PRESENT_OFFSET, 13483 }, + { 0xfc78, G_UNICODE_NOT_PRESENT_OFFSET, 13011 }, + { 0xfc79, G_UNICODE_NOT_PRESENT_OFFSET, 13488 }, + { 0xfc7a, G_UNICODE_NOT_PRESENT_OFFSET, 13016 }, + { 0xfc7b, G_UNICODE_NOT_PRESENT_OFFSET, 13021 }, + { 0xfc7c, G_UNICODE_NOT_PRESENT_OFFSET, 13166 }, + { 0xfc7d, G_UNICODE_NOT_PRESENT_OFFSET, 13171 }, + { 0xfc7e, G_UNICODE_NOT_PRESENT_OFFSET, 13186 }, + { 0xfc7f, G_UNICODE_NOT_PRESENT_OFFSET, 13191 }, + { 0xfc80, G_UNICODE_NOT_PRESENT_OFFSET, 13196 }, + { 0xfc81, G_UNICODE_NOT_PRESENT_OFFSET, 13216 }, + { 0xfc82, G_UNICODE_NOT_PRESENT_OFFSET, 13221 }, + { 0xfc83, G_UNICODE_NOT_PRESENT_OFFSET, 13226 }, + { 0xfc84, G_UNICODE_NOT_PRESENT_OFFSET, 13231 }, + { 0xfc85, G_UNICODE_NOT_PRESENT_OFFSET, 13251 }, + { 0xfc86, G_UNICODE_NOT_PRESENT_OFFSET, 13256 }, + { 0xfc87, G_UNICODE_NOT_PRESENT_OFFSET, 13261 }, + { 0xfc88, G_UNICODE_NOT_PRESENT_OFFSET, 13493 }, + { 0xfc89, G_UNICODE_NOT_PRESENT_OFFSET, 13281 }, + { 0xfc8a, G_UNICODE_NOT_PRESENT_OFFSET, 13498 }, + { 0xfc8b, G_UNICODE_NOT_PRESENT_OFFSET, 13503 }, + { 0xfc8c, G_UNICODE_NOT_PRESENT_OFFSET, 13311 }, + { 0xfc8d, G_UNICODE_NOT_PRESENT_OFFSET, 13508 }, + { 0xfc8e, G_UNICODE_NOT_PRESENT_OFFSET, 13316 }, + { 0xfc8f, G_UNICODE_NOT_PRESENT_OFFSET, 13321 }, + { 0xfc90, G_UNICODE_NOT_PRESENT_OFFSET, 13386 }, + { 0xfc91, G_UNICODE_NOT_PRESENT_OFFSET, 13513 }, + { 0xfc92, G_UNICODE_NOT_PRESENT_OFFSET, 13518 }, + { 0xfc93, G_UNICODE_NOT_PRESENT_OFFSET, 13361 }, + { 0xfc94, G_UNICODE_NOT_PRESENT_OFFSET, 13523 }, + { 0xfc95, G_UNICODE_NOT_PRESENT_OFFSET, 13366 }, + { 0xfc96, G_UNICODE_NOT_PRESENT_OFFSET, 13371 }, + { 0xfc97, G_UNICODE_NOT_PRESENT_OFFSET, 12918 }, + { 0xfc98, G_UNICODE_NOT_PRESENT_OFFSET, 12925 }, + { 0xfc99, G_UNICODE_NOT_PRESENT_OFFSET, 13528 }, + { 0xfc9a, G_UNICODE_NOT_PRESENT_OFFSET, 12932 }, + { 0xfc9b, G_UNICODE_NOT_PRESENT_OFFSET, 13535 }, + { 0xfc9c, G_UNICODE_NOT_PRESENT_OFFSET, 12946 }, + { 0xfc9d, G_UNICODE_NOT_PRESENT_OFFSET, 12951 }, + { 0xfc9e, G_UNICODE_NOT_PRESENT_OFFSET, 12956 }, + { 0xfc9f, G_UNICODE_NOT_PRESENT_OFFSET, 12961 }, + { 0xfca0, G_UNICODE_NOT_PRESENT_OFFSET, 13542 }, + { 0xfca1, G_UNICODE_NOT_PRESENT_OFFSET, 12976 }, + { 0xfca2, G_UNICODE_NOT_PRESENT_OFFSET, 12981 }, + { 0xfca3, G_UNICODE_NOT_PRESENT_OFFSET, 12986 }, + { 0xfca4, G_UNICODE_NOT_PRESENT_OFFSET, 12991 }, + { 0xfca5, G_UNICODE_NOT_PRESENT_OFFSET, 13547 }, + { 0xfca6, G_UNICODE_NOT_PRESENT_OFFSET, 13011 }, + { 0xfca7, G_UNICODE_NOT_PRESENT_OFFSET, 13026 }, + { 0xfca8, G_UNICODE_NOT_PRESENT_OFFSET, 13031 }, + { 0xfca9, G_UNICODE_NOT_PRESENT_OFFSET, 13036 }, + { 0xfcaa, G_UNICODE_NOT_PRESENT_OFFSET, 13041 }, + { 0xfcab, G_UNICODE_NOT_PRESENT_OFFSET, 13046 }, + { 0xfcac, G_UNICODE_NOT_PRESENT_OFFSET, 13056 }, + { 0xfcad, G_UNICODE_NOT_PRESENT_OFFSET, 13061 }, + { 0xfcae, G_UNICODE_NOT_PRESENT_OFFSET, 13066 }, + { 0xfcaf, G_UNICODE_NOT_PRESENT_OFFSET, 13071 }, + { 0xfcb0, G_UNICODE_NOT_PRESENT_OFFSET, 13076 }, + { 0xfcb1, G_UNICODE_NOT_PRESENT_OFFSET, 13081 }, + { 0xfcb2, G_UNICODE_NOT_PRESENT_OFFSET, 13552 }, + { 0xfcb3, G_UNICODE_NOT_PRESENT_OFFSET, 13086 }, + { 0xfcb4, G_UNICODE_NOT_PRESENT_OFFSET, 13091 }, + { 0xfcb5, G_UNICODE_NOT_PRESENT_OFFSET, 13096 }, + { 0xfcb6, G_UNICODE_NOT_PRESENT_OFFSET, 13101 }, + { 0xfcb7, G_UNICODE_NOT_PRESENT_OFFSET, 13106 }, + { 0xfcb8, G_UNICODE_NOT_PRESENT_OFFSET, 13111 }, + { 0xfcb9, G_UNICODE_NOT_PRESENT_OFFSET, 13121 }, + { 0xfcba, G_UNICODE_NOT_PRESENT_OFFSET, 13126 }, + { 0xfcbb, G_UNICODE_NOT_PRESENT_OFFSET, 13131 }, + { 0xfcbc, G_UNICODE_NOT_PRESENT_OFFSET, 13136 }, + { 0xfcbd, G_UNICODE_NOT_PRESENT_OFFSET, 13141 }, + { 0xfcbe, G_UNICODE_NOT_PRESENT_OFFSET, 13146 }, + { 0xfcbf, G_UNICODE_NOT_PRESENT_OFFSET, 13151 }, + { 0xfcc0, G_UNICODE_NOT_PRESENT_OFFSET, 13156 }, + { 0xfcc1, G_UNICODE_NOT_PRESENT_OFFSET, 13161 }, + { 0xfcc2, G_UNICODE_NOT_PRESENT_OFFSET, 13176 }, + { 0xfcc3, G_UNICODE_NOT_PRESENT_OFFSET, 13181 }, + { 0xfcc4, G_UNICODE_NOT_PRESENT_OFFSET, 13201 }, + { 0xfcc5, G_UNICODE_NOT_PRESENT_OFFSET, 13206 }, + { 0xfcc6, G_UNICODE_NOT_PRESENT_OFFSET, 13211 }, + { 0xfcc7, G_UNICODE_NOT_PRESENT_OFFSET, 13216 }, + { 0xfcc8, G_UNICODE_NOT_PRESENT_OFFSET, 13221 }, + { 0xfcc9, G_UNICODE_NOT_PRESENT_OFFSET, 13236 }, + { 0xfcca, G_UNICODE_NOT_PRESENT_OFFSET, 13241 }, + { 0xfccb, G_UNICODE_NOT_PRESENT_OFFSET, 13246 }, + { 0xfccc, G_UNICODE_NOT_PRESENT_OFFSET, 13251 }, + { 0xfccd, G_UNICODE_NOT_PRESENT_OFFSET, 13557 }, + { 0xfcce, G_UNICODE_NOT_PRESENT_OFFSET, 13266 }, + { 0xfccf, G_UNICODE_NOT_PRESENT_OFFSET, 13271 }, + { 0xfcd0, G_UNICODE_NOT_PRESENT_OFFSET, 13276 }, + { 0xfcd1, G_UNICODE_NOT_PRESENT_OFFSET, 13281 }, + { 0xfcd2, G_UNICODE_NOT_PRESENT_OFFSET, 13296 }, + { 0xfcd3, G_UNICODE_NOT_PRESENT_OFFSET, 13301 }, + { 0xfcd4, G_UNICODE_NOT_PRESENT_OFFSET, 13306 }, + { 0xfcd5, G_UNICODE_NOT_PRESENT_OFFSET, 13311 }, + { 0xfcd6, G_UNICODE_NOT_PRESENT_OFFSET, 13562 }, + { 0xfcd7, G_UNICODE_NOT_PRESENT_OFFSET, 13326 }, + { 0xfcd8, G_UNICODE_NOT_PRESENT_OFFSET, 13331 }, + { 0xfcd9, G_UNICODE_NOT_PRESENT_OFFSET, 13567 }, + { 0xfcda, G_UNICODE_NOT_PRESENT_OFFSET, 13346 }, + { 0xfcdb, G_UNICODE_NOT_PRESENT_OFFSET, 13351 }, + { 0xfcdc, G_UNICODE_NOT_PRESENT_OFFSET, 13356 }, + { 0xfcdd, G_UNICODE_NOT_PRESENT_OFFSET, 13361 }, + { 0xfcde, G_UNICODE_NOT_PRESENT_OFFSET, 13572 }, + { 0xfcdf, G_UNICODE_NOT_PRESENT_OFFSET, 12932 }, + { 0xfce0, G_UNICODE_NOT_PRESENT_OFFSET, 13535 }, + { 0xfce1, G_UNICODE_NOT_PRESENT_OFFSET, 12961 }, + { 0xfce2, G_UNICODE_NOT_PRESENT_OFFSET, 13542 }, + { 0xfce3, G_UNICODE_NOT_PRESENT_OFFSET, 12991 }, + { 0xfce4, G_UNICODE_NOT_PRESENT_OFFSET, 13547 }, + { 0xfce5, G_UNICODE_NOT_PRESENT_OFFSET, 13011 }, + { 0xfce6, G_UNICODE_NOT_PRESENT_OFFSET, 13577 }, + { 0xfce7, G_UNICODE_NOT_PRESENT_OFFSET, 13076 }, + { 0xfce8, G_UNICODE_NOT_PRESENT_OFFSET, 13582 }, + { 0xfce9, G_UNICODE_NOT_PRESENT_OFFSET, 13587 }, + { 0xfcea, G_UNICODE_NOT_PRESENT_OFFSET, 13592 }, + { 0xfceb, G_UNICODE_NOT_PRESENT_OFFSET, 13216 }, + { 0xfcec, G_UNICODE_NOT_PRESENT_OFFSET, 13221 }, + { 0xfced, G_UNICODE_NOT_PRESENT_OFFSET, 13251 }, + { 0xfcee, G_UNICODE_NOT_PRESENT_OFFSET, 13311 }, + { 0xfcef, G_UNICODE_NOT_PRESENT_OFFSET, 13562 }, + { 0xfcf0, G_UNICODE_NOT_PRESENT_OFFSET, 13361 }, + { 0xfcf1, G_UNICODE_NOT_PRESENT_OFFSET, 13572 }, + { 0xfcf2, G_UNICODE_NOT_PRESENT_OFFSET, 13597 }, + { 0xfcf3, G_UNICODE_NOT_PRESENT_OFFSET, 13604 }, + { 0xfcf4, G_UNICODE_NOT_PRESENT_OFFSET, 13611 }, + { 0xfcf5, G_UNICODE_NOT_PRESENT_OFFSET, 13618 }, + { 0xfcf6, G_UNICODE_NOT_PRESENT_OFFSET, 13623 }, + { 0xfcf7, G_UNICODE_NOT_PRESENT_OFFSET, 13628 }, + { 0xfcf8, G_UNICODE_NOT_PRESENT_OFFSET, 13633 }, + { 0xfcf9, G_UNICODE_NOT_PRESENT_OFFSET, 13638 }, + { 0xfcfa, G_UNICODE_NOT_PRESENT_OFFSET, 13643 }, + { 0xfcfb, G_UNICODE_NOT_PRESENT_OFFSET, 13648 }, + { 0xfcfc, G_UNICODE_NOT_PRESENT_OFFSET, 13653 }, + { 0xfcfd, G_UNICODE_NOT_PRESENT_OFFSET, 13658 }, + { 0xfcfe, G_UNICODE_NOT_PRESENT_OFFSET, 13663 }, + { 0xfcff, G_UNICODE_NOT_PRESENT_OFFSET, 13668 }, + { 0xfd00, G_UNICODE_NOT_PRESENT_OFFSET, 13673 }, + { 0xfd01, G_UNICODE_NOT_PRESENT_OFFSET, 13678 }, + { 0xfd02, G_UNICODE_NOT_PRESENT_OFFSET, 13683 }, + { 0xfd03, G_UNICODE_NOT_PRESENT_OFFSET, 13688 }, + { 0xfd04, G_UNICODE_NOT_PRESENT_OFFSET, 13693 }, + { 0xfd05, G_UNICODE_NOT_PRESENT_OFFSET, 13698 }, + { 0xfd06, G_UNICODE_NOT_PRESENT_OFFSET, 13703 }, + { 0xfd07, G_UNICODE_NOT_PRESENT_OFFSET, 13708 }, + { 0xfd08, G_UNICODE_NOT_PRESENT_OFFSET, 13713 }, + { 0xfd09, G_UNICODE_NOT_PRESENT_OFFSET, 13718 }, + { 0xfd0a, G_UNICODE_NOT_PRESENT_OFFSET, 13723 }, + { 0xfd0b, G_UNICODE_NOT_PRESENT_OFFSET, 13728 }, + { 0xfd0c, G_UNICODE_NOT_PRESENT_OFFSET, 13587 }, + { 0xfd0d, G_UNICODE_NOT_PRESENT_OFFSET, 13733 }, + { 0xfd0e, G_UNICODE_NOT_PRESENT_OFFSET, 13738 }, + { 0xfd0f, G_UNICODE_NOT_PRESENT_OFFSET, 13743 }, + { 0xfd10, G_UNICODE_NOT_PRESENT_OFFSET, 13748 }, + { 0xfd11, G_UNICODE_NOT_PRESENT_OFFSET, 13618 }, + { 0xfd12, G_UNICODE_NOT_PRESENT_OFFSET, 13623 }, + { 0xfd13, G_UNICODE_NOT_PRESENT_OFFSET, 13628 }, + { 0xfd14, G_UNICODE_NOT_PRESENT_OFFSET, 13633 }, + { 0xfd15, G_UNICODE_NOT_PRESENT_OFFSET, 13638 }, + { 0xfd16, G_UNICODE_NOT_PRESENT_OFFSET, 13643 }, + { 0xfd17, G_UNICODE_NOT_PRESENT_OFFSET, 13648 }, + { 0xfd18, G_UNICODE_NOT_PRESENT_OFFSET, 13653 }, + { 0xfd19, G_UNICODE_NOT_PRESENT_OFFSET, 13658 }, + { 0xfd1a, G_UNICODE_NOT_PRESENT_OFFSET, 13663 }, + { 0xfd1b, G_UNICODE_NOT_PRESENT_OFFSET, 13668 }, + { 0xfd1c, G_UNICODE_NOT_PRESENT_OFFSET, 13673 }, + { 0xfd1d, G_UNICODE_NOT_PRESENT_OFFSET, 13678 }, + { 0xfd1e, G_UNICODE_NOT_PRESENT_OFFSET, 13683 }, + { 0xfd1f, G_UNICODE_NOT_PRESENT_OFFSET, 13688 }, + { 0xfd20, G_UNICODE_NOT_PRESENT_OFFSET, 13693 }, + { 0xfd21, G_UNICODE_NOT_PRESENT_OFFSET, 13698 }, + { 0xfd22, G_UNICODE_NOT_PRESENT_OFFSET, 13703 }, + { 0xfd23, G_UNICODE_NOT_PRESENT_OFFSET, 13708 }, + { 0xfd24, G_UNICODE_NOT_PRESENT_OFFSET, 13713 }, + { 0xfd25, G_UNICODE_NOT_PRESENT_OFFSET, 13718 }, + { 0xfd26, G_UNICODE_NOT_PRESENT_OFFSET, 13723 }, + { 0xfd27, G_UNICODE_NOT_PRESENT_OFFSET, 13728 }, + { 0xfd28, G_UNICODE_NOT_PRESENT_OFFSET, 13587 }, + { 0xfd29, G_UNICODE_NOT_PRESENT_OFFSET, 13733 }, + { 0xfd2a, G_UNICODE_NOT_PRESENT_OFFSET, 13738 }, + { 0xfd2b, G_UNICODE_NOT_PRESENT_OFFSET, 13743 }, + { 0xfd2c, G_UNICODE_NOT_PRESENT_OFFSET, 13748 }, + { 0xfd2d, G_UNICODE_NOT_PRESENT_OFFSET, 13718 }, + { 0xfd2e, G_UNICODE_NOT_PRESENT_OFFSET, 13723 }, + { 0xfd2f, G_UNICODE_NOT_PRESENT_OFFSET, 13728 }, + { 0xfd30, G_UNICODE_NOT_PRESENT_OFFSET, 13587 }, + { 0xfd31, G_UNICODE_NOT_PRESENT_OFFSET, 13582 }, + { 0xfd32, G_UNICODE_NOT_PRESENT_OFFSET, 13592 }, + { 0xfd33, G_UNICODE_NOT_PRESENT_OFFSET, 13116 }, + { 0xfd34, G_UNICODE_NOT_PRESENT_OFFSET, 13061 }, + { 0xfd35, G_UNICODE_NOT_PRESENT_OFFSET, 13066 }, + { 0xfd36, G_UNICODE_NOT_PRESENT_OFFSET, 13071 }, + { 0xfd37, G_UNICODE_NOT_PRESENT_OFFSET, 13718 }, + { 0xfd38, G_UNICODE_NOT_PRESENT_OFFSET, 13723 }, + { 0xfd39, G_UNICODE_NOT_PRESENT_OFFSET, 13728 }, + { 0xfd3a, G_UNICODE_NOT_PRESENT_OFFSET, 13116 }, + { 0xfd3b, G_UNICODE_NOT_PRESENT_OFFSET, 13121 }, + { 0xfd3c, G_UNICODE_NOT_PRESENT_OFFSET, 13753 }, + { 0xfd3d, G_UNICODE_NOT_PRESENT_OFFSET, 13753 }, + { 0xfd50, G_UNICODE_NOT_PRESENT_OFFSET, 13758 }, + { 0xfd51, G_UNICODE_NOT_PRESENT_OFFSET, 13765 }, + { 0xfd52, G_UNICODE_NOT_PRESENT_OFFSET, 13765 }, + { 0xfd53, G_UNICODE_NOT_PRESENT_OFFSET, 13772 }, + { 0xfd54, G_UNICODE_NOT_PRESENT_OFFSET, 13779 }, + { 0xfd55, G_UNICODE_NOT_PRESENT_OFFSET, 13786 }, + { 0xfd56, G_UNICODE_NOT_PRESENT_OFFSET, 13793 }, + { 0xfd57, G_UNICODE_NOT_PRESENT_OFFSET, 13800 }, + { 0xfd58, G_UNICODE_NOT_PRESENT_OFFSET, 13807 }, + { 0xfd59, G_UNICODE_NOT_PRESENT_OFFSET, 13807 }, + { 0xfd5a, G_UNICODE_NOT_PRESENT_OFFSET, 13814 }, + { 0xfd5b, G_UNICODE_NOT_PRESENT_OFFSET, 13821 }, + { 0xfd5c, G_UNICODE_NOT_PRESENT_OFFSET, 13828 }, + { 0xfd5d, G_UNICODE_NOT_PRESENT_OFFSET, 13835 }, + { 0xfd5e, G_UNICODE_NOT_PRESENT_OFFSET, 13842 }, + { 0xfd5f, G_UNICODE_NOT_PRESENT_OFFSET, 13849 }, + { 0xfd60, G_UNICODE_NOT_PRESENT_OFFSET, 13849 }, + { 0xfd61, G_UNICODE_NOT_PRESENT_OFFSET, 13856 }, + { 0xfd62, G_UNICODE_NOT_PRESENT_OFFSET, 13863 }, + { 0xfd63, G_UNICODE_NOT_PRESENT_OFFSET, 13863 }, + { 0xfd64, G_UNICODE_NOT_PRESENT_OFFSET, 13870 }, + { 0xfd65, G_UNICODE_NOT_PRESENT_OFFSET, 13870 }, + { 0xfd66, G_UNICODE_NOT_PRESENT_OFFSET, 13877 }, + { 0xfd67, G_UNICODE_NOT_PRESENT_OFFSET, 13884 }, + { 0xfd68, G_UNICODE_NOT_PRESENT_OFFSET, 13884 }, + { 0xfd69, G_UNICODE_NOT_PRESENT_OFFSET, 13891 }, + { 0xfd6a, G_UNICODE_NOT_PRESENT_OFFSET, 13898 }, + { 0xfd6b, G_UNICODE_NOT_PRESENT_OFFSET, 13898 }, + { 0xfd6c, G_UNICODE_NOT_PRESENT_OFFSET, 13905 }, + { 0xfd6d, G_UNICODE_NOT_PRESENT_OFFSET, 13905 }, + { 0xfd6e, G_UNICODE_NOT_PRESENT_OFFSET, 13912 }, + { 0xfd6f, G_UNICODE_NOT_PRESENT_OFFSET, 13919 }, + { 0xfd70, G_UNICODE_NOT_PRESENT_OFFSET, 13919 }, + { 0xfd71, G_UNICODE_NOT_PRESENT_OFFSET, 13926 }, + { 0xfd72, G_UNICODE_NOT_PRESENT_OFFSET, 13926 }, + { 0xfd73, G_UNICODE_NOT_PRESENT_OFFSET, 13933 }, + { 0xfd74, G_UNICODE_NOT_PRESENT_OFFSET, 13940 }, + { 0xfd75, G_UNICODE_NOT_PRESENT_OFFSET, 13947 }, + { 0xfd76, G_UNICODE_NOT_PRESENT_OFFSET, 13954 }, + { 0xfd77, G_UNICODE_NOT_PRESENT_OFFSET, 13954 }, + { 0xfd78, G_UNICODE_NOT_PRESENT_OFFSET, 13961 }, + { 0xfd79, G_UNICODE_NOT_PRESENT_OFFSET, 13968 }, + { 0xfd7a, G_UNICODE_NOT_PRESENT_OFFSET, 13975 }, + { 0xfd7b, G_UNICODE_NOT_PRESENT_OFFSET, 13982 }, + { 0xfd7c, G_UNICODE_NOT_PRESENT_OFFSET, 13989 }, + { 0xfd7d, G_UNICODE_NOT_PRESENT_OFFSET, 13989 }, + { 0xfd7e, G_UNICODE_NOT_PRESENT_OFFSET, 13996 }, + { 0xfd7f, G_UNICODE_NOT_PRESENT_OFFSET, 14003 }, + { 0xfd80, G_UNICODE_NOT_PRESENT_OFFSET, 14010 }, + { 0xfd81, G_UNICODE_NOT_PRESENT_OFFSET, 14017 }, + { 0xfd82, G_UNICODE_NOT_PRESENT_OFFSET, 14024 }, + { 0xfd83, G_UNICODE_NOT_PRESENT_OFFSET, 14031 }, + { 0xfd84, G_UNICODE_NOT_PRESENT_OFFSET, 14031 }, + { 0xfd85, G_UNICODE_NOT_PRESENT_OFFSET, 14038 }, + { 0xfd86, G_UNICODE_NOT_PRESENT_OFFSET, 14038 }, + { 0xfd87, G_UNICODE_NOT_PRESENT_OFFSET, 14045 }, + { 0xfd88, G_UNICODE_NOT_PRESENT_OFFSET, 14045 }, + { 0xfd89, G_UNICODE_NOT_PRESENT_OFFSET, 14052 }, + { 0xfd8a, G_UNICODE_NOT_PRESENT_OFFSET, 14059 }, + { 0xfd8b, G_UNICODE_NOT_PRESENT_OFFSET, 14066 }, + { 0xfd8c, G_UNICODE_NOT_PRESENT_OFFSET, 14073 }, + { 0xfd8d, G_UNICODE_NOT_PRESENT_OFFSET, 14080 }, + { 0xfd8e, G_UNICODE_NOT_PRESENT_OFFSET, 14087 }, + { 0xfd8f, G_UNICODE_NOT_PRESENT_OFFSET, 14094 }, + { 0xfd92, G_UNICODE_NOT_PRESENT_OFFSET, 14101 }, + { 0xfd93, G_UNICODE_NOT_PRESENT_OFFSET, 14108 }, + { 0xfd94, G_UNICODE_NOT_PRESENT_OFFSET, 14115 }, + { 0xfd95, G_UNICODE_NOT_PRESENT_OFFSET, 14122 }, + { 0xfd96, G_UNICODE_NOT_PRESENT_OFFSET, 14129 }, + { 0xfd97, G_UNICODE_NOT_PRESENT_OFFSET, 14136 }, + { 0xfd98, G_UNICODE_NOT_PRESENT_OFFSET, 14136 }, + { 0xfd99, G_UNICODE_NOT_PRESENT_OFFSET, 14143 }, + { 0xfd9a, G_UNICODE_NOT_PRESENT_OFFSET, 14150 }, + { 0xfd9b, G_UNICODE_NOT_PRESENT_OFFSET, 14157 }, + { 0xfd9c, G_UNICODE_NOT_PRESENT_OFFSET, 14164 }, + { 0xfd9d, G_UNICODE_NOT_PRESENT_OFFSET, 14164 }, + { 0xfd9e, G_UNICODE_NOT_PRESENT_OFFSET, 14171 }, + { 0xfd9f, G_UNICODE_NOT_PRESENT_OFFSET, 14178 }, + { 0xfda0, G_UNICODE_NOT_PRESENT_OFFSET, 14185 }, + { 0xfda1, G_UNICODE_NOT_PRESENT_OFFSET, 14192 }, + { 0xfda2, G_UNICODE_NOT_PRESENT_OFFSET, 14199 }, + { 0xfda3, G_UNICODE_NOT_PRESENT_OFFSET, 14206 }, + { 0xfda4, G_UNICODE_NOT_PRESENT_OFFSET, 14213 }, + { 0xfda5, G_UNICODE_NOT_PRESENT_OFFSET, 14220 }, + { 0xfda6, G_UNICODE_NOT_PRESENT_OFFSET, 14227 }, + { 0xfda7, G_UNICODE_NOT_PRESENT_OFFSET, 14234 }, + { 0xfda8, G_UNICODE_NOT_PRESENT_OFFSET, 14241 }, + { 0xfda9, G_UNICODE_NOT_PRESENT_OFFSET, 14248 }, + { 0xfdaa, G_UNICODE_NOT_PRESENT_OFFSET, 14255 }, + { 0xfdab, G_UNICODE_NOT_PRESENT_OFFSET, 14262 }, + { 0xfdac, G_UNICODE_NOT_PRESENT_OFFSET, 14269 }, + { 0xfdad, G_UNICODE_NOT_PRESENT_OFFSET, 14276 }, + { 0xfdae, G_UNICODE_NOT_PRESENT_OFFSET, 14283 }, + { 0xfdaf, G_UNICODE_NOT_PRESENT_OFFSET, 14290 }, + { 0xfdb0, G_UNICODE_NOT_PRESENT_OFFSET, 14297 }, + { 0xfdb1, G_UNICODE_NOT_PRESENT_OFFSET, 14304 }, + { 0xfdb2, G_UNICODE_NOT_PRESENT_OFFSET, 14311 }, + { 0xfdb3, G_UNICODE_NOT_PRESENT_OFFSET, 14318 }, + { 0xfdb4, G_UNICODE_NOT_PRESENT_OFFSET, 13996 }, + { 0xfdb5, G_UNICODE_NOT_PRESENT_OFFSET, 14010 }, + { 0xfdb6, G_UNICODE_NOT_PRESENT_OFFSET, 14325 }, + { 0xfdb7, G_UNICODE_NOT_PRESENT_OFFSET, 14332 }, + { 0xfdb8, G_UNICODE_NOT_PRESENT_OFFSET, 14339 }, + { 0xfdb9, G_UNICODE_NOT_PRESENT_OFFSET, 14346 }, + { 0xfdba, G_UNICODE_NOT_PRESENT_OFFSET, 14353 }, + { 0xfdbb, G_UNICODE_NOT_PRESENT_OFFSET, 14360 }, + { 0xfdbc, G_UNICODE_NOT_PRESENT_OFFSET, 14353 }, + { 0xfdbd, G_UNICODE_NOT_PRESENT_OFFSET, 14339 }, + { 0xfdbe, G_UNICODE_NOT_PRESENT_OFFSET, 14367 }, + { 0xfdbf, G_UNICODE_NOT_PRESENT_OFFSET, 14374 }, + { 0xfdc0, G_UNICODE_NOT_PRESENT_OFFSET, 14381 }, + { 0xfdc1, G_UNICODE_NOT_PRESENT_OFFSET, 14388 }, + { 0xfdc2, G_UNICODE_NOT_PRESENT_OFFSET, 14395 }, + { 0xfdc3, G_UNICODE_NOT_PRESENT_OFFSET, 14360 }, + { 0xfdc4, G_UNICODE_NOT_PRESENT_OFFSET, 13947 }, + { 0xfdc5, G_UNICODE_NOT_PRESENT_OFFSET, 13877 }, + { 0xfdc6, G_UNICODE_NOT_PRESENT_OFFSET, 14402 }, + { 0xfdc7, G_UNICODE_NOT_PRESENT_OFFSET, 14409 }, + { 0xfdf0, G_UNICODE_NOT_PRESENT_OFFSET, 14416 }, + { 0xfdf1, G_UNICODE_NOT_PRESENT_OFFSET, 14423 }, + { 0xfdf2, G_UNICODE_NOT_PRESENT_OFFSET, 14430 }, + { 0xfdf3, G_UNICODE_NOT_PRESENT_OFFSET, 14439 }, + { 0xfdf4, G_UNICODE_NOT_PRESENT_OFFSET, 14448 }, + { 0xfdf5, G_UNICODE_NOT_PRESENT_OFFSET, 14457 }, + { 0xfdf6, G_UNICODE_NOT_PRESENT_OFFSET, 14466 }, + { 0xfdf7, G_UNICODE_NOT_PRESENT_OFFSET, 14475 }, + { 0xfdf8, G_UNICODE_NOT_PRESENT_OFFSET, 14484 }, + { 0xfdf9, G_UNICODE_NOT_PRESENT_OFFSET, 14493 }, + { 0xfdfa, G_UNICODE_NOT_PRESENT_OFFSET, 14500 }, + { 0xfdfb, G_UNICODE_NOT_PRESENT_OFFSET, 14534 }, + { 0xfdfc, G_UNICODE_NOT_PRESENT_OFFSET, 14550 }, + { 0xfe10, G_UNICODE_NOT_PRESENT_OFFSET, 14559 }, + { 0xfe11, G_UNICODE_NOT_PRESENT_OFFSET, 14561 }, + { 0xfe12, G_UNICODE_NOT_PRESENT_OFFSET, 14565 }, + { 0xfe13, G_UNICODE_NOT_PRESENT_OFFSET, 14569 }, + { 0xfe14, G_UNICODE_NOT_PRESENT_OFFSET, 1248 }, + { 0xfe15, G_UNICODE_NOT_PRESENT_OFFSET, 14571 }, + { 0xfe16, G_UNICODE_NOT_PRESENT_OFFSET, 14573 }, + { 0xfe17, G_UNICODE_NOT_PRESENT_OFFSET, 14575 }, + { 0xfe18, G_UNICODE_NOT_PRESENT_OFFSET, 14579 }, + { 0xfe19, G_UNICODE_NOT_PRESENT_OFFSET, 5186 }, + { 0xfe30, G_UNICODE_NOT_PRESENT_OFFSET, 5183 }, + { 0xfe31, G_UNICODE_NOT_PRESENT_OFFSET, 14583 }, + { 0xfe32, G_UNICODE_NOT_PRESENT_OFFSET, 14587 }, + { 0xfe33, G_UNICODE_NOT_PRESENT_OFFSET, 14591 }, + { 0xfe34, G_UNICODE_NOT_PRESENT_OFFSET, 14591 }, + { 0xfe35, G_UNICODE_NOT_PRESENT_OFFSET, 5275 }, + { 0xfe36, G_UNICODE_NOT_PRESENT_OFFSET, 5277 }, + { 0xfe37, G_UNICODE_NOT_PRESENT_OFFSET, 14593 }, + { 0xfe38, G_UNICODE_NOT_PRESENT_OFFSET, 14595 }, + { 0xfe39, G_UNICODE_NOT_PRESENT_OFFSET, 14597 }, + { 0xfe3a, G_UNICODE_NOT_PRESENT_OFFSET, 14601 }, + { 0xfe3b, G_UNICODE_NOT_PRESENT_OFFSET, 14605 }, + { 0xfe3c, G_UNICODE_NOT_PRESENT_OFFSET, 14609 }, + { 0xfe3d, G_UNICODE_NOT_PRESENT_OFFSET, 14613 }, + { 0xfe3e, G_UNICODE_NOT_PRESENT_OFFSET, 14617 }, + { 0xfe3f, G_UNICODE_NOT_PRESENT_OFFSET, 5826 }, + { 0xfe40, G_UNICODE_NOT_PRESENT_OFFSET, 5830 }, + { 0xfe41, G_UNICODE_NOT_PRESENT_OFFSET, 14621 }, + { 0xfe42, G_UNICODE_NOT_PRESENT_OFFSET, 14625 }, + { 0xfe43, G_UNICODE_NOT_PRESENT_OFFSET, 14629 }, + { 0xfe44, G_UNICODE_NOT_PRESENT_OFFSET, 14633 }, + { 0xfe47, G_UNICODE_NOT_PRESENT_OFFSET, 14637 }, + { 0xfe48, G_UNICODE_NOT_PRESENT_OFFSET, 14639 }, + { 0xfe49, G_UNICODE_NOT_PRESENT_OFFSET, 5227 }, + { 0xfe4a, G_UNICODE_NOT_PRESENT_OFFSET, 5227 }, + { 0xfe4b, G_UNICODE_NOT_PRESENT_OFFSET, 5227 }, + { 0xfe4c, G_UNICODE_NOT_PRESENT_OFFSET, 5227 }, + { 0xfe4d, G_UNICODE_NOT_PRESENT_OFFSET, 14591 }, + { 0xfe4e, G_UNICODE_NOT_PRESENT_OFFSET, 14591 }, + { 0xfe4f, G_UNICODE_NOT_PRESENT_OFFSET, 14591 }, + { 0xfe50, G_UNICODE_NOT_PRESENT_OFFSET, 14559 }, + { 0xfe51, G_UNICODE_NOT_PRESENT_OFFSET, 14561 }, + { 0xfe52, G_UNICODE_NOT_PRESENT_OFFSET, 5181 }, + { 0xfe54, G_UNICODE_NOT_PRESENT_OFFSET, 1248 }, + { 0xfe55, G_UNICODE_NOT_PRESENT_OFFSET, 14569 }, + { 0xfe56, G_UNICODE_NOT_PRESENT_OFFSET, 14573 }, + { 0xfe57, G_UNICODE_NOT_PRESENT_OFFSET, 14571 }, + { 0xfe58, G_UNICODE_NOT_PRESENT_OFFSET, 14583 }, + { 0xfe59, G_UNICODE_NOT_PRESENT_OFFSET, 5275 }, + { 0xfe5a, G_UNICODE_NOT_PRESENT_OFFSET, 5277 }, + { 0xfe5b, G_UNICODE_NOT_PRESENT_OFFSET, 14593 }, + { 0xfe5c, G_UNICODE_NOT_PRESENT_OFFSET, 14595 }, + { 0xfe5d, G_UNICODE_NOT_PRESENT_OFFSET, 14597 }, + { 0xfe5e, G_UNICODE_NOT_PRESENT_OFFSET, 14601 }, + { 0xfe5f, G_UNICODE_NOT_PRESENT_OFFSET, 14641 }, + { 0xfe60, G_UNICODE_NOT_PRESENT_OFFSET, 14643 }, + { 0xfe61, G_UNICODE_NOT_PRESENT_OFFSET, 14645 }, + { 0xfe62, G_UNICODE_NOT_PRESENT_OFFSET, 5267 }, + { 0xfe63, G_UNICODE_NOT_PRESENT_OFFSET, 14647 }, + { 0xfe64, G_UNICODE_NOT_PRESENT_OFFSET, 14649 }, + { 0xfe65, G_UNICODE_NOT_PRESENT_OFFSET, 14651 }, + { 0xfe66, G_UNICODE_NOT_PRESENT_OFFSET, 5273 }, + { 0xfe68, G_UNICODE_NOT_PRESENT_OFFSET, 14653 }, + { 0xfe69, G_UNICODE_NOT_PRESENT_OFFSET, 14655 }, + { 0xfe6a, G_UNICODE_NOT_PRESENT_OFFSET, 14657 }, + { 0xfe6b, G_UNICODE_NOT_PRESENT_OFFSET, 14659 }, + { 0xfe70, G_UNICODE_NOT_PRESENT_OFFSET, 14661 }, + { 0xfe71, G_UNICODE_NOT_PRESENT_OFFSET, 14665 }, + { 0xfe72, G_UNICODE_NOT_PRESENT_OFFSET, 14670 }, + { 0xfe74, G_UNICODE_NOT_PRESENT_OFFSET, 14674 }, + { 0xfe76, G_UNICODE_NOT_PRESENT_OFFSET, 14678 }, + { 0xfe77, G_UNICODE_NOT_PRESENT_OFFSET, 14682 }, + { 0xfe78, G_UNICODE_NOT_PRESENT_OFFSET, 14687 }, + { 0xfe79, G_UNICODE_NOT_PRESENT_OFFSET, 14691 }, + { 0xfe7a, G_UNICODE_NOT_PRESENT_OFFSET, 14696 }, + { 0xfe7b, G_UNICODE_NOT_PRESENT_OFFSET, 14700 }, + { 0xfe7c, G_UNICODE_NOT_PRESENT_OFFSET, 14705 }, + { 0xfe7d, G_UNICODE_NOT_PRESENT_OFFSET, 14709 }, + { 0xfe7e, G_UNICODE_NOT_PRESENT_OFFSET, 14714 }, + { 0xfe7f, G_UNICODE_NOT_PRESENT_OFFSET, 14718 }, + { 0xfe80, G_UNICODE_NOT_PRESENT_OFFSET, 14723 }, + { 0xfe81, G_UNICODE_NOT_PRESENT_OFFSET, 1676 }, + { 0xfe82, G_UNICODE_NOT_PRESENT_OFFSET, 1676 }, + { 0xfe83, G_UNICODE_NOT_PRESENT_OFFSET, 1681 }, + { 0xfe84, G_UNICODE_NOT_PRESENT_OFFSET, 1681 }, + { 0xfe85, G_UNICODE_NOT_PRESENT_OFFSET, 1686 }, + { 0xfe86, G_UNICODE_NOT_PRESENT_OFFSET, 1686 }, + { 0xfe87, G_UNICODE_NOT_PRESENT_OFFSET, 1691 }, + { 0xfe88, G_UNICODE_NOT_PRESENT_OFFSET, 1691 }, + { 0xfe89, G_UNICODE_NOT_PRESENT_OFFSET, 1696 }, + { 0xfe8a, G_UNICODE_NOT_PRESENT_OFFSET, 1696 }, + { 0xfe8b, G_UNICODE_NOT_PRESENT_OFFSET, 1696 }, + { 0xfe8c, G_UNICODE_NOT_PRESENT_OFFSET, 1696 }, + { 0xfe8d, G_UNICODE_NOT_PRESENT_OFFSET, 14726 }, + { 0xfe8e, G_UNICODE_NOT_PRESENT_OFFSET, 14726 }, + { 0xfe8f, G_UNICODE_NOT_PRESENT_OFFSET, 14729 }, + { 0xfe90, G_UNICODE_NOT_PRESENT_OFFSET, 14729 }, + { 0xfe91, G_UNICODE_NOT_PRESENT_OFFSET, 14729 }, + { 0xfe92, G_UNICODE_NOT_PRESENT_OFFSET, 14729 }, + { 0xfe93, G_UNICODE_NOT_PRESENT_OFFSET, 14732 }, + { 0xfe94, G_UNICODE_NOT_PRESENT_OFFSET, 14732 }, + { 0xfe95, G_UNICODE_NOT_PRESENT_OFFSET, 14735 }, + { 0xfe96, G_UNICODE_NOT_PRESENT_OFFSET, 14735 }, + { 0xfe97, G_UNICODE_NOT_PRESENT_OFFSET, 14735 }, + { 0xfe98, G_UNICODE_NOT_PRESENT_OFFSET, 14735 }, + { 0xfe99, G_UNICODE_NOT_PRESENT_OFFSET, 14738 }, + { 0xfe9a, G_UNICODE_NOT_PRESENT_OFFSET, 14738 }, + { 0xfe9b, G_UNICODE_NOT_PRESENT_OFFSET, 14738 }, + { 0xfe9c, G_UNICODE_NOT_PRESENT_OFFSET, 14738 }, + { 0xfe9d, G_UNICODE_NOT_PRESENT_OFFSET, 14741 }, + { 0xfe9e, G_UNICODE_NOT_PRESENT_OFFSET, 14741 }, + { 0xfe9f, G_UNICODE_NOT_PRESENT_OFFSET, 14741 }, + { 0xfea0, G_UNICODE_NOT_PRESENT_OFFSET, 14741 }, + { 0xfea1, G_UNICODE_NOT_PRESENT_OFFSET, 14744 }, + { 0xfea2, G_UNICODE_NOT_PRESENT_OFFSET, 14744 }, + { 0xfea3, G_UNICODE_NOT_PRESENT_OFFSET, 14744 }, + { 0xfea4, G_UNICODE_NOT_PRESENT_OFFSET, 14744 }, + { 0xfea5, G_UNICODE_NOT_PRESENT_OFFSET, 14747 }, + { 0xfea6, G_UNICODE_NOT_PRESENT_OFFSET, 14747 }, + { 0xfea7, G_UNICODE_NOT_PRESENT_OFFSET, 14747 }, + { 0xfea8, G_UNICODE_NOT_PRESENT_OFFSET, 14747 }, + { 0xfea9, G_UNICODE_NOT_PRESENT_OFFSET, 14750 }, + { 0xfeaa, G_UNICODE_NOT_PRESENT_OFFSET, 14750 }, + { 0xfeab, G_UNICODE_NOT_PRESENT_OFFSET, 14753 }, + { 0xfeac, G_UNICODE_NOT_PRESENT_OFFSET, 14753 }, + { 0xfead, G_UNICODE_NOT_PRESENT_OFFSET, 14756 }, + { 0xfeae, G_UNICODE_NOT_PRESENT_OFFSET, 14756 }, + { 0xfeaf, G_UNICODE_NOT_PRESENT_OFFSET, 14759 }, + { 0xfeb0, G_UNICODE_NOT_PRESENT_OFFSET, 14759 }, + { 0xfeb1, G_UNICODE_NOT_PRESENT_OFFSET, 14762 }, + { 0xfeb2, G_UNICODE_NOT_PRESENT_OFFSET, 14762 }, + { 0xfeb3, G_UNICODE_NOT_PRESENT_OFFSET, 14762 }, + { 0xfeb4, G_UNICODE_NOT_PRESENT_OFFSET, 14762 }, + { 0xfeb5, G_UNICODE_NOT_PRESENT_OFFSET, 14765 }, + { 0xfeb6, G_UNICODE_NOT_PRESENT_OFFSET, 14765 }, + { 0xfeb7, G_UNICODE_NOT_PRESENT_OFFSET, 14765 }, + { 0xfeb8, G_UNICODE_NOT_PRESENT_OFFSET, 14765 }, + { 0xfeb9, G_UNICODE_NOT_PRESENT_OFFSET, 14768 }, + { 0xfeba, G_UNICODE_NOT_PRESENT_OFFSET, 14768 }, + { 0xfebb, G_UNICODE_NOT_PRESENT_OFFSET, 14768 }, + { 0xfebc, G_UNICODE_NOT_PRESENT_OFFSET, 14768 }, + { 0xfebd, G_UNICODE_NOT_PRESENT_OFFSET, 14771 }, + { 0xfebe, G_UNICODE_NOT_PRESENT_OFFSET, 14771 }, + { 0xfebf, G_UNICODE_NOT_PRESENT_OFFSET, 14771 }, + { 0xfec0, G_UNICODE_NOT_PRESENT_OFFSET, 14771 }, + { 0xfec1, G_UNICODE_NOT_PRESENT_OFFSET, 14774 }, + { 0xfec2, G_UNICODE_NOT_PRESENT_OFFSET, 14774 }, + { 0xfec3, G_UNICODE_NOT_PRESENT_OFFSET, 14774 }, + { 0xfec4, G_UNICODE_NOT_PRESENT_OFFSET, 14774 }, + { 0xfec5, G_UNICODE_NOT_PRESENT_OFFSET, 14777 }, + { 0xfec6, G_UNICODE_NOT_PRESENT_OFFSET, 14777 }, + { 0xfec7, G_UNICODE_NOT_PRESENT_OFFSET, 14777 }, + { 0xfec8, G_UNICODE_NOT_PRESENT_OFFSET, 14777 }, + { 0xfec9, G_UNICODE_NOT_PRESENT_OFFSET, 14780 }, + { 0xfeca, G_UNICODE_NOT_PRESENT_OFFSET, 14780 }, + { 0xfecb, G_UNICODE_NOT_PRESENT_OFFSET, 14780 }, + { 0xfecc, G_UNICODE_NOT_PRESENT_OFFSET, 14780 }, + { 0xfecd, G_UNICODE_NOT_PRESENT_OFFSET, 14783 }, + { 0xfece, G_UNICODE_NOT_PRESENT_OFFSET, 14783 }, + { 0xfecf, G_UNICODE_NOT_PRESENT_OFFSET, 14783 }, + { 0xfed0, G_UNICODE_NOT_PRESENT_OFFSET, 14783 }, + { 0xfed1, G_UNICODE_NOT_PRESENT_OFFSET, 14786 }, + { 0xfed2, G_UNICODE_NOT_PRESENT_OFFSET, 14786 }, + { 0xfed3, G_UNICODE_NOT_PRESENT_OFFSET, 14786 }, + { 0xfed4, G_UNICODE_NOT_PRESENT_OFFSET, 14786 }, + { 0xfed5, G_UNICODE_NOT_PRESENT_OFFSET, 14789 }, + { 0xfed6, G_UNICODE_NOT_PRESENT_OFFSET, 14789 }, + { 0xfed7, G_UNICODE_NOT_PRESENT_OFFSET, 14789 }, + { 0xfed8, G_UNICODE_NOT_PRESENT_OFFSET, 14789 }, + { 0xfed9, G_UNICODE_NOT_PRESENT_OFFSET, 14792 }, + { 0xfeda, G_UNICODE_NOT_PRESENT_OFFSET, 14792 }, + { 0xfedb, G_UNICODE_NOT_PRESENT_OFFSET, 14792 }, + { 0xfedc, G_UNICODE_NOT_PRESENT_OFFSET, 14792 }, + { 0xfedd, G_UNICODE_NOT_PRESENT_OFFSET, 14795 }, + { 0xfede, G_UNICODE_NOT_PRESENT_OFFSET, 14795 }, + { 0xfedf, G_UNICODE_NOT_PRESENT_OFFSET, 14795 }, + { 0xfee0, G_UNICODE_NOT_PRESENT_OFFSET, 14795 }, + { 0xfee1, G_UNICODE_NOT_PRESENT_OFFSET, 14798 }, + { 0xfee2, G_UNICODE_NOT_PRESENT_OFFSET, 14798 }, + { 0xfee3, G_UNICODE_NOT_PRESENT_OFFSET, 14798 }, + { 0xfee4, G_UNICODE_NOT_PRESENT_OFFSET, 14798 }, + { 0xfee5, G_UNICODE_NOT_PRESENT_OFFSET, 14801 }, + { 0xfee6, G_UNICODE_NOT_PRESENT_OFFSET, 14801 }, + { 0xfee7, G_UNICODE_NOT_PRESENT_OFFSET, 14801 }, + { 0xfee8, G_UNICODE_NOT_PRESENT_OFFSET, 14801 }, + { 0xfee9, G_UNICODE_NOT_PRESENT_OFFSET, 14804 }, + { 0xfeea, G_UNICODE_NOT_PRESENT_OFFSET, 14804 }, + { 0xfeeb, G_UNICODE_NOT_PRESENT_OFFSET, 14804 }, + { 0xfeec, G_UNICODE_NOT_PRESENT_OFFSET, 14804 }, + { 0xfeed, G_UNICODE_NOT_PRESENT_OFFSET, 14807 }, + { 0xfeee, G_UNICODE_NOT_PRESENT_OFFSET, 14807 }, + { 0xfeef, G_UNICODE_NOT_PRESENT_OFFSET, 12856 }, + { 0xfef0, G_UNICODE_NOT_PRESENT_OFFSET, 12856 }, + { 0xfef1, G_UNICODE_NOT_PRESENT_OFFSET, 14810 }, + { 0xfef2, G_UNICODE_NOT_PRESENT_OFFSET, 14810 }, + { 0xfef3, G_UNICODE_NOT_PRESENT_OFFSET, 14810 }, + { 0xfef4, G_UNICODE_NOT_PRESENT_OFFSET, 14810 }, + { 0xfef5, G_UNICODE_NOT_PRESENT_OFFSET, 14813 }, + { 0xfef6, G_UNICODE_NOT_PRESENT_OFFSET, 14813 }, + { 0xfef7, G_UNICODE_NOT_PRESENT_OFFSET, 14820 }, + { 0xfef8, G_UNICODE_NOT_PRESENT_OFFSET, 14820 }, + { 0xfef9, G_UNICODE_NOT_PRESENT_OFFSET, 14827 }, + { 0xfefa, G_UNICODE_NOT_PRESENT_OFFSET, 14827 }, + { 0xfefb, G_UNICODE_NOT_PRESENT_OFFSET, 14834 }, + { 0xfefc, G_UNICODE_NOT_PRESENT_OFFSET, 14834 }, + { 0xff01, G_UNICODE_NOT_PRESENT_OFFSET, 14571 }, + { 0xff02, G_UNICODE_NOT_PRESENT_OFFSET, 14839 }, + { 0xff03, G_UNICODE_NOT_PRESENT_OFFSET, 14641 }, + { 0xff04, G_UNICODE_NOT_PRESENT_OFFSET, 14655 }, + { 0xff05, G_UNICODE_NOT_PRESENT_OFFSET, 14657 }, + { 0xff06, G_UNICODE_NOT_PRESENT_OFFSET, 14643 }, + { 0xff07, G_UNICODE_NOT_PRESENT_OFFSET, 14841 }, + { 0xff08, G_UNICODE_NOT_PRESENT_OFFSET, 5275 }, + { 0xff09, G_UNICODE_NOT_PRESENT_OFFSET, 5277 }, + { 0xff0a, G_UNICODE_NOT_PRESENT_OFFSET, 14645 }, + { 0xff0b, G_UNICODE_NOT_PRESENT_OFFSET, 5267 }, + { 0xff0c, G_UNICODE_NOT_PRESENT_OFFSET, 14559 }, + { 0xff0d, G_UNICODE_NOT_PRESENT_OFFSET, 14647 }, + { 0xff0e, G_UNICODE_NOT_PRESENT_OFFSET, 5181 }, + { 0xff0f, G_UNICODE_NOT_PRESENT_OFFSET, 14843 }, + { 0xff10, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0xff11, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0xff12, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0xff13, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0xff14, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0xff15, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0xff16, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0xff17, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0xff18, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0xff19, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0xff1a, G_UNICODE_NOT_PRESENT_OFFSET, 14569 }, + { 0xff1b, G_UNICODE_NOT_PRESENT_OFFSET, 1248 }, + { 0xff1c, G_UNICODE_NOT_PRESENT_OFFSET, 14649 }, + { 0xff1d, G_UNICODE_NOT_PRESENT_OFFSET, 5273 }, + { 0xff1e, G_UNICODE_NOT_PRESENT_OFFSET, 14651 }, + { 0xff1f, G_UNICODE_NOT_PRESENT_OFFSET, 14573 }, + { 0xff20, G_UNICODE_NOT_PRESENT_OFFSET, 14659 }, + { 0xff21, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0xff22, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0xff23, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0xff24, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0xff25, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0xff26, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0xff27, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0xff28, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0xff29, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0xff2a, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0xff2b, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0xff2c, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0xff2d, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0xff2e, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0xff2f, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0xff30, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0xff31, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0xff32, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0xff33, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0xff34, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0xff35, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0xff36, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0xff37, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0xff38, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0xff39, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0xff3a, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0xff3b, G_UNICODE_NOT_PRESENT_OFFSET, 14637 }, + { 0xff3c, G_UNICODE_NOT_PRESENT_OFFSET, 14653 }, + { 0xff3d, G_UNICODE_NOT_PRESENT_OFFSET, 14639 }, + { 0xff3e, G_UNICODE_NOT_PRESENT_OFFSET, 14845 }, + { 0xff3f, G_UNICODE_NOT_PRESENT_OFFSET, 14591 }, + { 0xff40, G_UNICODE_NOT_PRESENT_OFFSET, 5110 }, + { 0xff41, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0xff42, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0xff43, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0xff44, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0xff45, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0xff46, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0xff47, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0xff48, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0xff49, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0xff4a, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0xff4b, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0xff4c, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0xff4d, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0xff4e, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0xff4f, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0xff50, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0xff51, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0xff52, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0xff53, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0xff54, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0xff55, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0xff56, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0xff57, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0xff58, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0xff59, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0xff5a, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0xff5b, G_UNICODE_NOT_PRESENT_OFFSET, 14593 }, + { 0xff5c, G_UNICODE_NOT_PRESENT_OFFSET, 14847 }, + { 0xff5d, G_UNICODE_NOT_PRESENT_OFFSET, 14595 }, + { 0xff5e, G_UNICODE_NOT_PRESENT_OFFSET, 14849 }, + { 0xff5f, G_UNICODE_NOT_PRESENT_OFFSET, 14851 }, + { 0xff60, G_UNICODE_NOT_PRESENT_OFFSET, 14855 }, + { 0xff61, G_UNICODE_NOT_PRESENT_OFFSET, 14565 }, + { 0xff62, G_UNICODE_NOT_PRESENT_OFFSET, 14621 }, + { 0xff63, G_UNICODE_NOT_PRESENT_OFFSET, 14625 }, + { 0xff64, G_UNICODE_NOT_PRESENT_OFFSET, 14561 }, + { 0xff65, G_UNICODE_NOT_PRESENT_OFFSET, 14859 }, + { 0xff66, G_UNICODE_NOT_PRESENT_OFFSET, 8992 }, + { 0xff67, G_UNICODE_NOT_PRESENT_OFFSET, 14863 }, + { 0xff68, G_UNICODE_NOT_PRESENT_OFFSET, 14867 }, + { 0xff69, G_UNICODE_NOT_PRESENT_OFFSET, 14871 }, + { 0xff6a, G_UNICODE_NOT_PRESENT_OFFSET, 14875 }, + { 0xff6b, G_UNICODE_NOT_PRESENT_OFFSET, 14879 }, + { 0xff6c, G_UNICODE_NOT_PRESENT_OFFSET, 14883 }, + { 0xff6d, G_UNICODE_NOT_PRESENT_OFFSET, 14887 }, + { 0xff6e, G_UNICODE_NOT_PRESENT_OFFSET, 14891 }, + { 0xff6f, G_UNICODE_NOT_PRESENT_OFFSET, 14895 }, + { 0xff70, G_UNICODE_NOT_PRESENT_OFFSET, 14899 }, + { 0xff71, G_UNICODE_NOT_PRESENT_OFFSET, 8808 }, + { 0xff72, G_UNICODE_NOT_PRESENT_OFFSET, 8812 }, + { 0xff73, G_UNICODE_NOT_PRESENT_OFFSET, 8816 }, + { 0xff74, G_UNICODE_NOT_PRESENT_OFFSET, 8820 }, + { 0xff75, G_UNICODE_NOT_PRESENT_OFFSET, 8824 }, + { 0xff76, G_UNICODE_NOT_PRESENT_OFFSET, 8828 }, + { 0xff77, G_UNICODE_NOT_PRESENT_OFFSET, 8832 }, + { 0xff78, G_UNICODE_NOT_PRESENT_OFFSET, 8836 }, + { 0xff79, G_UNICODE_NOT_PRESENT_OFFSET, 8840 }, + { 0xff7a, G_UNICODE_NOT_PRESENT_OFFSET, 8844 }, + { 0xff7b, G_UNICODE_NOT_PRESENT_OFFSET, 8848 }, + { 0xff7c, G_UNICODE_NOT_PRESENT_OFFSET, 8852 }, + { 0xff7d, G_UNICODE_NOT_PRESENT_OFFSET, 8856 }, + { 0xff7e, G_UNICODE_NOT_PRESENT_OFFSET, 8860 }, + { 0xff7f, G_UNICODE_NOT_PRESENT_OFFSET, 8864 }, + { 0xff80, G_UNICODE_NOT_PRESENT_OFFSET, 8868 }, + { 0xff81, G_UNICODE_NOT_PRESENT_OFFSET, 8872 }, + { 0xff82, G_UNICODE_NOT_PRESENT_OFFSET, 8876 }, + { 0xff83, G_UNICODE_NOT_PRESENT_OFFSET, 8880 }, + { 0xff84, G_UNICODE_NOT_PRESENT_OFFSET, 8884 }, + { 0xff85, G_UNICODE_NOT_PRESENT_OFFSET, 8888 }, + { 0xff86, G_UNICODE_NOT_PRESENT_OFFSET, 8892 }, + { 0xff87, G_UNICODE_NOT_PRESENT_OFFSET, 8896 }, + { 0xff88, G_UNICODE_NOT_PRESENT_OFFSET, 8900 }, + { 0xff89, G_UNICODE_NOT_PRESENT_OFFSET, 8904 }, + { 0xff8a, G_UNICODE_NOT_PRESENT_OFFSET, 8908 }, + { 0xff8b, G_UNICODE_NOT_PRESENT_OFFSET, 8912 }, + { 0xff8c, G_UNICODE_NOT_PRESENT_OFFSET, 8916 }, + { 0xff8d, G_UNICODE_NOT_PRESENT_OFFSET, 8920 }, + { 0xff8e, G_UNICODE_NOT_PRESENT_OFFSET, 8924 }, + { 0xff8f, G_UNICODE_NOT_PRESENT_OFFSET, 8928 }, + { 0xff90, G_UNICODE_NOT_PRESENT_OFFSET, 8932 }, + { 0xff91, G_UNICODE_NOT_PRESENT_OFFSET, 8936 }, + { 0xff92, G_UNICODE_NOT_PRESENT_OFFSET, 8940 }, + { 0xff93, G_UNICODE_NOT_PRESENT_OFFSET, 8944 }, + { 0xff94, G_UNICODE_NOT_PRESENT_OFFSET, 8948 }, + { 0xff95, G_UNICODE_NOT_PRESENT_OFFSET, 8952 }, + { 0xff96, G_UNICODE_NOT_PRESENT_OFFSET, 8956 }, + { 0xff97, G_UNICODE_NOT_PRESENT_OFFSET, 8960 }, + { 0xff98, G_UNICODE_NOT_PRESENT_OFFSET, 8964 }, + { 0xff99, G_UNICODE_NOT_PRESENT_OFFSET, 8968 }, + { 0xff9a, G_UNICODE_NOT_PRESENT_OFFSET, 8972 }, + { 0xff9b, G_UNICODE_NOT_PRESENT_OFFSET, 8976 }, + { 0xff9c, G_UNICODE_NOT_PRESENT_OFFSET, 8980 }, + { 0xff9d, G_UNICODE_NOT_PRESENT_OFFSET, 14903 }, + { 0xff9e, G_UNICODE_NOT_PRESENT_OFFSET, 14907 }, + { 0xff9f, G_UNICODE_NOT_PRESENT_OFFSET, 14911 }, + { 0xffa0, G_UNICODE_NOT_PRESENT_OFFSET, 7683 }, + { 0xffa1, G_UNICODE_NOT_PRESENT_OFFSET, 7479 }, + { 0xffa2, G_UNICODE_NOT_PRESENT_OFFSET, 7483 }, + { 0xffa3, G_UNICODE_NOT_PRESENT_OFFSET, 7487 }, + { 0xffa4, G_UNICODE_NOT_PRESENT_OFFSET, 7491 }, + { 0xffa5, G_UNICODE_NOT_PRESENT_OFFSET, 7495 }, + { 0xffa6, G_UNICODE_NOT_PRESENT_OFFSET, 7499 }, + { 0xffa7, G_UNICODE_NOT_PRESENT_OFFSET, 7503 }, + { 0xffa8, G_UNICODE_NOT_PRESENT_OFFSET, 7507 }, + { 0xffa9, G_UNICODE_NOT_PRESENT_OFFSET, 7511 }, + { 0xffaa, G_UNICODE_NOT_PRESENT_OFFSET, 7515 }, + { 0xffab, G_UNICODE_NOT_PRESENT_OFFSET, 7519 }, + { 0xffac, G_UNICODE_NOT_PRESENT_OFFSET, 7523 }, + { 0xffad, G_UNICODE_NOT_PRESENT_OFFSET, 7527 }, + { 0xffae, G_UNICODE_NOT_PRESENT_OFFSET, 7531 }, + { 0xffaf, G_UNICODE_NOT_PRESENT_OFFSET, 7535 }, + { 0xffb0, G_UNICODE_NOT_PRESENT_OFFSET, 7539 }, + { 0xffb1, G_UNICODE_NOT_PRESENT_OFFSET, 7543 }, + { 0xffb2, G_UNICODE_NOT_PRESENT_OFFSET, 7547 }, + { 0xffb3, G_UNICODE_NOT_PRESENT_OFFSET, 7551 }, + { 0xffb4, G_UNICODE_NOT_PRESENT_OFFSET, 7555 }, + { 0xffb5, G_UNICODE_NOT_PRESENT_OFFSET, 7559 }, + { 0xffb6, G_UNICODE_NOT_PRESENT_OFFSET, 7563 }, + { 0xffb7, G_UNICODE_NOT_PRESENT_OFFSET, 7567 }, + { 0xffb8, G_UNICODE_NOT_PRESENT_OFFSET, 7571 }, + { 0xffb9, G_UNICODE_NOT_PRESENT_OFFSET, 7575 }, + { 0xffba, G_UNICODE_NOT_PRESENT_OFFSET, 7579 }, + { 0xffbb, G_UNICODE_NOT_PRESENT_OFFSET, 7583 }, + { 0xffbc, G_UNICODE_NOT_PRESENT_OFFSET, 7587 }, + { 0xffbd, G_UNICODE_NOT_PRESENT_OFFSET, 7591 }, + { 0xffbe, G_UNICODE_NOT_PRESENT_OFFSET, 7595 }, + { 0xffc2, G_UNICODE_NOT_PRESENT_OFFSET, 7599 }, + { 0xffc3, G_UNICODE_NOT_PRESENT_OFFSET, 7603 }, + { 0xffc4, G_UNICODE_NOT_PRESENT_OFFSET, 7607 }, + { 0xffc5, G_UNICODE_NOT_PRESENT_OFFSET, 7611 }, + { 0xffc6, G_UNICODE_NOT_PRESENT_OFFSET, 7615 }, + { 0xffc7, G_UNICODE_NOT_PRESENT_OFFSET, 7619 }, + { 0xffca, G_UNICODE_NOT_PRESENT_OFFSET, 7623 }, + { 0xffcb, G_UNICODE_NOT_PRESENT_OFFSET, 7627 }, + { 0xffcc, G_UNICODE_NOT_PRESENT_OFFSET, 7631 }, + { 0xffcd, G_UNICODE_NOT_PRESENT_OFFSET, 7635 }, + { 0xffce, G_UNICODE_NOT_PRESENT_OFFSET, 7639 }, + { 0xffcf, G_UNICODE_NOT_PRESENT_OFFSET, 7643 }, + { 0xffd2, G_UNICODE_NOT_PRESENT_OFFSET, 7647 }, + { 0xffd3, G_UNICODE_NOT_PRESENT_OFFSET, 7651 }, + { 0xffd4, G_UNICODE_NOT_PRESENT_OFFSET, 7655 }, + { 0xffd5, G_UNICODE_NOT_PRESENT_OFFSET, 7659 }, + { 0xffd6, G_UNICODE_NOT_PRESENT_OFFSET, 7663 }, + { 0xffd7, G_UNICODE_NOT_PRESENT_OFFSET, 7667 }, + { 0xffda, G_UNICODE_NOT_PRESENT_OFFSET, 7671 }, + { 0xffdb, G_UNICODE_NOT_PRESENT_OFFSET, 7675 }, + { 0xffdc, G_UNICODE_NOT_PRESENT_OFFSET, 7679 }, + { 0xffe0, G_UNICODE_NOT_PRESENT_OFFSET, 14915 }, + { 0xffe1, G_UNICODE_NOT_PRESENT_OFFSET, 14918 }, + { 0xffe2, G_UNICODE_NOT_PRESENT_OFFSET, 14921 }, + { 0xffe3, G_UNICODE_NOT_PRESENT_OFFSET, 8 }, + { 0xffe4, G_UNICODE_NOT_PRESENT_OFFSET, 14924 }, + { 0xffe5, G_UNICODE_NOT_PRESENT_OFFSET, 14927 }, + { 0xffe6, G_UNICODE_NOT_PRESENT_OFFSET, 14930 }, + { 0xffe8, G_UNICODE_NOT_PRESENT_OFFSET, 14934 }, + { 0xffe9, G_UNICODE_NOT_PRESENT_OFFSET, 14938 }, + { 0xffea, G_UNICODE_NOT_PRESENT_OFFSET, 14942 }, + { 0xffeb, G_UNICODE_NOT_PRESENT_OFFSET, 14946 }, + { 0xffec, G_UNICODE_NOT_PRESENT_OFFSET, 14950 }, + { 0xffed, G_UNICODE_NOT_PRESENT_OFFSET, 14954 }, + { 0xffee, G_UNICODE_NOT_PRESENT_OFFSET, 14958 }, + { 0x1109a, 14962, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1109c, 14971, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x110ab, 14980, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d15e, 14989, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d15f, 14998, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d160, 15007, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d161, 15020, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d162, 15033, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d163, 15046, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d164, 15059, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d1bb, 15072, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d1bc, 15081, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d1bd, 15090, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d1be, 15103, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d1bf, 15116, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d1c0, 15129, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x1d400, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d401, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d402, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d403, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d404, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d405, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d406, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d407, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d408, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d409, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d40a, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d40b, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d40c, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d40d, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d40e, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d40f, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d410, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d411, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d412, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d413, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d414, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d415, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d416, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d417, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d418, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d419, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d41a, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d41b, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d41c, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d41d, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d41e, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d41f, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d420, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d421, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d422, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d423, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d424, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d425, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d426, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d427, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d428, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d429, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d42a, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d42b, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d42c, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d42d, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d42e, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d42f, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d430, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d431, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d432, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d433, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d434, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d435, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d436, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d437, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d438, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d439, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d43a, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d43b, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d43c, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d43d, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d43e, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d43f, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d440, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d441, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d442, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d443, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d444, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d445, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d446, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d447, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d448, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d449, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d44a, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d44b, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d44c, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d44d, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d44e, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d44f, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d450, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d451, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d452, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d453, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d454, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d456, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d457, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d458, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d459, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d45a, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d45b, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d45c, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d45d, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d45e, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d45f, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d460, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d461, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d462, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d463, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d464, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d465, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d466, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d467, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d468, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d469, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d46a, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d46b, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d46c, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d46d, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d46e, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d46f, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d470, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d471, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d472, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d473, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d474, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d475, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d476, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d477, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d478, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d479, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d47a, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d47b, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d47c, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d47d, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d47e, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d47f, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d480, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d481, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d482, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d483, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d484, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d485, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d486, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d487, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d488, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d489, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d48a, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d48b, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d48c, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d48d, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d48e, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d48f, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d490, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d491, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d492, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d493, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d494, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d495, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d496, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d497, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d498, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d499, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d49a, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d49b, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d49c, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d49e, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d49f, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d4a2, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d4a5, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d4a6, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d4a9, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d4aa, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d4ab, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d4ac, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d4ae, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d4af, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d4b0, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d4b1, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d4b2, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d4b3, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d4b4, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d4b5, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d4b6, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d4b7, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d4b8, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d4b9, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d4bb, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d4bd, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d4be, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d4bf, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d4c0, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d4c1, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d4c2, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d4c3, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d4c5, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d4c6, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d4c7, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d4c8, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d4c9, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d4ca, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d4cb, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d4cc, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d4cd, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d4ce, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d4cf, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d4d0, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d4d1, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d4d2, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d4d3, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d4d4, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d4d5, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d4d6, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d4d7, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d4d8, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d4d9, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d4da, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d4db, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d4dc, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d4dd, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d4de, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d4df, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d4e0, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d4e1, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d4e2, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d4e3, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d4e4, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d4e5, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d4e6, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d4e7, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d4e8, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d4e9, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d4ea, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d4eb, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d4ec, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d4ed, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d4ee, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d4ef, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d4f0, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d4f1, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d4f2, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d4f3, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d4f4, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d4f5, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d4f6, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d4f7, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d4f8, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d4f9, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d4fa, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d4fb, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d4fc, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d4fd, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d4fe, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d4ff, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d500, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d501, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d502, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d503, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d504, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d505, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d507, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d508, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d509, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d50a, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d50d, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d50e, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d50f, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d510, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d511, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d512, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d513, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d514, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d516, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d517, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d518, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d519, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d51a, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d51b, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d51c, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d51e, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d51f, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d520, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d521, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d522, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d523, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d524, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d525, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d526, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d527, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d528, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d529, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d52a, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d52b, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d52c, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d52d, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d52e, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d52f, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d530, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d531, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d532, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d533, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d534, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d535, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d536, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d537, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d538, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d539, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d53b, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d53c, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d53d, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d53e, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d540, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d541, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d542, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d543, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d544, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d546, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d54a, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d54b, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d54c, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d54d, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d54e, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d54f, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d550, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d552, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d553, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d554, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d555, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d556, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d557, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d558, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d559, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d55a, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d55b, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d55c, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d55d, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d55e, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d55f, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d560, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d561, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d562, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d563, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d564, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d565, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d566, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d567, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d568, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d569, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d56a, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d56b, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d56c, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d56d, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d56e, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d56f, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d570, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d571, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d572, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d573, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d574, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d575, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d576, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d577, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d578, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d579, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d57a, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d57b, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d57c, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d57d, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d57e, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d57f, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d580, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d581, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d582, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d583, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d584, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d585, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d586, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d587, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d588, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d589, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d58a, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d58b, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d58c, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d58d, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d58e, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d58f, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d590, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d591, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d592, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d593, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d594, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d595, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d596, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d597, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d598, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d599, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d59a, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d59b, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d59c, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d59d, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d59e, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d59f, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d5a0, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d5a1, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d5a2, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d5a3, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d5a4, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d5a5, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d5a6, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d5a7, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d5a8, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d5a9, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d5aa, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d5ab, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d5ac, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d5ad, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d5ae, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d5af, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d5b0, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d5b1, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d5b2, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d5b3, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d5b4, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d5b5, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d5b6, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d5b7, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d5b8, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d5b9, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d5ba, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d5bb, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d5bc, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d5bd, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d5be, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d5bf, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d5c0, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d5c1, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d5c2, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d5c3, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d5c4, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d5c5, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d5c6, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d5c7, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d5c8, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d5c9, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d5ca, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d5cb, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d5cc, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d5cd, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d5ce, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d5cf, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d5d0, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d5d1, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d5d2, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d5d3, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d5d4, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d5d5, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d5d6, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d5d7, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d5d8, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d5d9, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d5da, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d5db, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d5dc, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d5dd, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d5de, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d5df, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d5e0, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d5e1, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d5e2, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d5e3, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d5e4, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d5e5, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d5e6, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d5e7, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d5e8, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d5e9, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d5ea, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d5eb, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d5ec, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d5ed, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d5ee, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d5ef, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d5f0, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d5f1, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d5f2, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d5f3, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d5f4, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d5f5, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d5f6, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d5f7, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d5f8, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d5f9, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d5fa, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d5fb, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d5fc, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d5fd, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d5fe, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d5ff, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d600, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d601, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d602, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d603, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d604, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d605, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d606, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d607, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d608, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d609, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d60a, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d60b, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d60c, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d60d, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d60e, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d60f, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d610, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d611, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d612, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d613, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d614, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d615, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d616, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d617, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d618, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d619, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d61a, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d61b, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d61c, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d61d, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d61e, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d61f, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d620, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d621, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d622, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d623, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d624, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d625, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d626, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d627, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d628, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d629, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d62a, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d62b, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d62c, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d62d, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d62e, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d62f, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d630, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d631, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d632, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d633, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d634, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d635, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d636, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d637, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d638, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d639, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d63a, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d63b, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d63c, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d63d, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d63e, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d63f, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d640, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d641, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d642, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d643, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d644, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d645, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d646, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d647, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d648, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d649, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d64a, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d64b, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d64c, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d64d, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d64e, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d64f, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d650, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d651, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d652, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d653, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d654, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d655, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d656, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d657, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d658, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d659, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d65a, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d65b, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d65c, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d65d, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d65e, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d65f, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d660, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d661, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d662, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d663, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d664, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d665, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d666, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d667, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d668, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d669, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d66a, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d66b, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d66c, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d66d, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d66e, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d66f, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d670, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1d671, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1d672, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1d673, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1d674, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1d675, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1d676, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1d677, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1d678, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1d679, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1d67a, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1d67b, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1d67c, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1d67d, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1d67e, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1d67f, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1d680, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1d681, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1d682, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1d683, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1d684, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1d685, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1d686, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1d687, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1d688, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1d689, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1d68a, G_UNICODE_NOT_PRESENT_OFFSET, 6 }, + { 0x1d68b, G_UNICODE_NOT_PRESENT_OFFSET, 2364 }, + { 0x1d68c, G_UNICODE_NOT_PRESENT_OFFSET, 2435 }, + { 0x1d68d, G_UNICODE_NOT_PRESENT_OFFSET, 2366 }, + { 0x1d68e, G_UNICODE_NOT_PRESENT_OFFSET, 2368 }, + { 0x1d68f, G_UNICODE_NOT_PRESENT_OFFSET, 2443 }, + { 0x1d690, G_UNICODE_NOT_PRESENT_OFFSET, 2379 }, + { 0x1d691, G_UNICODE_NOT_PRESENT_OFFSET, 1171 }, + { 0x1d692, G_UNICODE_NOT_PRESENT_OFFSET, 2427 }, + { 0x1d693, G_UNICODE_NOT_PRESENT_OFFSET, 1176 }, + { 0x1d694, G_UNICODE_NOT_PRESENT_OFFSET, 2381 }, + { 0x1d695, G_UNICODE_NOT_PRESENT_OFFSET, 1220 }, + { 0x1d696, G_UNICODE_NOT_PRESENT_OFFSET, 2383 }, + { 0x1d697, G_UNICODE_NOT_PRESENT_OFFSET, 5279 }, + { 0x1d698, G_UNICODE_NOT_PRESENT_OFFSET, 29 }, + { 0x1d699, G_UNICODE_NOT_PRESENT_OFFSET, 2399 }, + { 0x1d69a, G_UNICODE_NOT_PRESENT_OFFSET, 6137 }, + { 0x1d69b, G_UNICODE_NOT_PRESENT_OFFSET, 1178 }, + { 0x1d69c, G_UNICODE_NOT_PRESENT_OFFSET, 711 }, + { 0x1d69d, G_UNICODE_NOT_PRESENT_OFFSET, 2401 }, + { 0x1d69e, G_UNICODE_NOT_PRESENT_OFFSET, 2403 }, + { 0x1d69f, G_UNICODE_NOT_PRESENT_OFFSET, 2412 }, + { 0x1d6a0, G_UNICODE_NOT_PRESENT_OFFSET, 1189 }, + { 0x1d6a1, G_UNICODE_NOT_PRESENT_OFFSET, 1222 }, + { 0x1d6a2, G_UNICODE_NOT_PRESENT_OFFSET, 1191 }, + { 0x1d6a3, G_UNICODE_NOT_PRESENT_OFFSET, 2526 }, + { 0x1d6a4, G_UNICODE_NOT_PRESENT_OFFSET, 15142 }, + { 0x1d6a5, G_UNICODE_NOT_PRESENT_OFFSET, 15145 }, + { 0x1d6a8, G_UNICODE_NOT_PRESENT_OFFSET, 15148 }, + { 0x1d6a9, G_UNICODE_NOT_PRESENT_OFFSET, 15151 }, + { 0x1d6aa, G_UNICODE_NOT_PRESENT_OFFSET, 5354 }, + { 0x1d6ab, G_UNICODE_NOT_PRESENT_OFFSET, 15154 }, + { 0x1d6ac, G_UNICODE_NOT_PRESENT_OFFSET, 15157 }, + { 0x1d6ad, G_UNICODE_NOT_PRESENT_OFFSET, 15160 }, + { 0x1d6ae, G_UNICODE_NOT_PRESENT_OFFSET, 15163 }, + { 0x1d6af, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d6b0, G_UNICODE_NOT_PRESENT_OFFSET, 15166 }, + { 0x1d6b1, G_UNICODE_NOT_PRESENT_OFFSET, 15169 }, + { 0x1d6b2, G_UNICODE_NOT_PRESENT_OFFSET, 15172 }, + { 0x1d6b3, G_UNICODE_NOT_PRESENT_OFFSET, 15175 }, + { 0x1d6b4, G_UNICODE_NOT_PRESENT_OFFSET, 15178 }, + { 0x1d6b5, G_UNICODE_NOT_PRESENT_OFFSET, 15181 }, + { 0x1d6b6, G_UNICODE_NOT_PRESENT_OFFSET, 15184 }, + { 0x1d6b7, G_UNICODE_NOT_PRESENT_OFFSET, 5357 }, + { 0x1d6b8, G_UNICODE_NOT_PRESENT_OFFSET, 15187 }, + { 0x1d6b9, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d6ba, G_UNICODE_NOT_PRESENT_OFFSET, 1408 }, + { 0x1d6bb, G_UNICODE_NOT_PRESENT_OFFSET, 15190 }, + { 0x1d6bc, G_UNICODE_NOT_PRESENT_OFFSET, 1374 }, + { 0x1d6bd, G_UNICODE_NOT_PRESENT_OFFSET, 15193 }, + { 0x1d6be, G_UNICODE_NOT_PRESENT_OFFSET, 15196 }, + { 0x1d6bf, G_UNICODE_NOT_PRESENT_OFFSET, 15199 }, + { 0x1d6c0, G_UNICODE_NOT_PRESENT_OFFSET, 5333 }, + { 0x1d6c1, G_UNICODE_NOT_PRESENT_OFFSET, 15202 }, + { 0x1d6c2, G_UNICODE_NOT_PRESENT_OFFSET, 15206 }, + { 0x1d6c3, G_UNICODE_NOT_PRESENT_OFFSET, 1368 }, + { 0x1d6c4, G_UNICODE_NOT_PRESENT_OFFSET, 2418 }, + { 0x1d6c5, G_UNICODE_NOT_PRESENT_OFFSET, 2421 }, + { 0x1d6c6, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d6c7, G_UNICODE_NOT_PRESENT_OFFSET, 15209 }, + { 0x1d6c8, G_UNICODE_NOT_PRESENT_OFFSET, 15212 }, + { 0x1d6c9, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d6ca, G_UNICODE_NOT_PRESENT_OFFSET, 4860 }, + { 0x1d6cb, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d6cc, G_UNICODE_NOT_PRESENT_OFFSET, 15215 }, + { 0x1d6cd, G_UNICODE_NOT_PRESENT_OFFSET, 20 }, + { 0x1d6ce, G_UNICODE_NOT_PRESENT_OFFSET, 15218 }, + { 0x1d6cf, G_UNICODE_NOT_PRESENT_OFFSET, 15221 }, + { 0x1d6d0, G_UNICODE_NOT_PRESENT_OFFSET, 15224 }, + { 0x1d6d1, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d6d2, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d6d3, G_UNICODE_NOT_PRESENT_OFFSET, 1399 }, + { 0x1d6d4, G_UNICODE_NOT_PRESENT_OFFSET, 15227 }, + { 0x1d6d5, G_UNICODE_NOT_PRESENT_OFFSET, 15230 }, + { 0x1d6d6, G_UNICODE_NOT_PRESENT_OFFSET, 15233 }, + { 0x1d6d7, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d6d8, G_UNICODE_NOT_PRESENT_OFFSET, 2424 }, + { 0x1d6d9, G_UNICODE_NOT_PRESENT_OFFSET, 15236 }, + { 0x1d6da, G_UNICODE_NOT_PRESENT_OFFSET, 15239 }, + { 0x1d6db, G_UNICODE_NOT_PRESENT_OFFSET, 15242 }, + { 0x1d6dc, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d6dd, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d6de, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d6df, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d6e0, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d6e1, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d6e2, G_UNICODE_NOT_PRESENT_OFFSET, 15148 }, + { 0x1d6e3, G_UNICODE_NOT_PRESENT_OFFSET, 15151 }, + { 0x1d6e4, G_UNICODE_NOT_PRESENT_OFFSET, 5354 }, + { 0x1d6e5, G_UNICODE_NOT_PRESENT_OFFSET, 15154 }, + { 0x1d6e6, G_UNICODE_NOT_PRESENT_OFFSET, 15157 }, + { 0x1d6e7, G_UNICODE_NOT_PRESENT_OFFSET, 15160 }, + { 0x1d6e8, G_UNICODE_NOT_PRESENT_OFFSET, 15163 }, + { 0x1d6e9, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d6ea, G_UNICODE_NOT_PRESENT_OFFSET, 15166 }, + { 0x1d6eb, G_UNICODE_NOT_PRESENT_OFFSET, 15169 }, + { 0x1d6ec, G_UNICODE_NOT_PRESENT_OFFSET, 15172 }, + { 0x1d6ed, G_UNICODE_NOT_PRESENT_OFFSET, 15175 }, + { 0x1d6ee, G_UNICODE_NOT_PRESENT_OFFSET, 15178 }, + { 0x1d6ef, G_UNICODE_NOT_PRESENT_OFFSET, 15181 }, + { 0x1d6f0, G_UNICODE_NOT_PRESENT_OFFSET, 15184 }, + { 0x1d6f1, G_UNICODE_NOT_PRESENT_OFFSET, 5357 }, + { 0x1d6f2, G_UNICODE_NOT_PRESENT_OFFSET, 15187 }, + { 0x1d6f3, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d6f4, G_UNICODE_NOT_PRESENT_OFFSET, 1408 }, + { 0x1d6f5, G_UNICODE_NOT_PRESENT_OFFSET, 15190 }, + { 0x1d6f6, G_UNICODE_NOT_PRESENT_OFFSET, 1374 }, + { 0x1d6f7, G_UNICODE_NOT_PRESENT_OFFSET, 15193 }, + { 0x1d6f8, G_UNICODE_NOT_PRESENT_OFFSET, 15196 }, + { 0x1d6f9, G_UNICODE_NOT_PRESENT_OFFSET, 15199 }, + { 0x1d6fa, G_UNICODE_NOT_PRESENT_OFFSET, 5333 }, + { 0x1d6fb, G_UNICODE_NOT_PRESENT_OFFSET, 15202 }, + { 0x1d6fc, G_UNICODE_NOT_PRESENT_OFFSET, 15206 }, + { 0x1d6fd, G_UNICODE_NOT_PRESENT_OFFSET, 1368 }, + { 0x1d6fe, G_UNICODE_NOT_PRESENT_OFFSET, 2418 }, + { 0x1d6ff, G_UNICODE_NOT_PRESENT_OFFSET, 2421 }, + { 0x1d700, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d701, G_UNICODE_NOT_PRESENT_OFFSET, 15209 }, + { 0x1d702, G_UNICODE_NOT_PRESENT_OFFSET, 15212 }, + { 0x1d703, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d704, G_UNICODE_NOT_PRESENT_OFFSET, 4860 }, + { 0x1d705, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d706, G_UNICODE_NOT_PRESENT_OFFSET, 15215 }, + { 0x1d707, G_UNICODE_NOT_PRESENT_OFFSET, 20 }, + { 0x1d708, G_UNICODE_NOT_PRESENT_OFFSET, 15218 }, + { 0x1d709, G_UNICODE_NOT_PRESENT_OFFSET, 15221 }, + { 0x1d70a, G_UNICODE_NOT_PRESENT_OFFSET, 15224 }, + { 0x1d70b, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d70c, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d70d, G_UNICODE_NOT_PRESENT_OFFSET, 1399 }, + { 0x1d70e, G_UNICODE_NOT_PRESENT_OFFSET, 15227 }, + { 0x1d70f, G_UNICODE_NOT_PRESENT_OFFSET, 15230 }, + { 0x1d710, G_UNICODE_NOT_PRESENT_OFFSET, 15233 }, + { 0x1d711, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d712, G_UNICODE_NOT_PRESENT_OFFSET, 2424 }, + { 0x1d713, G_UNICODE_NOT_PRESENT_OFFSET, 15236 }, + { 0x1d714, G_UNICODE_NOT_PRESENT_OFFSET, 15239 }, + { 0x1d715, G_UNICODE_NOT_PRESENT_OFFSET, 15242 }, + { 0x1d716, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d717, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d718, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d719, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d71a, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d71b, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d71c, G_UNICODE_NOT_PRESENT_OFFSET, 15148 }, + { 0x1d71d, G_UNICODE_NOT_PRESENT_OFFSET, 15151 }, + { 0x1d71e, G_UNICODE_NOT_PRESENT_OFFSET, 5354 }, + { 0x1d71f, G_UNICODE_NOT_PRESENT_OFFSET, 15154 }, + { 0x1d720, G_UNICODE_NOT_PRESENT_OFFSET, 15157 }, + { 0x1d721, G_UNICODE_NOT_PRESENT_OFFSET, 15160 }, + { 0x1d722, G_UNICODE_NOT_PRESENT_OFFSET, 15163 }, + { 0x1d723, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d724, G_UNICODE_NOT_PRESENT_OFFSET, 15166 }, + { 0x1d725, G_UNICODE_NOT_PRESENT_OFFSET, 15169 }, + { 0x1d726, G_UNICODE_NOT_PRESENT_OFFSET, 15172 }, + { 0x1d727, G_UNICODE_NOT_PRESENT_OFFSET, 15175 }, + { 0x1d728, G_UNICODE_NOT_PRESENT_OFFSET, 15178 }, + { 0x1d729, G_UNICODE_NOT_PRESENT_OFFSET, 15181 }, + { 0x1d72a, G_UNICODE_NOT_PRESENT_OFFSET, 15184 }, + { 0x1d72b, G_UNICODE_NOT_PRESENT_OFFSET, 5357 }, + { 0x1d72c, G_UNICODE_NOT_PRESENT_OFFSET, 15187 }, + { 0x1d72d, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d72e, G_UNICODE_NOT_PRESENT_OFFSET, 1408 }, + { 0x1d72f, G_UNICODE_NOT_PRESENT_OFFSET, 15190 }, + { 0x1d730, G_UNICODE_NOT_PRESENT_OFFSET, 1374 }, + { 0x1d731, G_UNICODE_NOT_PRESENT_OFFSET, 15193 }, + { 0x1d732, G_UNICODE_NOT_PRESENT_OFFSET, 15196 }, + { 0x1d733, G_UNICODE_NOT_PRESENT_OFFSET, 15199 }, + { 0x1d734, G_UNICODE_NOT_PRESENT_OFFSET, 5333 }, + { 0x1d735, G_UNICODE_NOT_PRESENT_OFFSET, 15202 }, + { 0x1d736, G_UNICODE_NOT_PRESENT_OFFSET, 15206 }, + { 0x1d737, G_UNICODE_NOT_PRESENT_OFFSET, 1368 }, + { 0x1d738, G_UNICODE_NOT_PRESENT_OFFSET, 2418 }, + { 0x1d739, G_UNICODE_NOT_PRESENT_OFFSET, 2421 }, + { 0x1d73a, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d73b, G_UNICODE_NOT_PRESENT_OFFSET, 15209 }, + { 0x1d73c, G_UNICODE_NOT_PRESENT_OFFSET, 15212 }, + { 0x1d73d, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d73e, G_UNICODE_NOT_PRESENT_OFFSET, 4860 }, + { 0x1d73f, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d740, G_UNICODE_NOT_PRESENT_OFFSET, 15215 }, + { 0x1d741, G_UNICODE_NOT_PRESENT_OFFSET, 20 }, + { 0x1d742, G_UNICODE_NOT_PRESENT_OFFSET, 15218 }, + { 0x1d743, G_UNICODE_NOT_PRESENT_OFFSET, 15221 }, + { 0x1d744, G_UNICODE_NOT_PRESENT_OFFSET, 15224 }, + { 0x1d745, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d746, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d747, G_UNICODE_NOT_PRESENT_OFFSET, 1399 }, + { 0x1d748, G_UNICODE_NOT_PRESENT_OFFSET, 15227 }, + { 0x1d749, G_UNICODE_NOT_PRESENT_OFFSET, 15230 }, + { 0x1d74a, G_UNICODE_NOT_PRESENT_OFFSET, 15233 }, + { 0x1d74b, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d74c, G_UNICODE_NOT_PRESENT_OFFSET, 2424 }, + { 0x1d74d, G_UNICODE_NOT_PRESENT_OFFSET, 15236 }, + { 0x1d74e, G_UNICODE_NOT_PRESENT_OFFSET, 15239 }, + { 0x1d74f, G_UNICODE_NOT_PRESENT_OFFSET, 15242 }, + { 0x1d750, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d751, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d752, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d753, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d754, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d755, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d756, G_UNICODE_NOT_PRESENT_OFFSET, 15148 }, + { 0x1d757, G_UNICODE_NOT_PRESENT_OFFSET, 15151 }, + { 0x1d758, G_UNICODE_NOT_PRESENT_OFFSET, 5354 }, + { 0x1d759, G_UNICODE_NOT_PRESENT_OFFSET, 15154 }, + { 0x1d75a, G_UNICODE_NOT_PRESENT_OFFSET, 15157 }, + { 0x1d75b, G_UNICODE_NOT_PRESENT_OFFSET, 15160 }, + { 0x1d75c, G_UNICODE_NOT_PRESENT_OFFSET, 15163 }, + { 0x1d75d, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d75e, G_UNICODE_NOT_PRESENT_OFFSET, 15166 }, + { 0x1d75f, G_UNICODE_NOT_PRESENT_OFFSET, 15169 }, + { 0x1d760, G_UNICODE_NOT_PRESENT_OFFSET, 15172 }, + { 0x1d761, G_UNICODE_NOT_PRESENT_OFFSET, 15175 }, + { 0x1d762, G_UNICODE_NOT_PRESENT_OFFSET, 15178 }, + { 0x1d763, G_UNICODE_NOT_PRESENT_OFFSET, 15181 }, + { 0x1d764, G_UNICODE_NOT_PRESENT_OFFSET, 15184 }, + { 0x1d765, G_UNICODE_NOT_PRESENT_OFFSET, 5357 }, + { 0x1d766, G_UNICODE_NOT_PRESENT_OFFSET, 15187 }, + { 0x1d767, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d768, G_UNICODE_NOT_PRESENT_OFFSET, 1408 }, + { 0x1d769, G_UNICODE_NOT_PRESENT_OFFSET, 15190 }, + { 0x1d76a, G_UNICODE_NOT_PRESENT_OFFSET, 1374 }, + { 0x1d76b, G_UNICODE_NOT_PRESENT_OFFSET, 15193 }, + { 0x1d76c, G_UNICODE_NOT_PRESENT_OFFSET, 15196 }, + { 0x1d76d, G_UNICODE_NOT_PRESENT_OFFSET, 15199 }, + { 0x1d76e, G_UNICODE_NOT_PRESENT_OFFSET, 5333 }, + { 0x1d76f, G_UNICODE_NOT_PRESENT_OFFSET, 15202 }, + { 0x1d770, G_UNICODE_NOT_PRESENT_OFFSET, 15206 }, + { 0x1d771, G_UNICODE_NOT_PRESENT_OFFSET, 1368 }, + { 0x1d772, G_UNICODE_NOT_PRESENT_OFFSET, 2418 }, + { 0x1d773, G_UNICODE_NOT_PRESENT_OFFSET, 2421 }, + { 0x1d774, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d775, G_UNICODE_NOT_PRESENT_OFFSET, 15209 }, + { 0x1d776, G_UNICODE_NOT_PRESENT_OFFSET, 15212 }, + { 0x1d777, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d778, G_UNICODE_NOT_PRESENT_OFFSET, 4860 }, + { 0x1d779, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d77a, G_UNICODE_NOT_PRESENT_OFFSET, 15215 }, + { 0x1d77b, G_UNICODE_NOT_PRESENT_OFFSET, 20 }, + { 0x1d77c, G_UNICODE_NOT_PRESENT_OFFSET, 15218 }, + { 0x1d77d, G_UNICODE_NOT_PRESENT_OFFSET, 15221 }, + { 0x1d77e, G_UNICODE_NOT_PRESENT_OFFSET, 15224 }, + { 0x1d77f, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d780, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d781, G_UNICODE_NOT_PRESENT_OFFSET, 1399 }, + { 0x1d782, G_UNICODE_NOT_PRESENT_OFFSET, 15227 }, + { 0x1d783, G_UNICODE_NOT_PRESENT_OFFSET, 15230 }, + { 0x1d784, G_UNICODE_NOT_PRESENT_OFFSET, 15233 }, + { 0x1d785, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d786, G_UNICODE_NOT_PRESENT_OFFSET, 2424 }, + { 0x1d787, G_UNICODE_NOT_PRESENT_OFFSET, 15236 }, + { 0x1d788, G_UNICODE_NOT_PRESENT_OFFSET, 15239 }, + { 0x1d789, G_UNICODE_NOT_PRESENT_OFFSET, 15242 }, + { 0x1d78a, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d78b, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d78c, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d78d, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d78e, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d78f, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d790, G_UNICODE_NOT_PRESENT_OFFSET, 15148 }, + { 0x1d791, G_UNICODE_NOT_PRESENT_OFFSET, 15151 }, + { 0x1d792, G_UNICODE_NOT_PRESENT_OFFSET, 5354 }, + { 0x1d793, G_UNICODE_NOT_PRESENT_OFFSET, 15154 }, + { 0x1d794, G_UNICODE_NOT_PRESENT_OFFSET, 15157 }, + { 0x1d795, G_UNICODE_NOT_PRESENT_OFFSET, 15160 }, + { 0x1d796, G_UNICODE_NOT_PRESENT_OFFSET, 15163 }, + { 0x1d797, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d798, G_UNICODE_NOT_PRESENT_OFFSET, 15166 }, + { 0x1d799, G_UNICODE_NOT_PRESENT_OFFSET, 15169 }, + { 0x1d79a, G_UNICODE_NOT_PRESENT_OFFSET, 15172 }, + { 0x1d79b, G_UNICODE_NOT_PRESENT_OFFSET, 15175 }, + { 0x1d79c, G_UNICODE_NOT_PRESENT_OFFSET, 15178 }, + { 0x1d79d, G_UNICODE_NOT_PRESENT_OFFSET, 15181 }, + { 0x1d79e, G_UNICODE_NOT_PRESENT_OFFSET, 15184 }, + { 0x1d79f, G_UNICODE_NOT_PRESENT_OFFSET, 5357 }, + { 0x1d7a0, G_UNICODE_NOT_PRESENT_OFFSET, 15187 }, + { 0x1d7a1, G_UNICODE_NOT_PRESENT_OFFSET, 1402 }, + { 0x1d7a2, G_UNICODE_NOT_PRESENT_OFFSET, 1408 }, + { 0x1d7a3, G_UNICODE_NOT_PRESENT_OFFSET, 15190 }, + { 0x1d7a4, G_UNICODE_NOT_PRESENT_OFFSET, 1374 }, + { 0x1d7a5, G_UNICODE_NOT_PRESENT_OFFSET, 15193 }, + { 0x1d7a6, G_UNICODE_NOT_PRESENT_OFFSET, 15196 }, + { 0x1d7a7, G_UNICODE_NOT_PRESENT_OFFSET, 15199 }, + { 0x1d7a8, G_UNICODE_NOT_PRESENT_OFFSET, 5333 }, + { 0x1d7a9, G_UNICODE_NOT_PRESENT_OFFSET, 15202 }, + { 0x1d7aa, G_UNICODE_NOT_PRESENT_OFFSET, 15206 }, + { 0x1d7ab, G_UNICODE_NOT_PRESENT_OFFSET, 1368 }, + { 0x1d7ac, G_UNICODE_NOT_PRESENT_OFFSET, 2418 }, + { 0x1d7ad, G_UNICODE_NOT_PRESENT_OFFSET, 2421 }, + { 0x1d7ae, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d7af, G_UNICODE_NOT_PRESENT_OFFSET, 15209 }, + { 0x1d7b0, G_UNICODE_NOT_PRESENT_OFFSET, 15212 }, + { 0x1d7b1, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d7b2, G_UNICODE_NOT_PRESENT_OFFSET, 4860 }, + { 0x1d7b3, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d7b4, G_UNICODE_NOT_PRESENT_OFFSET, 15215 }, + { 0x1d7b5, G_UNICODE_NOT_PRESENT_OFFSET, 20 }, + { 0x1d7b6, G_UNICODE_NOT_PRESENT_OFFSET, 15218 }, + { 0x1d7b7, G_UNICODE_NOT_PRESENT_OFFSET, 15221 }, + { 0x1d7b8, G_UNICODE_NOT_PRESENT_OFFSET, 15224 }, + { 0x1d7b9, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d7ba, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d7bb, G_UNICODE_NOT_PRESENT_OFFSET, 1399 }, + { 0x1d7bc, G_UNICODE_NOT_PRESENT_OFFSET, 15227 }, + { 0x1d7bd, G_UNICODE_NOT_PRESENT_OFFSET, 15230 }, + { 0x1d7be, G_UNICODE_NOT_PRESENT_OFFSET, 15233 }, + { 0x1d7bf, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d7c0, G_UNICODE_NOT_PRESENT_OFFSET, 2424 }, + { 0x1d7c1, G_UNICODE_NOT_PRESENT_OFFSET, 15236 }, + { 0x1d7c2, G_UNICODE_NOT_PRESENT_OFFSET, 15239 }, + { 0x1d7c3, G_UNICODE_NOT_PRESENT_OFFSET, 15242 }, + { 0x1d7c4, G_UNICODE_NOT_PRESENT_OFFSET, 1405 }, + { 0x1d7c5, G_UNICODE_NOT_PRESENT_OFFSET, 1371 }, + { 0x1d7c6, G_UNICODE_NOT_PRESENT_OFFSET, 1393 }, + { 0x1d7c7, G_UNICODE_NOT_PRESENT_OFFSET, 1387 }, + { 0x1d7c8, G_UNICODE_NOT_PRESENT_OFFSET, 1396 }, + { 0x1d7c9, G_UNICODE_NOT_PRESENT_OFFSET, 1390 }, + { 0x1d7ca, G_UNICODE_NOT_PRESENT_OFFSET, 15246 }, + { 0x1d7cb, G_UNICODE_NOT_PRESENT_OFFSET, 15249 }, + { 0x1d7ce, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0x1d7cf, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0x1d7d0, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0x1d7d1, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0x1d7d2, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0x1d7d3, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0x1d7d4, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0x1d7d5, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0x1d7d6, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0x1d7d7, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0x1d7d8, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0x1d7d9, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0x1d7da, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0x1d7db, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0x1d7dc, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0x1d7dd, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0x1d7de, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0x1d7df, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0x1d7e0, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0x1d7e1, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0x1d7e2, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0x1d7e3, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0x1d7e4, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0x1d7e5, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0x1d7e6, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0x1d7e7, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0x1d7e8, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0x1d7e9, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0x1d7ea, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0x1d7eb, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0x1d7ec, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0x1d7ed, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0x1d7ee, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0x1d7ef, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0x1d7f0, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0x1d7f1, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0x1d7f2, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0x1d7f3, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0x1d7f4, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0x1d7f5, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0x1d7f6, G_UNICODE_NOT_PRESENT_OFFSET, 5253 }, + { 0x1d7f7, G_UNICODE_NOT_PRESENT_OFFSET, 27 }, + { 0x1d7f8, G_UNICODE_NOT_PRESENT_OFFSET, 12 }, + { 0x1d7f9, G_UNICODE_NOT_PRESENT_OFFSET, 14 }, + { 0x1d7fa, G_UNICODE_NOT_PRESENT_OFFSET, 5255 }, + { 0x1d7fb, G_UNICODE_NOT_PRESENT_OFFSET, 5257 }, + { 0x1d7fc, G_UNICODE_NOT_PRESENT_OFFSET, 5259 }, + { 0x1d7fd, G_UNICODE_NOT_PRESENT_OFFSET, 5261 }, + { 0x1d7fe, G_UNICODE_NOT_PRESENT_OFFSET, 5263 }, + { 0x1d7ff, G_UNICODE_NOT_PRESENT_OFFSET, 5265 }, + { 0x1f100, G_UNICODE_NOT_PRESENT_OFFSET, 15252 }, + { 0x1f101, G_UNICODE_NOT_PRESENT_OFFSET, 15255 }, + { 0x1f102, G_UNICODE_NOT_PRESENT_OFFSET, 15258 }, + { 0x1f103, G_UNICODE_NOT_PRESENT_OFFSET, 15261 }, + { 0x1f104, G_UNICODE_NOT_PRESENT_OFFSET, 15264 }, + { 0x1f105, G_UNICODE_NOT_PRESENT_OFFSET, 15267 }, + { 0x1f106, G_UNICODE_NOT_PRESENT_OFFSET, 15270 }, + { 0x1f107, G_UNICODE_NOT_PRESENT_OFFSET, 15273 }, + { 0x1f108, G_UNICODE_NOT_PRESENT_OFFSET, 15276 }, + { 0x1f109, G_UNICODE_NOT_PRESENT_OFFSET, 15279 }, + { 0x1f10a, G_UNICODE_NOT_PRESENT_OFFSET, 15282 }, + { 0x1f110, G_UNICODE_NOT_PRESENT_OFFSET, 15285 }, + { 0x1f111, G_UNICODE_NOT_PRESENT_OFFSET, 15289 }, + { 0x1f112, G_UNICODE_NOT_PRESENT_OFFSET, 15293 }, + { 0x1f113, G_UNICODE_NOT_PRESENT_OFFSET, 15297 }, + { 0x1f114, G_UNICODE_NOT_PRESENT_OFFSET, 15301 }, + { 0x1f115, G_UNICODE_NOT_PRESENT_OFFSET, 15305 }, + { 0x1f116, G_UNICODE_NOT_PRESENT_OFFSET, 15309 }, + { 0x1f117, G_UNICODE_NOT_PRESENT_OFFSET, 15313 }, + { 0x1f118, G_UNICODE_NOT_PRESENT_OFFSET, 15317 }, + { 0x1f119, G_UNICODE_NOT_PRESENT_OFFSET, 15321 }, + { 0x1f11a, G_UNICODE_NOT_PRESENT_OFFSET, 15325 }, + { 0x1f11b, G_UNICODE_NOT_PRESENT_OFFSET, 15329 }, + { 0x1f11c, G_UNICODE_NOT_PRESENT_OFFSET, 15333 }, + { 0x1f11d, G_UNICODE_NOT_PRESENT_OFFSET, 15337 }, + { 0x1f11e, G_UNICODE_NOT_PRESENT_OFFSET, 15341 }, + { 0x1f11f, G_UNICODE_NOT_PRESENT_OFFSET, 15345 }, + { 0x1f120, G_UNICODE_NOT_PRESENT_OFFSET, 15349 }, + { 0x1f121, G_UNICODE_NOT_PRESENT_OFFSET, 15353 }, + { 0x1f122, G_UNICODE_NOT_PRESENT_OFFSET, 15357 }, + { 0x1f123, G_UNICODE_NOT_PRESENT_OFFSET, 15361 }, + { 0x1f124, G_UNICODE_NOT_PRESENT_OFFSET, 15365 }, + { 0x1f125, G_UNICODE_NOT_PRESENT_OFFSET, 15369 }, + { 0x1f126, G_UNICODE_NOT_PRESENT_OFFSET, 15373 }, + { 0x1f127, G_UNICODE_NOT_PRESENT_OFFSET, 15377 }, + { 0x1f128, G_UNICODE_NOT_PRESENT_OFFSET, 15381 }, + { 0x1f129, G_UNICODE_NOT_PRESENT_OFFSET, 15385 }, + { 0x1f12a, G_UNICODE_NOT_PRESENT_OFFSET, 15389 }, + { 0x1f12b, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1f12c, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1f12d, G_UNICODE_NOT_PRESENT_OFFSET, 15397 }, + { 0x1f12e, G_UNICODE_NOT_PRESENT_OFFSET, 15400 }, + { 0x1f130, G_UNICODE_NOT_PRESENT_OFFSET, 2309 }, + { 0x1f131, G_UNICODE_NOT_PRESENT_OFFSET, 2314 }, + { 0x1f132, G_UNICODE_NOT_PRESENT_OFFSET, 5292 }, + { 0x1f133, G_UNICODE_NOT_PRESENT_OFFSET, 2316 }, + { 0x1f134, G_UNICODE_NOT_PRESENT_OFFSET, 2318 }, + { 0x1f135, G_UNICODE_NOT_PRESENT_OFFSET, 5336 }, + { 0x1f136, G_UNICODE_NOT_PRESENT_OFFSET, 2323 }, + { 0x1f137, G_UNICODE_NOT_PRESENT_OFFSET, 2325 }, + { 0x1f138, G_UNICODE_NOT_PRESENT_OFFSET, 2327 }, + { 0x1f139, G_UNICODE_NOT_PRESENT_OFFSET, 2329 }, + { 0x1f13a, G_UNICODE_NOT_PRESENT_OFFSET, 2331 }, + { 0x1f13b, G_UNICODE_NOT_PRESENT_OFFSET, 2333 }, + { 0x1f13c, G_UNICODE_NOT_PRESENT_OFFSET, 2335 }, + { 0x1f13d, G_UNICODE_NOT_PRESENT_OFFSET, 2337 }, + { 0x1f13e, G_UNICODE_NOT_PRESENT_OFFSET, 2339 }, + { 0x1f13f, G_UNICODE_NOT_PRESENT_OFFSET, 2344 }, + { 0x1f140, G_UNICODE_NOT_PRESENT_OFFSET, 5319 }, + { 0x1f141, G_UNICODE_NOT_PRESENT_OFFSET, 2346 }, + { 0x1f142, G_UNICODE_NOT_PRESENT_OFFSET, 6133 }, + { 0x1f143, G_UNICODE_NOT_PRESENT_OFFSET, 2348 }, + { 0x1f144, G_UNICODE_NOT_PRESENT_OFFSET, 2350 }, + { 0x1f145, G_UNICODE_NOT_PRESENT_OFFSET, 5470 }, + { 0x1f146, G_UNICODE_NOT_PRESENT_OFFSET, 2352 }, + { 0x1f147, G_UNICODE_NOT_PRESENT_OFFSET, 5487 }, + { 0x1f148, G_UNICODE_NOT_PRESENT_OFFSET, 6135 }, + { 0x1f149, G_UNICODE_NOT_PRESENT_OFFSET, 5331 }, + { 0x1f14a, G_UNICODE_NOT_PRESENT_OFFSET, 15403 }, + { 0x1f14b, G_UNICODE_NOT_PRESENT_OFFSET, 10556 }, + { 0x1f14c, G_UNICODE_NOT_PRESENT_OFFSET, 15406 }, + { 0x1f14d, G_UNICODE_NOT_PRESENT_OFFSET, 15409 }, + { 0x1f14e, G_UNICODE_NOT_PRESENT_OFFSET, 15412 }, + { 0x1f14f, G_UNICODE_NOT_PRESENT_OFFSET, 15416 }, + { 0x1f190, G_UNICODE_NOT_PRESENT_OFFSET, 15419 }, + { 0x1f200, G_UNICODE_NOT_PRESENT_OFFSET, 15422 }, + { 0x1f201, G_UNICODE_NOT_PRESENT_OFFSET, 15429 }, + { 0x1f202, G_UNICODE_NOT_PRESENT_OFFSET, 8848 }, + { 0x1f210, G_UNICODE_NOT_PRESENT_OFFSET, 6433 }, + { 0x1f211, G_UNICODE_NOT_PRESENT_OFFSET, 15436 }, + { 0x1f212, G_UNICODE_NOT_PRESENT_OFFSET, 15440 }, + { 0x1f213, G_UNICODE_NOT_PRESENT_OFFSET, 7346 }, + { 0x1f214, G_UNICODE_NOT_PRESENT_OFFSET, 6205 }, + { 0x1f215, G_UNICODE_NOT_PRESENT_OFFSET, 15444 }, + { 0x1f216, G_UNICODE_NOT_PRESENT_OFFSET, 15448 }, + { 0x1f217, G_UNICODE_NOT_PRESENT_OFFSET, 7887 }, + { 0x1f218, G_UNICODE_NOT_PRESENT_OFFSET, 15452 }, + { 0x1f219, G_UNICODE_NOT_PRESENT_OFFSET, 15456 }, + { 0x1f21a, G_UNICODE_NOT_PRESENT_OFFSET, 15460 }, + { 0x1f21b, G_UNICODE_NOT_PRESENT_OFFSET, 11592 }, + { 0x1f21c, G_UNICODE_NOT_PRESENT_OFFSET, 15464 }, + { 0x1f21d, G_UNICODE_NOT_PRESENT_OFFSET, 15468 }, + { 0x1f21e, G_UNICODE_NOT_PRESENT_OFFSET, 15472 }, + { 0x1f21f, G_UNICODE_NOT_PRESENT_OFFSET, 15476 }, + { 0x1f220, G_UNICODE_NOT_PRESENT_OFFSET, 15480 }, + { 0x1f221, G_UNICODE_NOT_PRESENT_OFFSET, 15484 }, + { 0x1f222, G_UNICODE_NOT_PRESENT_OFFSET, 6577 }, + { 0x1f223, G_UNICODE_NOT_PRESENT_OFFSET, 15488 }, + { 0x1f224, G_UNICODE_NOT_PRESENT_OFFSET, 15492 }, + { 0x1f225, G_UNICODE_NOT_PRESENT_OFFSET, 15496 }, + { 0x1f226, G_UNICODE_NOT_PRESENT_OFFSET, 15500 }, + { 0x1f227, G_UNICODE_NOT_PRESENT_OFFSET, 15504 }, + { 0x1f228, G_UNICODE_NOT_PRESENT_OFFSET, 15508 }, + { 0x1f229, G_UNICODE_NOT_PRESENT_OFFSET, 6181 }, + { 0x1f22a, G_UNICODE_NOT_PRESENT_OFFSET, 7855 }, + { 0x1f22b, G_UNICODE_NOT_PRESENT_OFFSET, 15512 }, + { 0x1f22c, G_UNICODE_NOT_PRESENT_OFFSET, 8646 }, + { 0x1f22d, G_UNICODE_NOT_PRESENT_OFFSET, 7867 }, + { 0x1f22e, G_UNICODE_NOT_PRESENT_OFFSET, 8650 }, + { 0x1f22f, G_UNICODE_NOT_PRESENT_OFFSET, 15516 }, + { 0x1f230, G_UNICODE_NOT_PRESENT_OFFSET, 6801 }, + { 0x1f231, G_UNICODE_NOT_PRESENT_OFFSET, 15520 }, + { 0x1f232, G_UNICODE_NOT_PRESENT_OFFSET, 15524 }, + { 0x1f233, G_UNICODE_NOT_PRESENT_OFFSET, 15528 }, + { 0x1f234, G_UNICODE_NOT_PRESENT_OFFSET, 15532 }, + { 0x1f235, G_UNICODE_NOT_PRESENT_OFFSET, 15536 }, + { 0x1f236, G_UNICODE_NOT_PRESENT_OFFSET, 8578 }, + { 0x1f237, G_UNICODE_NOT_PRESENT_OFFSET, 6473 }, + { 0x1f238, G_UNICODE_NOT_PRESENT_OFFSET, 15540 }, + { 0x1f239, G_UNICODE_NOT_PRESENT_OFFSET, 15544 }, + { 0x1f23a, G_UNICODE_NOT_PRESENT_OFFSET, 15548 }, + { 0x1f240, G_UNICODE_NOT_PRESENT_OFFSET, 15552 }, + { 0x1f241, G_UNICODE_NOT_PRESENT_OFFSET, 15562 }, + { 0x1f242, G_UNICODE_NOT_PRESENT_OFFSET, 15572 }, + { 0x1f243, G_UNICODE_NOT_PRESENT_OFFSET, 15582 }, + { 0x1f244, G_UNICODE_NOT_PRESENT_OFFSET, 15592 }, + { 0x1f245, G_UNICODE_NOT_PRESENT_OFFSET, 15602 }, + { 0x1f246, G_UNICODE_NOT_PRESENT_OFFSET, 15612 }, + { 0x1f247, G_UNICODE_NOT_PRESENT_OFFSET, 15622 }, + { 0x1f248, G_UNICODE_NOT_PRESENT_OFFSET, 15632 }, + { 0x1f250, G_UNICODE_NOT_PRESENT_OFFSET, 15642 }, + { 0x1f251, G_UNICODE_NOT_PRESENT_OFFSET, 15646 }, + { 0x2f800, 15650, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f801, 15654, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f802, 15658, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f803, 15662, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f804, 15667, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f805, 11956, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f806, 15671, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f807, 15675, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f808, 15679, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f809, 15683, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f80a, 11960, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f80b, 15687, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f80c, 15691, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f80d, 15695, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f80e, 11964, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f80f, 15700, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f810, 15704, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f811, 15708, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f812, 15712, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f813, 15717, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f814, 15721, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f815, 15472, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f816, 15725, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f817, 15730, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f818, 15734, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f819, 15738, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f81a, 15742, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f81b, 12185, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f81c, 15746, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f81d, 6245, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f81e, 15751, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f81f, 15755, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f820, 15759, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f821, 15763, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f822, 15544, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f823, 15767, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f824, 15771, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f825, 12205, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f826, 11968, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f827, 11972, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f828, 12209, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f829, 15775, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f82a, 15779, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f82b, 11248, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f82c, 15783, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f82d, 11976, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f82e, 15787, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f82f, 15791, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f830, 15795, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f831, 15799, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f832, 15799, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f833, 15799, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f834, 15803, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f835, 15808, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f836, 15812, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f837, 15816, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f838, 15820, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f839, 15825, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f83a, 15829, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f83b, 15833, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f83c, 15837, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f83d, 15841, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f83e, 15845, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f83f, 15849, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f840, 15853, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f841, 15857, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f842, 15861, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f843, 15865, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f844, 15869, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f845, 15873, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f846, 15873, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f847, 12217, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f848, 15877, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f849, 15881, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f84a, 15885, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f84b, 15889, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f84c, 11984, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f84d, 15893, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f84e, 15897, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f84f, 15901, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f850, 11832, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f851, 15905, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f852, 15909, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f853, 15913, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f854, 15917, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f855, 15921, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f856, 15925, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f857, 15929, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f858, 15933, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f859, 15937, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f85a, 15942, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f85b, 15946, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f85c, 15950, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f85d, 15444, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f85e, 15954, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f85f, 15958, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f860, 15962, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f861, 15967, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f862, 15972, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f863, 15976, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f864, 15980, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f865, 15984, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f866, 15988, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f867, 15992, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f868, 15996, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f869, 16000, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f86a, 16004, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f86b, 16004, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f86c, 16008, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f86d, 16013, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f86e, 16017, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f86f, 11232, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f870, 16021, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f871, 16025, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f872, 16030, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f873, 16034, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f874, 16038, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f875, 6349, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f876, 16042, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f877, 16046, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f878, 6357, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f879, 16050, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f87a, 16054, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f87b, 16058, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f87c, 16063, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f87d, 16067, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f87e, 16072, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f87f, 16076, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f880, 16080, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f881, 16084, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f882, 16088, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f883, 16092, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f884, 16096, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f885, 16100, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f886, 16104, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f887, 16108, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f888, 16112, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f889, 16116, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f88a, 16121, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f88b, 16125, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f88c, 16129, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f88d, 16133, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f88e, 11024, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f88f, 16137, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f890, 6397, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f891, 16142, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f892, 16142, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f893, 16147, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f894, 16151, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f895, 16151, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f896, 16155, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f897, 16159, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f898, 16164, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f899, 16169, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f89a, 16173, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f89b, 16177, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f89c, 16181, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f89d, 16185, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f89e, 16189, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f89f, 16193, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a0, 16197, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a1, 16201, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a2, 16205, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a3, 12004, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a4, 16209, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a5, 16214, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a6, 16218, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a7, 16222, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a8, 12265, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8a9, 16222, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8aa, 16226, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ab, 12012, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ac, 16230, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ad, 16234, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ae, 16238, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8af, 16242, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b0, 12016, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b1, 10916, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b2, 16246, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b3, 16250, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b4, 16254, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b5, 16258, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b6, 16262, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b7, 16266, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b8, 16270, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8b9, 16275, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ba, 16279, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8bb, 16283, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8bc, 16287, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8bd, 16291, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8be, 16295, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8bf, 16300, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c0, 16304, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c1, 16308, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c2, 16312, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c3, 16316, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c4, 16320, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c5, 16324, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c6, 16328, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c7, 16332, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c8, 12020, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8c9, 16336, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ca, 16340, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8cb, 16345, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8cc, 16349, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8cd, 16353, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ce, 16357, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8cf, 12028, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d0, 16361, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d1, 16365, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d2, 16369, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d3, 16373, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d4, 16377, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d5, 16381, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d6, 16385, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d7, 16389, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d8, 11028, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8d9, 12297, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8da, 16393, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8db, 16397, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8dc, 16401, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8dd, 16405, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8de, 16410, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8df, 16414, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e0, 16418, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e1, 16422, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e2, 12032, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e3, 16426, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e4, 16431, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e5, 16435, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e6, 16439, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e7, 12468, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e8, 16443, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8e9, 16447, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ea, 16451, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8eb, 16455, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ec, 16459, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ed, 16464, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ee, 16468, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ef, 16472, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f0, 16476, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f1, 16481, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f2, 16485, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f3, 16489, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f4, 16493, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f5, 11300, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f6, 16497, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f7, 16501, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f8, 16506, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8f9, 16511, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8fa, 16516, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8fb, 16520, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8fc, 16525, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8fd, 16529, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8fe, 16533, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f8ff, 16537, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f900, 16541, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f901, 12036, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f902, 11632, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f903, 16545, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f904, 16549, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f905, 16553, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f906, 16557, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f907, 16562, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f908, 16566, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f909, 16570, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f90a, 16574, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f90b, 12309, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f90c, 16578, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f90d, 16582, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f90e, 16587, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f90f, 16591, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f910, 16595, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f911, 16600, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f912, 16605, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f913, 16609, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f914, 12313, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f915, 16613, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f916, 16617, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f917, 16621, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f918, 16625, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f919, 16629, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f91a, 16633, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f91b, 16637, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f91c, 16642, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f91d, 16646, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f91e, 16651, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f91f, 16655, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f920, 16660, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f921, 12321, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f922, 16664, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f923, 16668, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f924, 16673, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f925, 16677, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f926, 16681, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f927, 16686, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f928, 16691, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f929, 16695, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f92a, 16699, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f92b, 16703, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f92c, 16707, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f92d, 16707, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f92e, 16711, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f92f, 16715, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f930, 12329, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f931, 16719, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f932, 16723, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f933, 16727, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f934, 16731, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f935, 16735, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f936, 16740, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f937, 16744, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f938, 11244, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f939, 16749, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f93a, 16754, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f93b, 16758, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f93c, 16763, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f93d, 16768, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f93e, 16773, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f93f, 16777, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f940, 12353, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f941, 16781, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f942, 16786, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f943, 16791, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f944, 16796, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f945, 16801, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f946, 16805, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f947, 16805, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f948, 12357, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f949, 12476, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f94a, 16809, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f94b, 16813, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f94c, 16817, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f94d, 16821, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f94e, 16826, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f94f, 11096, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f950, 12365, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f951, 16830, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f952, 16834, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f953, 12076, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f954, 16839, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f955, 16844, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f956, 11912, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f957, 16849, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f958, 16853, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f959, 12088, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f95a, 16857, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f95b, 16861, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f95c, 16865, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f95d, 16870, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f95e, 16870, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f95f, 16875, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f960, 16879, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f961, 16883, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f962, 16888, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f963, 16892, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f964, 16896, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f965, 16900, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f966, 16905, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f967, 16909, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f968, 16913, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f969, 16917, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f96a, 16921, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f96b, 16925, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f96c, 16930, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f96d, 16934, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f96e, 16938, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f96f, 16942, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f970, 16946, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f971, 16950, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f972, 16954, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f973, 16959, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f974, 16964, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f975, 16968, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f976, 16973, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f977, 16977, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f978, 16982, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f979, 16986, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f97a, 12112, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f97b, 16990, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f97c, 16995, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f97d, 17000, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f97e, 17004, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f97f, 17009, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f980, 17013, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f981, 17018, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f982, 17022, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f983, 17026, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f984, 17030, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f985, 17034, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f986, 17038, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f987, 17042, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f988, 17047, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f989, 17052, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f98a, 17057, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f98b, 16147, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f98c, 17062, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f98d, 17066, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f98e, 17070, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f98f, 17074, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f990, 17078, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f991, 17082, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f992, 17086, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f993, 17090, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f994, 17094, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f995, 17098, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f996, 17102, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f997, 17106, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f998, 11312, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f999, 17111, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f99a, 17115, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f99b, 17119, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f99c, 17123, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f99d, 17127, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f99e, 17131, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f99f, 12124, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a0, 17135, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a1, 17139, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a2, 17143, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a3, 17147, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a4, 17151, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a5, 17156, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a6, 17161, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a7, 17166, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a8, 17170, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9a9, 17174, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9aa, 17178, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ab, 17182, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ac, 17187, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ad, 17191, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ae, 17196, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9af, 17200, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b0, 17204, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b1, 17209, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b2, 17214, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b3, 17218, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b4, 11076, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b5, 17222, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b6, 17226, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b7, 17230, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b8, 17234, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9b9, 17238, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ba, 17242, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9bb, 12393, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9bc, 17246, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9bd, 17250, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9be, 17254, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9bf, 17258, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c0, 17262, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c1, 17266, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c2, 17270, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c3, 17274, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c4, 6757, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c5, 17278, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c6, 17283, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c7, 17287, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c8, 17291, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9c9, 17295, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ca, 17299, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9cb, 17303, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9cc, 17308, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9cd, 17313, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ce, 17317, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9cf, 17321, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d0, 12413, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d1, 12417, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d2, 6785, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d3, 17325, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d4, 17330, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d5, 17334, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d6, 17338, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d7, 17342, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d8, 17346, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9d9, 17351, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9da, 17356, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9db, 17360, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9dc, 17364, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9dd, 17368, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9de, 17373, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9df, 12421, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e0, 17377, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e1, 17382, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e2, 17387, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e3, 17391, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e4, 17395, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e5, 17399, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e6, 17404, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e7, 17408, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e8, 17412, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9e9, 17416, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ea, 17420, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9eb, 17424, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ec, 17428, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ed, 17432, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ee, 17437, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ef, 17441, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f0, 17445, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f1, 17449, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f2, 17454, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f3, 17458, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f4, 17462, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f5, 17466, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f6, 17470, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f7, 17475, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f8, 17480, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9f9, 17484, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9fa, 17488, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9fb, 17492, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9fc, 17497, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9fd, 17501, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9fe, 12445, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2f9ff, 12445, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa00, 17506, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa01, 17510, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa02, 17515, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa03, 17519, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa04, 17523, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa05, 17527, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa06, 17531, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa07, 17535, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa08, 17539, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa09, 17543, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa0a, 12449, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa0b, 17548, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa0c, 17552, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa0d, 17556, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa0e, 17560, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa0f, 17564, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa10, 17568, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa11, 17573, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa12, 17577, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa13, 17582, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa14, 17587, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa15, 6977, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa16, 17592, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa17, 6993, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa18, 17596, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa19, 17600, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa1a, 17604, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa1b, 17608, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa1c, 7013, G_UNICODE_NOT_PRESENT_OFFSET }, + { 0x2fa1d, 17612, G_UNICODE_NOT_PRESENT_OFFSET } +}; + +static const gchar decomp_expansion_string[] = + "\x20\0" /* offset 0 */ + "\x20\xcc\x88\0" /* offset 2 */ + "\x61\0" /* offset 6 */ + "\x20\xcc\x84\0" /* offset 8 */ + "\x32\0" /* offset 12 */ + "\x33\0" /* offset 14 */ + "\x20\xcc\x81\0" /* offset 16 */ + "\xce\xbc\0" /* offset 20 */ + "\x20\xcc\xa7\0" /* offset 23 */ + "\x31\0" /* offset 27 */ + "\x6f\0" /* offset 29 */ + "\x31\xe2\x81\x84\x34\0" /* offset 31 */ + "\x31\xe2\x81\x84\x32\0" /* offset 37 */ + "\x33\xe2\x81\x84\x34\0" /* offset 43 */ + "\x41\xcc\x80\0" /* offset 49 */ + "\x41\xcc\x81\0" /* offset 53 */ + "\x41\xcc\x82\0" /* offset 57 */ + "\x41\xcc\x83\0" /* offset 61 */ + "\x41\xcc\x88\0" /* offset 65 */ + "\x41\xcc\x8a\0" /* offset 69 */ + "\x43\xcc\xa7\0" /* offset 73 */ + "\x45\xcc\x80\0" /* offset 77 */ + "\x45\xcc\x81\0" /* offset 81 */ + "\x45\xcc\x82\0" /* offset 85 */ + "\x45\xcc\x88\0" /* offset 89 */ + "\x49\xcc\x80\0" /* offset 93 */ + "\x49\xcc\x81\0" /* offset 97 */ + "\x49\xcc\x82\0" /* offset 101 */ + "\x49\xcc\x88\0" /* offset 105 */ + "\x4e\xcc\x83\0" /* offset 109 */ + "\x4f\xcc\x80\0" /* offset 113 */ + "\x4f\xcc\x81\0" /* offset 117 */ + "\x4f\xcc\x82\0" /* offset 121 */ + "\x4f\xcc\x83\0" /* offset 125 */ + "\x4f\xcc\x88\0" /* offset 129 */ + "\x55\xcc\x80\0" /* offset 133 */ + "\x55\xcc\x81\0" /* offset 137 */ + "\x55\xcc\x82\0" /* offset 141 */ + "\x55\xcc\x88\0" /* offset 145 */ + "\x59\xcc\x81\0" /* offset 149 */ + "\x61\xcc\x80\0" /* offset 153 */ + "\x61\xcc\x81\0" /* offset 157 */ + "\x61\xcc\x82\0" /* offset 161 */ + "\x61\xcc\x83\0" /* offset 165 */ + "\x61\xcc\x88\0" /* offset 169 */ + "\x61\xcc\x8a\0" /* offset 173 */ + "\x63\xcc\xa7\0" /* offset 177 */ + "\x65\xcc\x80\0" /* offset 181 */ + "\x65\xcc\x81\0" /* offset 185 */ + "\x65\xcc\x82\0" /* offset 189 */ + "\x65\xcc\x88\0" /* offset 193 */ + "\x69\xcc\x80\0" /* offset 197 */ + "\x69\xcc\x81\0" /* offset 201 */ + "\x69\xcc\x82\0" /* offset 205 */ + "\x69\xcc\x88\0" /* offset 209 */ + "\x6e\xcc\x83\0" /* offset 213 */ + "\x6f\xcc\x80\0" /* offset 217 */ + "\x6f\xcc\x81\0" /* offset 221 */ + "\x6f\xcc\x82\0" /* offset 225 */ + "\x6f\xcc\x83\0" /* offset 229 */ + "\x6f\xcc\x88\0" /* offset 233 */ + "\x75\xcc\x80\0" /* offset 237 */ + "\x75\xcc\x81\0" /* offset 241 */ + "\x75\xcc\x82\0" /* offset 245 */ + "\x75\xcc\x88\0" /* offset 249 */ + "\x79\xcc\x81\0" /* offset 253 */ + "\x79\xcc\x88\0" /* offset 257 */ + "\x41\xcc\x84\0" /* offset 261 */ + "\x61\xcc\x84\0" /* offset 265 */ + "\x41\xcc\x86\0" /* offset 269 */ + "\x61\xcc\x86\0" /* offset 273 */ + "\x41\xcc\xa8\0" /* offset 277 */ + "\x61\xcc\xa8\0" /* offset 281 */ + "\x43\xcc\x81\0" /* offset 285 */ + "\x63\xcc\x81\0" /* offset 289 */ + "\x43\xcc\x82\0" /* offset 293 */ + "\x63\xcc\x82\0" /* offset 297 */ + "\x43\xcc\x87\0" /* offset 301 */ + "\x63\xcc\x87\0" /* offset 305 */ + "\x43\xcc\x8c\0" /* offset 309 */ + "\x63\xcc\x8c\0" /* offset 313 */ + "\x44\xcc\x8c\0" /* offset 317 */ + "\x64\xcc\x8c\0" /* offset 321 */ + "\x45\xcc\x84\0" /* offset 325 */ + "\x65\xcc\x84\0" /* offset 329 */ + "\x45\xcc\x86\0" /* offset 333 */ + "\x65\xcc\x86\0" /* offset 337 */ + "\x45\xcc\x87\0" /* offset 341 */ + "\x65\xcc\x87\0" /* offset 345 */ + "\x45\xcc\xa8\0" /* offset 349 */ + "\x65\xcc\xa8\0" /* offset 353 */ + "\x45\xcc\x8c\0" /* offset 357 */ + "\x65\xcc\x8c\0" /* offset 361 */ + "\x47\xcc\x82\0" /* offset 365 */ + "\x67\xcc\x82\0" /* offset 369 */ + "\x47\xcc\x86\0" /* offset 373 */ + "\x67\xcc\x86\0" /* offset 377 */ + "\x47\xcc\x87\0" /* offset 381 */ + "\x67\xcc\x87\0" /* offset 385 */ + "\x47\xcc\xa7\0" /* offset 389 */ + "\x67\xcc\xa7\0" /* offset 393 */ + "\x48\xcc\x82\0" /* offset 397 */ + "\x68\xcc\x82\0" /* offset 401 */ + "\x49\xcc\x83\0" /* offset 405 */ + "\x69\xcc\x83\0" /* offset 409 */ + "\x49\xcc\x84\0" /* offset 413 */ + "\x69\xcc\x84\0" /* offset 417 */ + "\x49\xcc\x86\0" /* offset 421 */ + "\x69\xcc\x86\0" /* offset 425 */ + "\x49\xcc\xa8\0" /* offset 429 */ + "\x69\xcc\xa8\0" /* offset 433 */ + "\x49\xcc\x87\0" /* offset 437 */ + "\x49\x4a\0" /* offset 441 */ + "\x69\x6a\0" /* offset 444 */ + "\x4a\xcc\x82\0" /* offset 447 */ + "\x6a\xcc\x82\0" /* offset 451 */ + "\x4b\xcc\xa7\0" /* offset 455 */ + "\x6b\xcc\xa7\0" /* offset 459 */ + "\x4c\xcc\x81\0" /* offset 463 */ + "\x6c\xcc\x81\0" /* offset 467 */ + "\x4c\xcc\xa7\0" /* offset 471 */ + "\x6c\xcc\xa7\0" /* offset 475 */ + "\x4c\xcc\x8c\0" /* offset 479 */ + "\x6c\xcc\x8c\0" /* offset 483 */ + "\x4c\xc2\xb7\0" /* offset 487 */ + "\x6c\xc2\xb7\0" /* offset 491 */ + "\x4e\xcc\x81\0" /* offset 495 */ + "\x6e\xcc\x81\0" /* offset 499 */ + "\x4e\xcc\xa7\0" /* offset 503 */ + "\x6e\xcc\xa7\0" /* offset 507 */ + "\x4e\xcc\x8c\0" /* offset 511 */ + "\x6e\xcc\x8c\0" /* offset 515 */ + "\xca\xbc\x6e\0" /* offset 519 */ + "\x4f\xcc\x84\0" /* offset 523 */ + "\x6f\xcc\x84\0" /* offset 527 */ + "\x4f\xcc\x86\0" /* offset 531 */ + "\x6f\xcc\x86\0" /* offset 535 */ + "\x4f\xcc\x8b\0" /* offset 539 */ + "\x6f\xcc\x8b\0" /* offset 543 */ + "\x52\xcc\x81\0" /* offset 547 */ + "\x72\xcc\x81\0" /* offset 551 */ + "\x52\xcc\xa7\0" /* offset 555 */ + "\x72\xcc\xa7\0" /* offset 559 */ + "\x52\xcc\x8c\0" /* offset 563 */ + "\x72\xcc\x8c\0" /* offset 567 */ + "\x53\xcc\x81\0" /* offset 571 */ + "\x73\xcc\x81\0" /* offset 575 */ + "\x53\xcc\x82\0" /* offset 579 */ + "\x73\xcc\x82\0" /* offset 583 */ + "\x53\xcc\xa7\0" /* offset 587 */ + "\x73\xcc\xa7\0" /* offset 591 */ + "\x53\xcc\x8c\0" /* offset 595 */ + "\x73\xcc\x8c\0" /* offset 599 */ + "\x54\xcc\xa7\0" /* offset 603 */ + "\x74\xcc\xa7\0" /* offset 607 */ + "\x54\xcc\x8c\0" /* offset 611 */ + "\x74\xcc\x8c\0" /* offset 615 */ + "\x55\xcc\x83\0" /* offset 619 */ + "\x75\xcc\x83\0" /* offset 623 */ + "\x55\xcc\x84\0" /* offset 627 */ + "\x75\xcc\x84\0" /* offset 631 */ + "\x55\xcc\x86\0" /* offset 635 */ + "\x75\xcc\x86\0" /* offset 639 */ + "\x55\xcc\x8a\0" /* offset 643 */ + "\x75\xcc\x8a\0" /* offset 647 */ + "\x55\xcc\x8b\0" /* offset 651 */ + "\x75\xcc\x8b\0" /* offset 655 */ + "\x55\xcc\xa8\0" /* offset 659 */ + "\x75\xcc\xa8\0" /* offset 663 */ + "\x57\xcc\x82\0" /* offset 667 */ + "\x77\xcc\x82\0" /* offset 671 */ + "\x59\xcc\x82\0" /* offset 675 */ + "\x79\xcc\x82\0" /* offset 679 */ + "\x59\xcc\x88\0" /* offset 683 */ + "\x5a\xcc\x81\0" /* offset 687 */ + "\x7a\xcc\x81\0" /* offset 691 */ + "\x5a\xcc\x87\0" /* offset 695 */ + "\x7a\xcc\x87\0" /* offset 699 */ + "\x5a\xcc\x8c\0" /* offset 703 */ + "\x7a\xcc\x8c\0" /* offset 707 */ + "\x73\0" /* offset 711 */ + "\x4f\xcc\x9b\0" /* offset 713 */ + "\x6f\xcc\x9b\0" /* offset 717 */ + "\x55\xcc\x9b\0" /* offset 721 */ + "\x75\xcc\x9b\0" /* offset 725 */ + "\x44\x5a\xcc\x8c\0" /* offset 729 */ + "\x44\x7a\xcc\x8c\0" /* offset 734 */ + "\x64\x7a\xcc\x8c\0" /* offset 739 */ + "\x4c\x4a\0" /* offset 744 */ + "\x4c\x6a\0" /* offset 747 */ + "\x6c\x6a\0" /* offset 750 */ + "\x4e\x4a\0" /* offset 753 */ + "\x4e\x6a\0" /* offset 756 */ + "\x6e\x6a\0" /* offset 759 */ + "\x41\xcc\x8c\0" /* offset 762 */ + "\x61\xcc\x8c\0" /* offset 766 */ + "\x49\xcc\x8c\0" /* offset 770 */ + "\x69\xcc\x8c\0" /* offset 774 */ + "\x4f\xcc\x8c\0" /* offset 778 */ + "\x6f\xcc\x8c\0" /* offset 782 */ + "\x55\xcc\x8c\0" /* offset 786 */ + "\x75\xcc\x8c\0" /* offset 790 */ + "\x55\xcc\x88\xcc\x84\0" /* offset 794 */ + "\x75\xcc\x88\xcc\x84\0" /* offset 800 */ + "\x55\xcc\x88\xcc\x81\0" /* offset 806 */ + "\x75\xcc\x88\xcc\x81\0" /* offset 812 */ + "\x55\xcc\x88\xcc\x8c\0" /* offset 818 */ + "\x75\xcc\x88\xcc\x8c\0" /* offset 824 */ + "\x55\xcc\x88\xcc\x80\0" /* offset 830 */ + "\x75\xcc\x88\xcc\x80\0" /* offset 836 */ + "\x41\xcc\x88\xcc\x84\0" /* offset 842 */ + "\x61\xcc\x88\xcc\x84\0" /* offset 848 */ + "\x41\xcc\x87\xcc\x84\0" /* offset 854 */ + "\x61\xcc\x87\xcc\x84\0" /* offset 860 */ + "\xc3\x86\xcc\x84\0" /* offset 866 */ + "\xc3\xa6\xcc\x84\0" /* offset 871 */ + "\x47\xcc\x8c\0" /* offset 876 */ + "\x67\xcc\x8c\0" /* offset 880 */ + "\x4b\xcc\x8c\0" /* offset 884 */ + "\x6b\xcc\x8c\0" /* offset 888 */ + "\x4f\xcc\xa8\0" /* offset 892 */ + "\x6f\xcc\xa8\0" /* offset 896 */ + "\x4f\xcc\xa8\xcc\x84\0" /* offset 900 */ + "\x6f\xcc\xa8\xcc\x84\0" /* offset 906 */ + "\xc6\xb7\xcc\x8c\0" /* offset 912 */ + "\xca\x92\xcc\x8c\0" /* offset 917 */ + "\x6a\xcc\x8c\0" /* offset 922 */ + "\x44\x5a\0" /* offset 926 */ + "\x44\x7a\0" /* offset 929 */ + "\x64\x7a\0" /* offset 932 */ + "\x47\xcc\x81\0" /* offset 935 */ + "\x67\xcc\x81\0" /* offset 939 */ + "\x4e\xcc\x80\0" /* offset 943 */ + "\x6e\xcc\x80\0" /* offset 947 */ + "\x41\xcc\x8a\xcc\x81\0" /* offset 951 */ + "\x61\xcc\x8a\xcc\x81\0" /* offset 957 */ + "\xc3\x86\xcc\x81\0" /* offset 963 */ + "\xc3\xa6\xcc\x81\0" /* offset 968 */ + "\xc3\x98\xcc\x81\0" /* offset 973 */ + "\xc3\xb8\xcc\x81\0" /* offset 978 */ + "\x41\xcc\x8f\0" /* offset 983 */ + "\x61\xcc\x8f\0" /* offset 987 */ + "\x41\xcc\x91\0" /* offset 991 */ + "\x61\xcc\x91\0" /* offset 995 */ + "\x45\xcc\x8f\0" /* offset 999 */ + "\x65\xcc\x8f\0" /* offset 1003 */ + "\x45\xcc\x91\0" /* offset 1007 */ + "\x65\xcc\x91\0" /* offset 1011 */ + "\x49\xcc\x8f\0" /* offset 1015 */ + "\x69\xcc\x8f\0" /* offset 1019 */ + "\x49\xcc\x91\0" /* offset 1023 */ + "\x69\xcc\x91\0" /* offset 1027 */ + "\x4f\xcc\x8f\0" /* offset 1031 */ + "\x6f\xcc\x8f\0" /* offset 1035 */ + "\x4f\xcc\x91\0" /* offset 1039 */ + "\x6f\xcc\x91\0" /* offset 1043 */ + "\x52\xcc\x8f\0" /* offset 1047 */ + "\x72\xcc\x8f\0" /* offset 1051 */ + "\x52\xcc\x91\0" /* offset 1055 */ + "\x72\xcc\x91\0" /* offset 1059 */ + "\x55\xcc\x8f\0" /* offset 1063 */ + "\x75\xcc\x8f\0" /* offset 1067 */ + "\x55\xcc\x91\0" /* offset 1071 */ + "\x75\xcc\x91\0" /* offset 1075 */ + "\x53\xcc\xa6\0" /* offset 1079 */ + "\x73\xcc\xa6\0" /* offset 1083 */ + "\x54\xcc\xa6\0" /* offset 1087 */ + "\x74\xcc\xa6\0" /* offset 1091 */ + "\x48\xcc\x8c\0" /* offset 1095 */ + "\x68\xcc\x8c\0" /* offset 1099 */ + "\x41\xcc\x87\0" /* offset 1103 */ + "\x61\xcc\x87\0" /* offset 1107 */ + "\x45\xcc\xa7\0" /* offset 1111 */ + "\x65\xcc\xa7\0" /* offset 1115 */ + "\x4f\xcc\x88\xcc\x84\0" /* offset 1119 */ + "\x6f\xcc\x88\xcc\x84\0" /* offset 1125 */ + "\x4f\xcc\x83\xcc\x84\0" /* offset 1131 */ + "\x6f\xcc\x83\xcc\x84\0" /* offset 1137 */ + "\x4f\xcc\x87\0" /* offset 1143 */ + "\x6f\xcc\x87\0" /* offset 1147 */ + "\x4f\xcc\x87\xcc\x84\0" /* offset 1151 */ + "\x6f\xcc\x87\xcc\x84\0" /* offset 1157 */ + "\x59\xcc\x84\0" /* offset 1163 */ + "\x79\xcc\x84\0" /* offset 1167 */ + "\x68\0" /* offset 1171 */ + "\xc9\xa6\0" /* offset 1173 */ + "\x6a\0" /* offset 1176 */ + "\x72\0" /* offset 1178 */ + "\xc9\xb9\0" /* offset 1180 */ + "\xc9\xbb\0" /* offset 1183 */ + "\xca\x81\0" /* offset 1186 */ + "\x77\0" /* offset 1189 */ + "\x79\0" /* offset 1191 */ + "\x20\xcc\x86\0" /* offset 1193 */ + "\x20\xcc\x87\0" /* offset 1197 */ + "\x20\xcc\x8a\0" /* offset 1201 */ + "\x20\xcc\xa8\0" /* offset 1205 */ + "\x20\xcc\x83\0" /* offset 1209 */ + "\x20\xcc\x8b\0" /* offset 1213 */ + "\xc9\xa3\0" /* offset 1217 */ + "\x6c\0" /* offset 1220 */ + "\x78\0" /* offset 1222 */ + "\xca\x95\0" /* offset 1224 */ + "\xcc\x80\0" /* offset 1227 */ + "\xcc\x81\0" /* offset 1230 */ + "\xcc\x93\0" /* offset 1233 */ + "\xcc\x88\xcc\x81\0" /* offset 1236 */ + "\xca\xb9\0" /* offset 1241 */ + "\x20\xcd\x85\0" /* offset 1244 */ + "\x3b\0" /* offset 1248 */ + "\xc2\xa8\xcc\x81\0" /* offset 1250 */ + "\x20\xcc\x88\xcc\x81\0" /* offset 1255 */ + "\xce\x91\xcc\x81\0" /* offset 1261 */ + "\xc2\xb7\0" /* offset 1266 */ + "\xce\x95\xcc\x81\0" /* offset 1269 */ + "\xce\x97\xcc\x81\0" /* offset 1274 */ + "\xce\x99\xcc\x81\0" /* offset 1279 */ + "\xce\x9f\xcc\x81\0" /* offset 1284 */ + "\xce\xa5\xcc\x81\0" /* offset 1289 */ + "\xce\xa9\xcc\x81\0" /* offset 1294 */ + "\xce\xb9\xcc\x88\xcc\x81\0" /* offset 1299 */ + "\xce\x99\xcc\x88\0" /* offset 1306 */ + "\xce\xa5\xcc\x88\0" /* offset 1311 */ + "\xce\xb1\xcc\x81\0" /* offset 1316 */ + "\xce\xb5\xcc\x81\0" /* offset 1321 */ + "\xce\xb7\xcc\x81\0" /* offset 1326 */ + "\xce\xb9\xcc\x81\0" /* offset 1331 */ + "\xcf\x85\xcc\x88\xcc\x81\0" /* offset 1336 */ + "\xce\xb9\xcc\x88\0" /* offset 1343 */ + "\xcf\x85\xcc\x88\0" /* offset 1348 */ + "\xce\xbf\xcc\x81\0" /* offset 1353 */ + "\xcf\x85\xcc\x81\0" /* offset 1358 */ + "\xcf\x89\xcc\x81\0" /* offset 1363 */ + "\xce\xb2\0" /* offset 1368 */ + "\xce\xb8\0" /* offset 1371 */ + "\xce\xa5\0" /* offset 1374 */ + "\xcf\x92\xcc\x81\0" /* offset 1377 */ + "\xcf\x92\xcc\x88\0" /* offset 1382 */ + "\xcf\x86\0" /* offset 1387 */ + "\xcf\x80\0" /* offset 1390 */ + "\xce\xba\0" /* offset 1393 */ + "\xcf\x81\0" /* offset 1396 */ + "\xcf\x82\0" /* offset 1399 */ + "\xce\x98\0" /* offset 1402 */ + "\xce\xb5\0" /* offset 1405 */ + "\xce\xa3\0" /* offset 1408 */ + "\xd0\x95\xcc\x80\0" /* offset 1411 */ + "\xd0\x95\xcc\x88\0" /* offset 1416 */ + "\xd0\x93\xcc\x81\0" /* offset 1421 */ + "\xd0\x86\xcc\x88\0" /* offset 1426 */ + "\xd0\x9a\xcc\x81\0" /* offset 1431 */ + "\xd0\x98\xcc\x80\0" /* offset 1436 */ + "\xd0\xa3\xcc\x86\0" /* offset 1441 */ + "\xd0\x98\xcc\x86\0" /* offset 1446 */ + "\xd0\xb8\xcc\x86\0" /* offset 1451 */ + "\xd0\xb5\xcc\x80\0" /* offset 1456 */ + "\xd0\xb5\xcc\x88\0" /* offset 1461 */ + "\xd0\xb3\xcc\x81\0" /* offset 1466 */ + "\xd1\x96\xcc\x88\0" /* offset 1471 */ + "\xd0\xba\xcc\x81\0" /* offset 1476 */ + "\xd0\xb8\xcc\x80\0" /* offset 1481 */ + "\xd1\x83\xcc\x86\0" /* offset 1486 */ + "\xd1\xb4\xcc\x8f\0" /* offset 1491 */ + "\xd1\xb5\xcc\x8f\0" /* offset 1496 */ + "\xd0\x96\xcc\x86\0" /* offset 1501 */ + "\xd0\xb6\xcc\x86\0" /* offset 1506 */ + "\xd0\x90\xcc\x86\0" /* offset 1511 */ + "\xd0\xb0\xcc\x86\0" /* offset 1516 */ + "\xd0\x90\xcc\x88\0" /* offset 1521 */ + "\xd0\xb0\xcc\x88\0" /* offset 1526 */ + "\xd0\x95\xcc\x86\0" /* offset 1531 */ + "\xd0\xb5\xcc\x86\0" /* offset 1536 */ + "\xd3\x98\xcc\x88\0" /* offset 1541 */ + "\xd3\x99\xcc\x88\0" /* offset 1546 */ + "\xd0\x96\xcc\x88\0" /* offset 1551 */ + "\xd0\xb6\xcc\x88\0" /* offset 1556 */ + "\xd0\x97\xcc\x88\0" /* offset 1561 */ + "\xd0\xb7\xcc\x88\0" /* offset 1566 */ + "\xd0\x98\xcc\x84\0" /* offset 1571 */ + "\xd0\xb8\xcc\x84\0" /* offset 1576 */ + "\xd0\x98\xcc\x88\0" /* offset 1581 */ + "\xd0\xb8\xcc\x88\0" /* offset 1586 */ + "\xd0\x9e\xcc\x88\0" /* offset 1591 */ + "\xd0\xbe\xcc\x88\0" /* offset 1596 */ + "\xd3\xa8\xcc\x88\0" /* offset 1601 */ + "\xd3\xa9\xcc\x88\0" /* offset 1606 */ + "\xd0\xad\xcc\x88\0" /* offset 1611 */ + "\xd1\x8d\xcc\x88\0" /* offset 1616 */ + "\xd0\xa3\xcc\x84\0" /* offset 1621 */ + "\xd1\x83\xcc\x84\0" /* offset 1626 */ + "\xd0\xa3\xcc\x88\0" /* offset 1631 */ + "\xd1\x83\xcc\x88\0" /* offset 1636 */ + "\xd0\xa3\xcc\x8b\0" /* offset 1641 */ + "\xd1\x83\xcc\x8b\0" /* offset 1646 */ + "\xd0\xa7\xcc\x88\0" /* offset 1651 */ + "\xd1\x87\xcc\x88\0" /* offset 1656 */ + "\xd0\xab\xcc\x88\0" /* offset 1661 */ + "\xd1\x8b\xcc\x88\0" /* offset 1666 */ + "\xd5\xa5\xd6\x82\0" /* offset 1671 */ + "\xd8\xa7\xd9\x93\0" /* offset 1676 */ + "\xd8\xa7\xd9\x94\0" /* offset 1681 */ + "\xd9\x88\xd9\x94\0" /* offset 1686 */ + "\xd8\xa7\xd9\x95\0" /* offset 1691 */ + "\xd9\x8a\xd9\x94\0" /* offset 1696 */ + "\xd8\xa7\xd9\xb4\0" /* offset 1701 */ + "\xd9\x88\xd9\xb4\0" /* offset 1706 */ + "\xdb\x87\xd9\xb4\0" /* offset 1711 */ + "\xd9\x8a\xd9\xb4\0" /* offset 1716 */ + "\xdb\x95\xd9\x94\0" /* offset 1721 */ + "\xdb\x81\xd9\x94\0" /* offset 1726 */ + "\xdb\x92\xd9\x94\0" /* offset 1731 */ + "\xe0\xa4\xa8\xe0\xa4\xbc\0" /* offset 1736 */ + "\xe0\xa4\xb0\xe0\xa4\xbc\0" /* offset 1743 */ + "\xe0\xa4\xb3\xe0\xa4\xbc\0" /* offset 1750 */ + "\xe0\xa4\x95\xe0\xa4\xbc\0" /* offset 1757 */ + "\xe0\xa4\x96\xe0\xa4\xbc\0" /* offset 1764 */ + "\xe0\xa4\x97\xe0\xa4\xbc\0" /* offset 1771 */ + "\xe0\xa4\x9c\xe0\xa4\xbc\0" /* offset 1778 */ + "\xe0\xa4\xa1\xe0\xa4\xbc\0" /* offset 1785 */ + "\xe0\xa4\xa2\xe0\xa4\xbc\0" /* offset 1792 */ + "\xe0\xa4\xab\xe0\xa4\xbc\0" /* offset 1799 */ + "\xe0\xa4\xaf\xe0\xa4\xbc\0" /* offset 1806 */ + "\xe0\xa7\x87\xe0\xa6\xbe\0" /* offset 1813 */ + "\xe0\xa7\x87\xe0\xa7\x97\0" /* offset 1820 */ + "\xe0\xa6\xa1\xe0\xa6\xbc\0" /* offset 1827 */ + "\xe0\xa6\xa2\xe0\xa6\xbc\0" /* offset 1834 */ + "\xe0\xa6\xaf\xe0\xa6\xbc\0" /* offset 1841 */ + "\xe0\xa8\xb2\xe0\xa8\xbc\0" /* offset 1848 */ + "\xe0\xa8\xb8\xe0\xa8\xbc\0" /* offset 1855 */ + "\xe0\xa8\x96\xe0\xa8\xbc\0" /* offset 1862 */ + "\xe0\xa8\x97\xe0\xa8\xbc\0" /* offset 1869 */ + "\xe0\xa8\x9c\xe0\xa8\xbc\0" /* offset 1876 */ + "\xe0\xa8\xab\xe0\xa8\xbc\0" /* offset 1883 */ + "\xe0\xad\x87\xe0\xad\x96\0" /* offset 1890 */ + "\xe0\xad\x87\xe0\xac\xbe\0" /* offset 1897 */ + "\xe0\xad\x87\xe0\xad\x97\0" /* offset 1904 */ + "\xe0\xac\xa1\xe0\xac\xbc\0" /* offset 1911 */ + "\xe0\xac\xa2\xe0\xac\xbc\0" /* offset 1918 */ + "\xe0\xae\x92\xe0\xaf\x97\0" /* offset 1925 */ + "\xe0\xaf\x86\xe0\xae\xbe\0" /* offset 1932 */ + "\xe0\xaf\x87\xe0\xae\xbe\0" /* offset 1939 */ + "\xe0\xaf\x86\xe0\xaf\x97\0" /* offset 1946 */ + "\xe0\xb1\x86\xe0\xb1\x96\0" /* offset 1953 */ + "\xe0\xb2\xbf\xe0\xb3\x95\0" /* offset 1960 */ + "\xe0\xb3\x86\xe0\xb3\x95\0" /* offset 1967 */ + "\xe0\xb3\x86\xe0\xb3\x96\0" /* offset 1974 */ + "\xe0\xb3\x86\xe0\xb3\x82\0" /* offset 1981 */ + "\xe0\xb3\x86\xe0\xb3\x82\xe0\xb3\x95\0" /* offset 1988 */ + "\xe0\xb5\x86\xe0\xb4\xbe\0" /* offset 1998 */ + "\xe0\xb5\x87\xe0\xb4\xbe\0" /* offset 2005 */ + "\xe0\xb5\x86\xe0\xb5\x97\0" /* offset 2012 */ + "\xe0\xb7\x99\xe0\xb7\x8a\0" /* offset 2019 */ + "\xe0\xb7\x99\xe0\xb7\x8f\0" /* offset 2026 */ + "\xe0\xb7\x99\xe0\xb7\x8f\xe0\xb7\x8a\0" /* offset 2033 */ + "\xe0\xb7\x99\xe0\xb7\x9f\0" /* offset 2043 */ + "\xe0\xb9\x8d\xe0\xb8\xb2\0" /* offset 2050 */ + "\xe0\xbb\x8d\xe0\xba\xb2\0" /* offset 2057 */ + "\xe0\xba\xab\xe0\xba\x99\0" /* offset 2064 */ + "\xe0\xba\xab\xe0\xba\xa1\0" /* offset 2071 */ + "\xe0\xbc\x8b\0" /* offset 2078 */ + "\xe0\xbd\x82\xe0\xbe\xb7\0" /* offset 2082 */ + "\xe0\xbd\x8c\xe0\xbe\xb7\0" /* offset 2089 */ + "\xe0\xbd\x91\xe0\xbe\xb7\0" /* offset 2096 */ + "\xe0\xbd\x96\xe0\xbe\xb7\0" /* offset 2103 */ + "\xe0\xbd\x9b\xe0\xbe\xb7\0" /* offset 2110 */ + "\xe0\xbd\x80\xe0\xbe\xb5\0" /* offset 2117 */ + "\xe0\xbd\xb1\xe0\xbd\xb2\0" /* offset 2124 */ + "\xe0\xbd\xb1\xe0\xbd\xb4\0" /* offset 2131 */ + "\xe0\xbe\xb2\xe0\xbe\x80\0" /* offset 2138 */ + "\xe0\xbe\xb2\xe0\xbd\xb1\xe0\xbe\x80\0" /* offset 2145 */ + "\xe0\xbe\xb3\xe0\xbe\x80\0" /* offset 2155 */ + "\xe0\xbe\xb3\xe0\xbd\xb1\xe0\xbe\x80\0" /* offset 2162 */ + "\xe0\xbd\xb1\xe0\xbe\x80\0" /* offset 2172 */ + "\xe0\xbe\x92\xe0\xbe\xb7\0" /* offset 2179 */ + "\xe0\xbe\x9c\xe0\xbe\xb7\0" /* offset 2186 */ + "\xe0\xbe\xa1\xe0\xbe\xb7\0" /* offset 2193 */ + "\xe0\xbe\xa6\xe0\xbe\xb7\0" /* offset 2200 */ + "\xe0\xbe\xab\xe0\xbe\xb7\0" /* offset 2207 */ + "\xe0\xbe\x90\xe0\xbe\xb5\0" /* offset 2214 */ + "\xe1\x80\xa5\xe1\x80\xae\0" /* offset 2221 */ + "\xe1\x83\x9c\0" /* offset 2228 */ + "\xe1\xac\x85\xe1\xac\xb5\0" /* offset 2232 */ + "\xe1\xac\x87\xe1\xac\xb5\0" /* offset 2239 */ + "\xe1\xac\x89\xe1\xac\xb5\0" /* offset 2246 */ + "\xe1\xac\x8b\xe1\xac\xb5\0" /* offset 2253 */ + "\xe1\xac\x8d\xe1\xac\xb5\0" /* offset 2260 */ + "\xe1\xac\x91\xe1\xac\xb5\0" /* offset 2267 */ + "\xe1\xac\xba\xe1\xac\xb5\0" /* offset 2274 */ + "\xe1\xac\xbc\xe1\xac\xb5\0" /* offset 2281 */ + "\xe1\xac\xbe\xe1\xac\xb5\0" /* offset 2288 */ + "\xe1\xac\xbf\xe1\xac\xb5\0" /* offset 2295 */ + "\xe1\xad\x82\xe1\xac\xb5\0" /* offset 2302 */ + "\x41\0" /* offset 2309 */ + "\xc3\x86\0" /* offset 2311 */ + "\x42\0" /* offset 2314 */ + "\x44\0" /* offset 2316 */ + "\x45\0" /* offset 2318 */ + "\xc6\x8e\0" /* offset 2320 */ + "\x47\0" /* offset 2323 */ + "\x48\0" /* offset 2325 */ + "\x49\0" /* offset 2327 */ + "\x4a\0" /* offset 2329 */ + "\x4b\0" /* offset 2331 */ + "\x4c\0" /* offset 2333 */ + "\x4d\0" /* offset 2335 */ + "\x4e\0" /* offset 2337 */ + "\x4f\0" /* offset 2339 */ + "\xc8\xa2\0" /* offset 2341 */ + "\x50\0" /* offset 2344 */ + "\x52\0" /* offset 2346 */ + "\x54\0" /* offset 2348 */ + "\x55\0" /* offset 2350 */ + "\x57\0" /* offset 2352 */ + "\xc9\x90\0" /* offset 2354 */ + "\xc9\x91\0" /* offset 2357 */ + "\xe1\xb4\x82\0" /* offset 2360 */ + "\x62\0" /* offset 2364 */ + "\x64\0" /* offset 2366 */ + "\x65\0" /* offset 2368 */ + "\xc9\x99\0" /* offset 2370 */ + "\xc9\x9b\0" /* offset 2373 */ + "\xc9\x9c\0" /* offset 2376 */ + "\x67\0" /* offset 2379 */ + "\x6b\0" /* offset 2381 */ + "\x6d\0" /* offset 2383 */ + "\xc5\x8b\0" /* offset 2385 */ + "\xc9\x94\0" /* offset 2388 */ + "\xe1\xb4\x96\0" /* offset 2391 */ + "\xe1\xb4\x97\0" /* offset 2395 */ + "\x70\0" /* offset 2399 */ + "\x74\0" /* offset 2401 */ + "\x75\0" /* offset 2403 */ + "\xe1\xb4\x9d\0" /* offset 2405 */ + "\xc9\xaf\0" /* offset 2409 */ + "\x76\0" /* offset 2412 */ + "\xe1\xb4\xa5\0" /* offset 2414 */ + "\xce\xb3\0" /* offset 2418 */ + "\xce\xb4\0" /* offset 2421 */ + "\xcf\x87\0" /* offset 2424 */ + "\x69\0" /* offset 2427 */ + "\xd0\xbd\0" /* offset 2429 */ + "\xc9\x92\0" /* offset 2432 */ + "\x63\0" /* offset 2435 */ + "\xc9\x95\0" /* offset 2437 */ + "\xc3\xb0\0" /* offset 2440 */ + "\x66\0" /* offset 2443 */ + "\xc9\x9f\0" /* offset 2445 */ + "\xc9\xa1\0" /* offset 2448 */ + "\xc9\xa5\0" /* offset 2451 */ + "\xc9\xa8\0" /* offset 2454 */ + "\xc9\xa9\0" /* offset 2457 */ + "\xc9\xaa\0" /* offset 2460 */ + "\xe1\xb5\xbb\0" /* offset 2463 */ + "\xca\x9d\0" /* offset 2467 */ + "\xc9\xad\0" /* offset 2470 */ + "\xe1\xb6\x85\0" /* offset 2473 */ + "\xca\x9f\0" /* offset 2477 */ + "\xc9\xb1\0" /* offset 2480 */ + "\xc9\xb0\0" /* offset 2483 */ + "\xc9\xb2\0" /* offset 2486 */ + "\xc9\xb3\0" /* offset 2489 */ + "\xc9\xb4\0" /* offset 2492 */ + "\xc9\xb5\0" /* offset 2495 */ + "\xc9\xb8\0" /* offset 2498 */ + "\xca\x82\0" /* offset 2501 */ + "\xca\x83\0" /* offset 2504 */ + "\xc6\xab\0" /* offset 2507 */ + "\xca\x89\0" /* offset 2510 */ + "\xca\x8a\0" /* offset 2513 */ + "\xe1\xb4\x9c\0" /* offset 2516 */ + "\xca\x8b\0" /* offset 2520 */ + "\xca\x8c\0" /* offset 2523 */ + "\x7a\0" /* offset 2526 */ + "\xca\x90\0" /* offset 2528 */ + "\xca\x91\0" /* offset 2531 */ + "\xca\x92\0" /* offset 2534 */ + "\x41\xcc\xa5\0" /* offset 2537 */ + "\x61\xcc\xa5\0" /* offset 2541 */ + "\x42\xcc\x87\0" /* offset 2545 */ + "\x62\xcc\x87\0" /* offset 2549 */ + "\x42\xcc\xa3\0" /* offset 2553 */ + "\x62\xcc\xa3\0" /* offset 2557 */ + "\x42\xcc\xb1\0" /* offset 2561 */ + "\x62\xcc\xb1\0" /* offset 2565 */ + "\x43\xcc\xa7\xcc\x81\0" /* offset 2569 */ + "\x63\xcc\xa7\xcc\x81\0" /* offset 2575 */ + "\x44\xcc\x87\0" /* offset 2581 */ + "\x64\xcc\x87\0" /* offset 2585 */ + "\x44\xcc\xa3\0" /* offset 2589 */ + "\x64\xcc\xa3\0" /* offset 2593 */ + "\x44\xcc\xb1\0" /* offset 2597 */ + "\x64\xcc\xb1\0" /* offset 2601 */ + "\x44\xcc\xa7\0" /* offset 2605 */ + "\x64\xcc\xa7\0" /* offset 2609 */ + "\x44\xcc\xad\0" /* offset 2613 */ + "\x64\xcc\xad\0" /* offset 2617 */ + "\x45\xcc\x84\xcc\x80\0" /* offset 2621 */ + "\x65\xcc\x84\xcc\x80\0" /* offset 2627 */ + "\x45\xcc\x84\xcc\x81\0" /* offset 2633 */ + "\x65\xcc\x84\xcc\x81\0" /* offset 2639 */ + "\x45\xcc\xad\0" /* offset 2645 */ + "\x65\xcc\xad\0" /* offset 2649 */ + "\x45\xcc\xb0\0" /* offset 2653 */ + "\x65\xcc\xb0\0" /* offset 2657 */ + "\x45\xcc\xa7\xcc\x86\0" /* offset 2661 */ + "\x65\xcc\xa7\xcc\x86\0" /* offset 2667 */ + "\x46\xcc\x87\0" /* offset 2673 */ + "\x66\xcc\x87\0" /* offset 2677 */ + "\x47\xcc\x84\0" /* offset 2681 */ + "\x67\xcc\x84\0" /* offset 2685 */ + "\x48\xcc\x87\0" /* offset 2689 */ + "\x68\xcc\x87\0" /* offset 2693 */ + "\x48\xcc\xa3\0" /* offset 2697 */ + "\x68\xcc\xa3\0" /* offset 2701 */ + "\x48\xcc\x88\0" /* offset 2705 */ + "\x68\xcc\x88\0" /* offset 2709 */ + "\x48\xcc\xa7\0" /* offset 2713 */ + "\x68\xcc\xa7\0" /* offset 2717 */ + "\x48\xcc\xae\0" /* offset 2721 */ + "\x68\xcc\xae\0" /* offset 2725 */ + "\x49\xcc\xb0\0" /* offset 2729 */ + "\x69\xcc\xb0\0" /* offset 2733 */ + "\x49\xcc\x88\xcc\x81\0" /* offset 2737 */ + "\x69\xcc\x88\xcc\x81\0" /* offset 2743 */ + "\x4b\xcc\x81\0" /* offset 2749 */ + "\x6b\xcc\x81\0" /* offset 2753 */ + "\x4b\xcc\xa3\0" /* offset 2757 */ + "\x6b\xcc\xa3\0" /* offset 2761 */ + "\x4b\xcc\xb1\0" /* offset 2765 */ + "\x6b\xcc\xb1\0" /* offset 2769 */ + "\x4c\xcc\xa3\0" /* offset 2773 */ + "\x6c\xcc\xa3\0" /* offset 2777 */ + "\x4c\xcc\xa3\xcc\x84\0" /* offset 2781 */ + "\x6c\xcc\xa3\xcc\x84\0" /* offset 2787 */ + "\x4c\xcc\xb1\0" /* offset 2793 */ + "\x6c\xcc\xb1\0" /* offset 2797 */ + "\x4c\xcc\xad\0" /* offset 2801 */ + "\x6c\xcc\xad\0" /* offset 2805 */ + "\x4d\xcc\x81\0" /* offset 2809 */ + "\x6d\xcc\x81\0" /* offset 2813 */ + "\x4d\xcc\x87\0" /* offset 2817 */ + "\x6d\xcc\x87\0" /* offset 2821 */ + "\x4d\xcc\xa3\0" /* offset 2825 */ + "\x6d\xcc\xa3\0" /* offset 2829 */ + "\x4e\xcc\x87\0" /* offset 2833 */ + "\x6e\xcc\x87\0" /* offset 2837 */ + "\x4e\xcc\xa3\0" /* offset 2841 */ + "\x6e\xcc\xa3\0" /* offset 2845 */ + "\x4e\xcc\xb1\0" /* offset 2849 */ + "\x6e\xcc\xb1\0" /* offset 2853 */ + "\x4e\xcc\xad\0" /* offset 2857 */ + "\x6e\xcc\xad\0" /* offset 2861 */ + "\x4f\xcc\x83\xcc\x81\0" /* offset 2865 */ + "\x6f\xcc\x83\xcc\x81\0" /* offset 2871 */ + "\x4f\xcc\x83\xcc\x88\0" /* offset 2877 */ + "\x6f\xcc\x83\xcc\x88\0" /* offset 2883 */ + "\x4f\xcc\x84\xcc\x80\0" /* offset 2889 */ + "\x6f\xcc\x84\xcc\x80\0" /* offset 2895 */ + "\x4f\xcc\x84\xcc\x81\0" /* offset 2901 */ + "\x6f\xcc\x84\xcc\x81\0" /* offset 2907 */ + "\x50\xcc\x81\0" /* offset 2913 */ + "\x70\xcc\x81\0" /* offset 2917 */ + "\x50\xcc\x87\0" /* offset 2921 */ + "\x70\xcc\x87\0" /* offset 2925 */ + "\x52\xcc\x87\0" /* offset 2929 */ + "\x72\xcc\x87\0" /* offset 2933 */ + "\x52\xcc\xa3\0" /* offset 2937 */ + "\x72\xcc\xa3\0" /* offset 2941 */ + "\x52\xcc\xa3\xcc\x84\0" /* offset 2945 */ + "\x72\xcc\xa3\xcc\x84\0" /* offset 2951 */ + "\x52\xcc\xb1\0" /* offset 2957 */ + "\x72\xcc\xb1\0" /* offset 2961 */ + "\x53\xcc\x87\0" /* offset 2965 */ + "\x73\xcc\x87\0" /* offset 2969 */ + "\x53\xcc\xa3\0" /* offset 2973 */ + "\x73\xcc\xa3\0" /* offset 2977 */ + "\x53\xcc\x81\xcc\x87\0" /* offset 2981 */ + "\x73\xcc\x81\xcc\x87\0" /* offset 2987 */ + "\x53\xcc\x8c\xcc\x87\0" /* offset 2993 */ + "\x73\xcc\x8c\xcc\x87\0" /* offset 2999 */ + "\x53\xcc\xa3\xcc\x87\0" /* offset 3005 */ + "\x73\xcc\xa3\xcc\x87\0" /* offset 3011 */ + "\x54\xcc\x87\0" /* offset 3017 */ + "\x74\xcc\x87\0" /* offset 3021 */ + "\x54\xcc\xa3\0" /* offset 3025 */ + "\x74\xcc\xa3\0" /* offset 3029 */ + "\x54\xcc\xb1\0" /* offset 3033 */ + "\x74\xcc\xb1\0" /* offset 3037 */ + "\x54\xcc\xad\0" /* offset 3041 */ + "\x74\xcc\xad\0" /* offset 3045 */ + "\x55\xcc\xa4\0" /* offset 3049 */ + "\x75\xcc\xa4\0" /* offset 3053 */ + "\x55\xcc\xb0\0" /* offset 3057 */ + "\x75\xcc\xb0\0" /* offset 3061 */ + "\x55\xcc\xad\0" /* offset 3065 */ + "\x75\xcc\xad\0" /* offset 3069 */ + "\x55\xcc\x83\xcc\x81\0" /* offset 3073 */ + "\x75\xcc\x83\xcc\x81\0" /* offset 3079 */ + "\x55\xcc\x84\xcc\x88\0" /* offset 3085 */ + "\x75\xcc\x84\xcc\x88\0" /* offset 3091 */ + "\x56\xcc\x83\0" /* offset 3097 */ + "\x76\xcc\x83\0" /* offset 3101 */ + "\x56\xcc\xa3\0" /* offset 3105 */ + "\x76\xcc\xa3\0" /* offset 3109 */ + "\x57\xcc\x80\0" /* offset 3113 */ + "\x77\xcc\x80\0" /* offset 3117 */ + "\x57\xcc\x81\0" /* offset 3121 */ + "\x77\xcc\x81\0" /* offset 3125 */ + "\x57\xcc\x88\0" /* offset 3129 */ + "\x77\xcc\x88\0" /* offset 3133 */ + "\x57\xcc\x87\0" /* offset 3137 */ + "\x77\xcc\x87\0" /* offset 3141 */ + "\x57\xcc\xa3\0" /* offset 3145 */ + "\x77\xcc\xa3\0" /* offset 3149 */ + "\x58\xcc\x87\0" /* offset 3153 */ + "\x78\xcc\x87\0" /* offset 3157 */ + "\x58\xcc\x88\0" /* offset 3161 */ + "\x78\xcc\x88\0" /* offset 3165 */ + "\x59\xcc\x87\0" /* offset 3169 */ + "\x79\xcc\x87\0" /* offset 3173 */ + "\x5a\xcc\x82\0" /* offset 3177 */ + "\x7a\xcc\x82\0" /* offset 3181 */ + "\x5a\xcc\xa3\0" /* offset 3185 */ + "\x7a\xcc\xa3\0" /* offset 3189 */ + "\x5a\xcc\xb1\0" /* offset 3193 */ + "\x7a\xcc\xb1\0" /* offset 3197 */ + "\x68\xcc\xb1\0" /* offset 3201 */ + "\x74\xcc\x88\0" /* offset 3205 */ + "\x77\xcc\x8a\0" /* offset 3209 */ + "\x79\xcc\x8a\0" /* offset 3213 */ + "\x61\xca\xbe\0" /* offset 3217 */ + "\xc5\xbf\xcc\x87\0" /* offset 3221 */ + "\x41\xcc\xa3\0" /* offset 3226 */ + "\x61\xcc\xa3\0" /* offset 3230 */ + "\x41\xcc\x89\0" /* offset 3234 */ + "\x61\xcc\x89\0" /* offset 3238 */ + "\x41\xcc\x82\xcc\x81\0" /* offset 3242 */ + "\x61\xcc\x82\xcc\x81\0" /* offset 3248 */ + "\x41\xcc\x82\xcc\x80\0" /* offset 3254 */ + "\x61\xcc\x82\xcc\x80\0" /* offset 3260 */ + "\x41\xcc\x82\xcc\x89\0" /* offset 3266 */ + "\x61\xcc\x82\xcc\x89\0" /* offset 3272 */ + "\x41\xcc\x82\xcc\x83\0" /* offset 3278 */ + "\x61\xcc\x82\xcc\x83\0" /* offset 3284 */ + "\x41\xcc\xa3\xcc\x82\0" /* offset 3290 */ + "\x61\xcc\xa3\xcc\x82\0" /* offset 3296 */ + "\x41\xcc\x86\xcc\x81\0" /* offset 3302 */ + "\x61\xcc\x86\xcc\x81\0" /* offset 3308 */ + "\x41\xcc\x86\xcc\x80\0" /* offset 3314 */ + "\x61\xcc\x86\xcc\x80\0" /* offset 3320 */ + "\x41\xcc\x86\xcc\x89\0" /* offset 3326 */ + "\x61\xcc\x86\xcc\x89\0" /* offset 3332 */ + "\x41\xcc\x86\xcc\x83\0" /* offset 3338 */ + "\x61\xcc\x86\xcc\x83\0" /* offset 3344 */ + "\x41\xcc\xa3\xcc\x86\0" /* offset 3350 */ + "\x61\xcc\xa3\xcc\x86\0" /* offset 3356 */ + "\x45\xcc\xa3\0" /* offset 3362 */ + "\x65\xcc\xa3\0" /* offset 3366 */ + "\x45\xcc\x89\0" /* offset 3370 */ + "\x65\xcc\x89\0" /* offset 3374 */ + "\x45\xcc\x83\0" /* offset 3378 */ + "\x65\xcc\x83\0" /* offset 3382 */ + "\x45\xcc\x82\xcc\x81\0" /* offset 3386 */ + "\x65\xcc\x82\xcc\x81\0" /* offset 3392 */ + "\x45\xcc\x82\xcc\x80\0" /* offset 3398 */ + "\x65\xcc\x82\xcc\x80\0" /* offset 3404 */ + "\x45\xcc\x82\xcc\x89\0" /* offset 3410 */ + "\x65\xcc\x82\xcc\x89\0" /* offset 3416 */ + "\x45\xcc\x82\xcc\x83\0" /* offset 3422 */ + "\x65\xcc\x82\xcc\x83\0" /* offset 3428 */ + "\x45\xcc\xa3\xcc\x82\0" /* offset 3434 */ + "\x65\xcc\xa3\xcc\x82\0" /* offset 3440 */ + "\x49\xcc\x89\0" /* offset 3446 */ + "\x69\xcc\x89\0" /* offset 3450 */ + "\x49\xcc\xa3\0" /* offset 3454 */ + "\x69\xcc\xa3\0" /* offset 3458 */ + "\x4f\xcc\xa3\0" /* offset 3462 */ + "\x6f\xcc\xa3\0" /* offset 3466 */ + "\x4f\xcc\x89\0" /* offset 3470 */ + "\x6f\xcc\x89\0" /* offset 3474 */ + "\x4f\xcc\x82\xcc\x81\0" /* offset 3478 */ + "\x6f\xcc\x82\xcc\x81\0" /* offset 3484 */ + "\x4f\xcc\x82\xcc\x80\0" /* offset 3490 */ + "\x6f\xcc\x82\xcc\x80\0" /* offset 3496 */ + "\x4f\xcc\x82\xcc\x89\0" /* offset 3502 */ + "\x6f\xcc\x82\xcc\x89\0" /* offset 3508 */ + "\x4f\xcc\x82\xcc\x83\0" /* offset 3514 */ + "\x6f\xcc\x82\xcc\x83\0" /* offset 3520 */ + "\x4f\xcc\xa3\xcc\x82\0" /* offset 3526 */ + "\x6f\xcc\xa3\xcc\x82\0" /* offset 3532 */ + "\x4f\xcc\x9b\xcc\x81\0" /* offset 3538 */ + "\x6f\xcc\x9b\xcc\x81\0" /* offset 3544 */ + "\x4f\xcc\x9b\xcc\x80\0" /* offset 3550 */ + "\x6f\xcc\x9b\xcc\x80\0" /* offset 3556 */ + "\x4f\xcc\x9b\xcc\x89\0" /* offset 3562 */ + "\x6f\xcc\x9b\xcc\x89\0" /* offset 3568 */ + "\x4f\xcc\x9b\xcc\x83\0" /* offset 3574 */ + "\x6f\xcc\x9b\xcc\x83\0" /* offset 3580 */ + "\x4f\xcc\x9b\xcc\xa3\0" /* offset 3586 */ + "\x6f\xcc\x9b\xcc\xa3\0" /* offset 3592 */ + "\x55\xcc\xa3\0" /* offset 3598 */ + "\x75\xcc\xa3\0" /* offset 3602 */ + "\x55\xcc\x89\0" /* offset 3606 */ + "\x75\xcc\x89\0" /* offset 3610 */ + "\x55\xcc\x9b\xcc\x81\0" /* offset 3614 */ + "\x75\xcc\x9b\xcc\x81\0" /* offset 3620 */ + "\x55\xcc\x9b\xcc\x80\0" /* offset 3626 */ + "\x75\xcc\x9b\xcc\x80\0" /* offset 3632 */ + "\x55\xcc\x9b\xcc\x89\0" /* offset 3638 */ + "\x75\xcc\x9b\xcc\x89\0" /* offset 3644 */ + "\x55\xcc\x9b\xcc\x83\0" /* offset 3650 */ + "\x75\xcc\x9b\xcc\x83\0" /* offset 3656 */ + "\x55\xcc\x9b\xcc\xa3\0" /* offset 3662 */ + "\x75\xcc\x9b\xcc\xa3\0" /* offset 3668 */ + "\x59\xcc\x80\0" /* offset 3674 */ + "\x79\xcc\x80\0" /* offset 3678 */ + "\x59\xcc\xa3\0" /* offset 3682 */ + "\x79\xcc\xa3\0" /* offset 3686 */ + "\x59\xcc\x89\0" /* offset 3690 */ + "\x79\xcc\x89\0" /* offset 3694 */ + "\x59\xcc\x83\0" /* offset 3698 */ + "\x79\xcc\x83\0" /* offset 3702 */ + "\xce\xb1\xcc\x93\0" /* offset 3706 */ + "\xce\xb1\xcc\x94\0" /* offset 3711 */ + "\xce\xb1\xcc\x93\xcc\x80\0" /* offset 3716 */ + "\xce\xb1\xcc\x94\xcc\x80\0" /* offset 3723 */ + "\xce\xb1\xcc\x93\xcc\x81\0" /* offset 3730 */ + "\xce\xb1\xcc\x94\xcc\x81\0" /* offset 3737 */ + "\xce\xb1\xcc\x93\xcd\x82\0" /* offset 3744 */ + "\xce\xb1\xcc\x94\xcd\x82\0" /* offset 3751 */ + "\xce\x91\xcc\x93\0" /* offset 3758 */ + "\xce\x91\xcc\x94\0" /* offset 3763 */ + "\xce\x91\xcc\x93\xcc\x80\0" /* offset 3768 */ + "\xce\x91\xcc\x94\xcc\x80\0" /* offset 3775 */ + "\xce\x91\xcc\x93\xcc\x81\0" /* offset 3782 */ + "\xce\x91\xcc\x94\xcc\x81\0" /* offset 3789 */ + "\xce\x91\xcc\x93\xcd\x82\0" /* offset 3796 */ + "\xce\x91\xcc\x94\xcd\x82\0" /* offset 3803 */ + "\xce\xb5\xcc\x93\0" /* offset 3810 */ + "\xce\xb5\xcc\x94\0" /* offset 3815 */ + "\xce\xb5\xcc\x93\xcc\x80\0" /* offset 3820 */ + "\xce\xb5\xcc\x94\xcc\x80\0" /* offset 3827 */ + "\xce\xb5\xcc\x93\xcc\x81\0" /* offset 3834 */ + "\xce\xb5\xcc\x94\xcc\x81\0" /* offset 3841 */ + "\xce\x95\xcc\x93\0" /* offset 3848 */ + "\xce\x95\xcc\x94\0" /* offset 3853 */ + "\xce\x95\xcc\x93\xcc\x80\0" /* offset 3858 */ + "\xce\x95\xcc\x94\xcc\x80\0" /* offset 3865 */ + "\xce\x95\xcc\x93\xcc\x81\0" /* offset 3872 */ + "\xce\x95\xcc\x94\xcc\x81\0" /* offset 3879 */ + "\xce\xb7\xcc\x93\0" /* offset 3886 */ + "\xce\xb7\xcc\x94\0" /* offset 3891 */ + "\xce\xb7\xcc\x93\xcc\x80\0" /* offset 3896 */ + "\xce\xb7\xcc\x94\xcc\x80\0" /* offset 3903 */ + "\xce\xb7\xcc\x93\xcc\x81\0" /* offset 3910 */ + "\xce\xb7\xcc\x94\xcc\x81\0" /* offset 3917 */ + "\xce\xb7\xcc\x93\xcd\x82\0" /* offset 3924 */ + "\xce\xb7\xcc\x94\xcd\x82\0" /* offset 3931 */ + "\xce\x97\xcc\x93\0" /* offset 3938 */ + "\xce\x97\xcc\x94\0" /* offset 3943 */ + "\xce\x97\xcc\x93\xcc\x80\0" /* offset 3948 */ + "\xce\x97\xcc\x94\xcc\x80\0" /* offset 3955 */ + "\xce\x97\xcc\x93\xcc\x81\0" /* offset 3962 */ + "\xce\x97\xcc\x94\xcc\x81\0" /* offset 3969 */ + "\xce\x97\xcc\x93\xcd\x82\0" /* offset 3976 */ + "\xce\x97\xcc\x94\xcd\x82\0" /* offset 3983 */ + "\xce\xb9\xcc\x93\0" /* offset 3990 */ + "\xce\xb9\xcc\x94\0" /* offset 3995 */ + "\xce\xb9\xcc\x93\xcc\x80\0" /* offset 4000 */ + "\xce\xb9\xcc\x94\xcc\x80\0" /* offset 4007 */ + "\xce\xb9\xcc\x93\xcc\x81\0" /* offset 4014 */ + "\xce\xb9\xcc\x94\xcc\x81\0" /* offset 4021 */ + "\xce\xb9\xcc\x93\xcd\x82\0" /* offset 4028 */ + "\xce\xb9\xcc\x94\xcd\x82\0" /* offset 4035 */ + "\xce\x99\xcc\x93\0" /* offset 4042 */ + "\xce\x99\xcc\x94\0" /* offset 4047 */ + "\xce\x99\xcc\x93\xcc\x80\0" /* offset 4052 */ + "\xce\x99\xcc\x94\xcc\x80\0" /* offset 4059 */ + "\xce\x99\xcc\x93\xcc\x81\0" /* offset 4066 */ + "\xce\x99\xcc\x94\xcc\x81\0" /* offset 4073 */ + "\xce\x99\xcc\x93\xcd\x82\0" /* offset 4080 */ + "\xce\x99\xcc\x94\xcd\x82\0" /* offset 4087 */ + "\xce\xbf\xcc\x93\0" /* offset 4094 */ + "\xce\xbf\xcc\x94\0" /* offset 4099 */ + "\xce\xbf\xcc\x93\xcc\x80\0" /* offset 4104 */ + "\xce\xbf\xcc\x94\xcc\x80\0" /* offset 4111 */ + "\xce\xbf\xcc\x93\xcc\x81\0" /* offset 4118 */ + "\xce\xbf\xcc\x94\xcc\x81\0" /* offset 4125 */ + "\xce\x9f\xcc\x93\0" /* offset 4132 */ + "\xce\x9f\xcc\x94\0" /* offset 4137 */ + "\xce\x9f\xcc\x93\xcc\x80\0" /* offset 4142 */ + "\xce\x9f\xcc\x94\xcc\x80\0" /* offset 4149 */ + "\xce\x9f\xcc\x93\xcc\x81\0" /* offset 4156 */ + "\xce\x9f\xcc\x94\xcc\x81\0" /* offset 4163 */ + "\xcf\x85\xcc\x93\0" /* offset 4170 */ + "\xcf\x85\xcc\x94\0" /* offset 4175 */ + "\xcf\x85\xcc\x93\xcc\x80\0" /* offset 4180 */ + "\xcf\x85\xcc\x94\xcc\x80\0" /* offset 4187 */ + "\xcf\x85\xcc\x93\xcc\x81\0" /* offset 4194 */ + "\xcf\x85\xcc\x94\xcc\x81\0" /* offset 4201 */ + "\xcf\x85\xcc\x93\xcd\x82\0" /* offset 4208 */ + "\xcf\x85\xcc\x94\xcd\x82\0" /* offset 4215 */ + "\xce\xa5\xcc\x94\0" /* offset 4222 */ + "\xce\xa5\xcc\x94\xcc\x80\0" /* offset 4227 */ + "\xce\xa5\xcc\x94\xcc\x81\0" /* offset 4234 */ + "\xce\xa5\xcc\x94\xcd\x82\0" /* offset 4241 */ + "\xcf\x89\xcc\x93\0" /* offset 4248 */ + "\xcf\x89\xcc\x94\0" /* offset 4253 */ + "\xcf\x89\xcc\x93\xcc\x80\0" /* offset 4258 */ + "\xcf\x89\xcc\x94\xcc\x80\0" /* offset 4265 */ + "\xcf\x89\xcc\x93\xcc\x81\0" /* offset 4272 */ + "\xcf\x89\xcc\x94\xcc\x81\0" /* offset 4279 */ + "\xcf\x89\xcc\x93\xcd\x82\0" /* offset 4286 */ + "\xcf\x89\xcc\x94\xcd\x82\0" /* offset 4293 */ + "\xce\xa9\xcc\x93\0" /* offset 4300 */ + "\xce\xa9\xcc\x94\0" /* offset 4305 */ + "\xce\xa9\xcc\x93\xcc\x80\0" /* offset 4310 */ + "\xce\xa9\xcc\x94\xcc\x80\0" /* offset 4317 */ + "\xce\xa9\xcc\x93\xcc\x81\0" /* offset 4324 */ + "\xce\xa9\xcc\x94\xcc\x81\0" /* offset 4331 */ + "\xce\xa9\xcc\x93\xcd\x82\0" /* offset 4338 */ + "\xce\xa9\xcc\x94\xcd\x82\0" /* offset 4345 */ + "\xce\xb1\xcc\x80\0" /* offset 4352 */ + "\xce\xb5\xcc\x80\0" /* offset 4357 */ + "\xce\xb7\xcc\x80\0" /* offset 4362 */ + "\xce\xb9\xcc\x80\0" /* offset 4367 */ + "\xce\xbf\xcc\x80\0" /* offset 4372 */ + "\xcf\x85\xcc\x80\0" /* offset 4377 */ + "\xcf\x89\xcc\x80\0" /* offset 4382 */ + "\xce\xb1\xcc\x93\xcd\x85\0" /* offset 4387 */ + "\xce\xb1\xcc\x94\xcd\x85\0" /* offset 4394 */ + "\xce\xb1\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4401 */ + "\xce\xb1\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4410 */ + "\xce\xb1\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4419 */ + "\xce\xb1\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4428 */ + "\xce\xb1\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4437 */ + "\xce\xb1\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4446 */ + "\xce\x91\xcc\x93\xcd\x85\0" /* offset 4455 */ + "\xce\x91\xcc\x94\xcd\x85\0" /* offset 4462 */ + "\xce\x91\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4469 */ + "\xce\x91\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4478 */ + "\xce\x91\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4487 */ + "\xce\x91\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4496 */ + "\xce\x91\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4505 */ + "\xce\x91\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4514 */ + "\xce\xb7\xcc\x93\xcd\x85\0" /* offset 4523 */ + "\xce\xb7\xcc\x94\xcd\x85\0" /* offset 4530 */ + "\xce\xb7\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4537 */ + "\xce\xb7\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4546 */ + "\xce\xb7\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4555 */ + "\xce\xb7\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4564 */ + "\xce\xb7\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4573 */ + "\xce\xb7\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4582 */ + "\xce\x97\xcc\x93\xcd\x85\0" /* offset 4591 */ + "\xce\x97\xcc\x94\xcd\x85\0" /* offset 4598 */ + "\xce\x97\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4605 */ + "\xce\x97\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4614 */ + "\xce\x97\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4623 */ + "\xce\x97\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4632 */ + "\xce\x97\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4641 */ + "\xce\x97\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4650 */ + "\xcf\x89\xcc\x93\xcd\x85\0" /* offset 4659 */ + "\xcf\x89\xcc\x94\xcd\x85\0" /* offset 4666 */ + "\xcf\x89\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4673 */ + "\xcf\x89\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4682 */ + "\xcf\x89\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4691 */ + "\xcf\x89\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4700 */ + "\xcf\x89\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4709 */ + "\xcf\x89\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4718 */ + "\xce\xa9\xcc\x93\xcd\x85\0" /* offset 4727 */ + "\xce\xa9\xcc\x94\xcd\x85\0" /* offset 4734 */ + "\xce\xa9\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4741 */ + "\xce\xa9\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4750 */ + "\xce\xa9\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4759 */ + "\xce\xa9\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4768 */ + "\xce\xa9\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4777 */ + "\xce\xa9\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4786 */ + "\xce\xb1\xcc\x86\0" /* offset 4795 */ + "\xce\xb1\xcc\x84\0" /* offset 4800 */ + "\xce\xb1\xcc\x80\xcd\x85\0" /* offset 4805 */ + "\xce\xb1\xcd\x85\0" /* offset 4812 */ + "\xce\xb1\xcc\x81\xcd\x85\0" /* offset 4817 */ + "\xce\xb1\xcd\x82\0" /* offset 4824 */ + "\xce\xb1\xcd\x82\xcd\x85\0" /* offset 4829 */ + "\xce\x91\xcc\x86\0" /* offset 4836 */ + "\xce\x91\xcc\x84\0" /* offset 4841 */ + "\xce\x91\xcc\x80\0" /* offset 4846 */ + "\xce\x91\xcd\x85\0" /* offset 4851 */ + "\x20\xcc\x93\0" /* offset 4856 */ + "\xce\xb9\0" /* offset 4860 */ + "\x20\xcd\x82\0" /* offset 4863 */ + "\xc2\xa8\xcd\x82\0" /* offset 4867 */ + "\x20\xcc\x88\xcd\x82\0" /* offset 4872 */ + "\xce\xb7\xcc\x80\xcd\x85\0" /* offset 4878 */ + "\xce\xb7\xcd\x85\0" /* offset 4885 */ + "\xce\xb7\xcc\x81\xcd\x85\0" /* offset 4890 */ + "\xce\xb7\xcd\x82\0" /* offset 4897 */ + "\xce\xb7\xcd\x82\xcd\x85\0" /* offset 4902 */ + "\xce\x95\xcc\x80\0" /* offset 4909 */ + "\xce\x97\xcc\x80\0" /* offset 4914 */ + "\xce\x97\xcd\x85\0" /* offset 4919 */ + "\xe1\xbe\xbf\xcc\x80\0" /* offset 4924 */ + "\x20\xcc\x93\xcc\x80\0" /* offset 4930 */ + "\xe1\xbe\xbf\xcc\x81\0" /* offset 4936 */ + "\x20\xcc\x93\xcc\x81\0" /* offset 4942 */ + "\xe1\xbe\xbf\xcd\x82\0" /* offset 4948 */ + "\x20\xcc\x93\xcd\x82\0" /* offset 4954 */ + "\xce\xb9\xcc\x86\0" /* offset 4960 */ + "\xce\xb9\xcc\x84\0" /* offset 4965 */ + "\xce\xb9\xcc\x88\xcc\x80\0" /* offset 4970 */ + "\xce\xb9\xcd\x82\0" /* offset 4977 */ + "\xce\xb9\xcc\x88\xcd\x82\0" /* offset 4982 */ + "\xce\x99\xcc\x86\0" /* offset 4989 */ + "\xce\x99\xcc\x84\0" /* offset 4994 */ + "\xce\x99\xcc\x80\0" /* offset 4999 */ + "\xe1\xbf\xbe\xcc\x80\0" /* offset 5004 */ + "\x20\xcc\x94\xcc\x80\0" /* offset 5010 */ + "\xe1\xbf\xbe\xcc\x81\0" /* offset 5016 */ + "\x20\xcc\x94\xcc\x81\0" /* offset 5022 */ + "\xe1\xbf\xbe\xcd\x82\0" /* offset 5028 */ + "\x20\xcc\x94\xcd\x82\0" /* offset 5034 */ + "\xcf\x85\xcc\x86\0" /* offset 5040 */ + "\xcf\x85\xcc\x84\0" /* offset 5045 */ + "\xcf\x85\xcc\x88\xcc\x80\0" /* offset 5050 */ + "\xcf\x81\xcc\x93\0" /* offset 5057 */ + "\xcf\x81\xcc\x94\0" /* offset 5062 */ + "\xcf\x85\xcd\x82\0" /* offset 5067 */ + "\xcf\x85\xcc\x88\xcd\x82\0" /* offset 5072 */ + "\xce\xa5\xcc\x86\0" /* offset 5079 */ + "\xce\xa5\xcc\x84\0" /* offset 5084 */ + "\xce\xa5\xcc\x80\0" /* offset 5089 */ + "\xce\xa1\xcc\x94\0" /* offset 5094 */ + "\xc2\xa8\xcc\x80\0" /* offset 5099 */ + "\x20\xcc\x88\xcc\x80\0" /* offset 5104 */ + "\x60\0" /* offset 5110 */ + "\xcf\x89\xcc\x80\xcd\x85\0" /* offset 5112 */ + "\xcf\x89\xcd\x85\0" /* offset 5119 */ + "\xcf\x89\xcc\x81\xcd\x85\0" /* offset 5124 */ + "\xcf\x89\xcd\x82\0" /* offset 5131 */ + "\xcf\x89\xcd\x82\xcd\x85\0" /* offset 5136 */ + "\xce\x9f\xcc\x80\0" /* offset 5143 */ + "\xce\xa9\xcc\x80\0" /* offset 5148 */ + "\xce\xa9\xcd\x85\0" /* offset 5153 */ + "\xc2\xb4\0" /* offset 5158 */ + "\x20\xcc\x94\0" /* offset 5161 */ + "\xe2\x80\x82\0" /* offset 5165 */ + "\xe2\x80\x83\0" /* offset 5169 */ + "\xe2\x80\x90\0" /* offset 5173 */ + "\x20\xcc\xb3\0" /* offset 5177 */ + "\x2e\0" /* offset 5181 */ + "\x2e\x2e\0" /* offset 5183 */ + "\x2e\x2e\x2e\0" /* offset 5186 */ + "\xe2\x80\xb2\xe2\x80\xb2\0" /* offset 5190 */ + "\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2\0" /* offset 5197 */ + "\xe2\x80\xb5\xe2\x80\xb5\0" /* offset 5207 */ + "\xe2\x80\xb5\xe2\x80\xb5\xe2\x80\xb5\0" /* offset 5214 */ + "\x21\x21\0" /* offset 5224 */ + "\x20\xcc\x85\0" /* offset 5227 */ + "\x3f\x3f\0" /* offset 5231 */ + "\x3f\x21\0" /* offset 5234 */ + "\x21\x3f\0" /* offset 5237 */ + "\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2\0" /* offset 5240 */ + "\x30\0" /* offset 5253 */ + "\x34\0" /* offset 5255 */ + "\x35\0" /* offset 5257 */ + "\x36\0" /* offset 5259 */ + "\x37\0" /* offset 5261 */ + "\x38\0" /* offset 5263 */ + "\x39\0" /* offset 5265 */ + "\x2b\0" /* offset 5267 */ + "\xe2\x88\x92\0" /* offset 5269 */ + "\x3d\0" /* offset 5273 */ + "\x28\0" /* offset 5275 */ + "\x29\0" /* offset 5277 */ + "\x6e\0" /* offset 5279 */ + "\x52\x73\0" /* offset 5281 */ + "\x61\x2f\x63\0" /* offset 5284 */ + "\x61\x2f\x73\0" /* offset 5288 */ + "\x43\0" /* offset 5292 */ + "\xc2\xb0\x43\0" /* offset 5294 */ + "\x63\x2f\x6f\0" /* offset 5298 */ + "\x63\x2f\x75\0" /* offset 5302 */ + "\xc6\x90\0" /* offset 5306 */ + "\xc2\xb0\x46\0" /* offset 5309 */ + "\xc4\xa7\0" /* offset 5313 */ + "\x4e\x6f\0" /* offset 5316 */ + "\x51\0" /* offset 5319 */ + "\x53\x4d\0" /* offset 5321 */ + "\x54\x45\x4c\0" /* offset 5324 */ + "\x54\x4d\0" /* offset 5328 */ + "\x5a\0" /* offset 5331 */ + "\xce\xa9\0" /* offset 5333 */ + "\x46\0" /* offset 5336 */ + "\xd7\x90\0" /* offset 5338 */ + "\xd7\x91\0" /* offset 5341 */ + "\xd7\x92\0" /* offset 5344 */ + "\xd7\x93\0" /* offset 5347 */ + "\x46\x41\x58\0" /* offset 5350 */ + "\xce\x93\0" /* offset 5354 */ + "\xce\xa0\0" /* offset 5357 */ + "\xe2\x88\x91\0" /* offset 5360 */ + "\x31\xe2\x81\x84\x37\0" /* offset 5364 */ + "\x31\xe2\x81\x84\x39\0" /* offset 5370 */ + "\x31\xe2\x81\x84\x31\x30\0" /* offset 5376 */ + "\x31\xe2\x81\x84\x33\0" /* offset 5383 */ + "\x32\xe2\x81\x84\x33\0" /* offset 5389 */ + "\x31\xe2\x81\x84\x35\0" /* offset 5395 */ + "\x32\xe2\x81\x84\x35\0" /* offset 5401 */ + "\x33\xe2\x81\x84\x35\0" /* offset 5407 */ + "\x34\xe2\x81\x84\x35\0" /* offset 5413 */ + "\x31\xe2\x81\x84\x36\0" /* offset 5419 */ + "\x35\xe2\x81\x84\x36\0" /* offset 5425 */ + "\x31\xe2\x81\x84\x38\0" /* offset 5431 */ + "\x33\xe2\x81\x84\x38\0" /* offset 5437 */ + "\x35\xe2\x81\x84\x38\0" /* offset 5443 */ + "\x37\xe2\x81\x84\x38\0" /* offset 5449 */ + "\x31\xe2\x81\x84\0" /* offset 5455 */ + "\x49\x49\0" /* offset 5460 */ + "\x49\x49\x49\0" /* offset 5463 */ + "\x49\x56\0" /* offset 5467 */ + "\x56\0" /* offset 5470 */ + "\x56\x49\0" /* offset 5472 */ + "\x56\x49\x49\0" /* offset 5475 */ + "\x56\x49\x49\x49\0" /* offset 5479 */ + "\x49\x58\0" /* offset 5484 */ + "\x58\0" /* offset 5487 */ + "\x58\x49\0" /* offset 5489 */ + "\x58\x49\x49\0" /* offset 5492 */ + "\x69\x69\0" /* offset 5496 */ + "\x69\x69\x69\0" /* offset 5499 */ + "\x69\x76\0" /* offset 5503 */ + "\x76\x69\0" /* offset 5506 */ + "\x76\x69\x69\0" /* offset 5509 */ + "\x76\x69\x69\x69\0" /* offset 5513 */ + "\x69\x78\0" /* offset 5518 */ + "\x78\x69\0" /* offset 5521 */ + "\x78\x69\x69\0" /* offset 5524 */ + "\x30\xe2\x81\x84\x33\0" /* offset 5528 */ + "\xe2\x86\x90\xcc\xb8\0" /* offset 5534 */ + "\xe2\x86\x92\xcc\xb8\0" /* offset 5540 */ + "\xe2\x86\x94\xcc\xb8\0" /* offset 5546 */ + "\xe2\x87\x90\xcc\xb8\0" /* offset 5552 */ + "\xe2\x87\x94\xcc\xb8\0" /* offset 5558 */ + "\xe2\x87\x92\xcc\xb8\0" /* offset 5564 */ + "\xe2\x88\x83\xcc\xb8\0" /* offset 5570 */ + "\xe2\x88\x88\xcc\xb8\0" /* offset 5576 */ + "\xe2\x88\x8b\xcc\xb8\0" /* offset 5582 */ + "\xe2\x88\xa3\xcc\xb8\0" /* offset 5588 */ + "\xe2\x88\xa5\xcc\xb8\0" /* offset 5594 */ + "\xe2\x88\xab\xe2\x88\xab\0" /* offset 5600 */ + "\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab\0" /* offset 5607 */ + "\xe2\x88\xae\xe2\x88\xae\0" /* offset 5617 */ + "\xe2\x88\xae\xe2\x88\xae\xe2\x88\xae\0" /* offset 5624 */ + "\xe2\x88\xbc\xcc\xb8\0" /* offset 5634 */ + "\xe2\x89\x83\xcc\xb8\0" /* offset 5640 */ + "\xe2\x89\x85\xcc\xb8\0" /* offset 5646 */ + "\xe2\x89\x88\xcc\xb8\0" /* offset 5652 */ + "\x3d\xcc\xb8\0" /* offset 5658 */ + "\xe2\x89\xa1\xcc\xb8\0" /* offset 5662 */ + "\xe2\x89\x8d\xcc\xb8\0" /* offset 5668 */ + "\x3c\xcc\xb8\0" /* offset 5674 */ + "\x3e\xcc\xb8\0" /* offset 5678 */ + "\xe2\x89\xa4\xcc\xb8\0" /* offset 5682 */ + "\xe2\x89\xa5\xcc\xb8\0" /* offset 5688 */ + "\xe2\x89\xb2\xcc\xb8\0" /* offset 5694 */ + "\xe2\x89\xb3\xcc\xb8\0" /* offset 5700 */ + "\xe2\x89\xb6\xcc\xb8\0" /* offset 5706 */ + "\xe2\x89\xb7\xcc\xb8\0" /* offset 5712 */ + "\xe2\x89\xba\xcc\xb8\0" /* offset 5718 */ + "\xe2\x89\xbb\xcc\xb8\0" /* offset 5724 */ + "\xe2\x8a\x82\xcc\xb8\0" /* offset 5730 */ + "\xe2\x8a\x83\xcc\xb8\0" /* offset 5736 */ + "\xe2\x8a\x86\xcc\xb8\0" /* offset 5742 */ + "\xe2\x8a\x87\xcc\xb8\0" /* offset 5748 */ + "\xe2\x8a\xa2\xcc\xb8\0" /* offset 5754 */ + "\xe2\x8a\xa8\xcc\xb8\0" /* offset 5760 */ + "\xe2\x8a\xa9\xcc\xb8\0" /* offset 5766 */ + "\xe2\x8a\xab\xcc\xb8\0" /* offset 5772 */ + "\xe2\x89\xbc\xcc\xb8\0" /* offset 5778 */ + "\xe2\x89\xbd\xcc\xb8\0" /* offset 5784 */ + "\xe2\x8a\x91\xcc\xb8\0" /* offset 5790 */ + "\xe2\x8a\x92\xcc\xb8\0" /* offset 5796 */ + "\xe2\x8a\xb2\xcc\xb8\0" /* offset 5802 */ + "\xe2\x8a\xb3\xcc\xb8\0" /* offset 5808 */ + "\xe2\x8a\xb4\xcc\xb8\0" /* offset 5814 */ + "\xe2\x8a\xb5\xcc\xb8\0" /* offset 5820 */ + "\xe3\x80\x88\0" /* offset 5826 */ + "\xe3\x80\x89\0" /* offset 5830 */ + "\x31\x30\0" /* offset 5834 */ + "\x31\x31\0" /* offset 5837 */ + "\x31\x32\0" /* offset 5840 */ + "\x31\x33\0" /* offset 5843 */ + "\x31\x34\0" /* offset 5846 */ + "\x31\x35\0" /* offset 5849 */ + "\x31\x36\0" /* offset 5852 */ + "\x31\x37\0" /* offset 5855 */ + "\x31\x38\0" /* offset 5858 */ + "\x31\x39\0" /* offset 5861 */ + "\x32\x30\0" /* offset 5864 */ + "\x28\x31\x29\0" /* offset 5867 */ + "\x28\x32\x29\0" /* offset 5871 */ + "\x28\x33\x29\0" /* offset 5875 */ + "\x28\x34\x29\0" /* offset 5879 */ + "\x28\x35\x29\0" /* offset 5883 */ + "\x28\x36\x29\0" /* offset 5887 */ + "\x28\x37\x29\0" /* offset 5891 */ + "\x28\x38\x29\0" /* offset 5895 */ + "\x28\x39\x29\0" /* offset 5899 */ + "\x28\x31\x30\x29\0" /* offset 5903 */ + "\x28\x31\x31\x29\0" /* offset 5908 */ + "\x28\x31\x32\x29\0" /* offset 5913 */ + "\x28\x31\x33\x29\0" /* offset 5918 */ + "\x28\x31\x34\x29\0" /* offset 5923 */ + "\x28\x31\x35\x29\0" /* offset 5928 */ + "\x28\x31\x36\x29\0" /* offset 5933 */ + "\x28\x31\x37\x29\0" /* offset 5938 */ + "\x28\x31\x38\x29\0" /* offset 5943 */ + "\x28\x31\x39\x29\0" /* offset 5948 */ + "\x28\x32\x30\x29\0" /* offset 5953 */ + "\x31\x2e\0" /* offset 5958 */ + "\x32\x2e\0" /* offset 5961 */ + "\x33\x2e\0" /* offset 5964 */ + "\x34\x2e\0" /* offset 5967 */ + "\x35\x2e\0" /* offset 5970 */ + "\x36\x2e\0" /* offset 5973 */ + "\x37\x2e\0" /* offset 5976 */ + "\x38\x2e\0" /* offset 5979 */ + "\x39\x2e\0" /* offset 5982 */ + "\x31\x30\x2e\0" /* offset 5985 */ + "\x31\x31\x2e\0" /* offset 5989 */ + "\x31\x32\x2e\0" /* offset 5993 */ + "\x31\x33\x2e\0" /* offset 5997 */ + "\x31\x34\x2e\0" /* offset 6001 */ + "\x31\x35\x2e\0" /* offset 6005 */ + "\x31\x36\x2e\0" /* offset 6009 */ + "\x31\x37\x2e\0" /* offset 6013 */ + "\x31\x38\x2e\0" /* offset 6017 */ + "\x31\x39\x2e\0" /* offset 6021 */ + "\x32\x30\x2e\0" /* offset 6025 */ + "\x28\x61\x29\0" /* offset 6029 */ + "\x28\x62\x29\0" /* offset 6033 */ + "\x28\x63\x29\0" /* offset 6037 */ + "\x28\x64\x29\0" /* offset 6041 */ + "\x28\x65\x29\0" /* offset 6045 */ + "\x28\x66\x29\0" /* offset 6049 */ + "\x28\x67\x29\0" /* offset 6053 */ + "\x28\x68\x29\0" /* offset 6057 */ + "\x28\x69\x29\0" /* offset 6061 */ + "\x28\x6a\x29\0" /* offset 6065 */ + "\x28\x6b\x29\0" /* offset 6069 */ + "\x28\x6c\x29\0" /* offset 6073 */ + "\x28\x6d\x29\0" /* offset 6077 */ + "\x28\x6e\x29\0" /* offset 6081 */ + "\x28\x6f\x29\0" /* offset 6085 */ + "\x28\x70\x29\0" /* offset 6089 */ + "\x28\x71\x29\0" /* offset 6093 */ + "\x28\x72\x29\0" /* offset 6097 */ + "\x28\x73\x29\0" /* offset 6101 */ + "\x28\x74\x29\0" /* offset 6105 */ + "\x28\x75\x29\0" /* offset 6109 */ + "\x28\x76\x29\0" /* offset 6113 */ + "\x28\x77\x29\0" /* offset 6117 */ + "\x28\x78\x29\0" /* offset 6121 */ + "\x28\x79\x29\0" /* offset 6125 */ + "\x28\x7a\x29\0" /* offset 6129 */ + "\x53\0" /* offset 6133 */ + "\x59\0" /* offset 6135 */ + "\x71\0" /* offset 6137 */ + "\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab\0" /* offset 6139 */ + "\x3a\x3a\x3d\0" /* offset 6152 */ + "\x3d\x3d\0" /* offset 6156 */ + "\x3d\x3d\x3d\0" /* offset 6159 */ + "\xe2\xab\x9d\xcc\xb8\0" /* offset 6163 */ + "\xe2\xb5\xa1\0" /* offset 6169 */ + "\xe6\xaf\x8d\0" /* offset 6173 */ + "\xe9\xbe\x9f\0" /* offset 6177 */ + "\xe4\xb8\x80\0" /* offset 6181 */ + "\xe4\xb8\xa8\0" /* offset 6185 */ + "\xe4\xb8\xb6\0" /* offset 6189 */ + "\xe4\xb8\xbf\0" /* offset 6193 */ + "\xe4\xb9\x99\0" /* offset 6197 */ + "\xe4\xba\x85\0" /* offset 6201 */ + "\xe4\xba\x8c\0" /* offset 6205 */ + "\xe4\xba\xa0\0" /* offset 6209 */ + "\xe4\xba\xba\0" /* offset 6213 */ + "\xe5\x84\xbf\0" /* offset 6217 */ + "\xe5\x85\xa5\0" /* offset 6221 */ + "\xe5\x85\xab\0" /* offset 6225 */ + "\xe5\x86\x82\0" /* offset 6229 */ + "\xe5\x86\x96\0" /* offset 6233 */ + "\xe5\x86\xab\0" /* offset 6237 */ + "\xe5\x87\xa0\0" /* offset 6241 */ + "\xe5\x87\xb5\0" /* offset 6245 */ + "\xe5\x88\x80\0" /* offset 6249 */ + "\xe5\x8a\x9b\0" /* offset 6253 */ + "\xe5\x8b\xb9\0" /* offset 6257 */ + "\xe5\x8c\x95\0" /* offset 6261 */ + "\xe5\x8c\x9a\0" /* offset 6265 */ + "\xe5\x8c\xb8\0" /* offset 6269 */ + "\xe5\x8d\x81\0" /* offset 6273 */ + "\xe5\x8d\x9c\0" /* offset 6277 */ + "\xe5\x8d\xa9\0" /* offset 6281 */ + "\xe5\x8e\x82\0" /* offset 6285 */ + "\xe5\x8e\xb6\0" /* offset 6289 */ + "\xe5\x8f\x88\0" /* offset 6293 */ + "\xe5\x8f\xa3\0" /* offset 6297 */ + "\xe5\x9b\x97\0" /* offset 6301 */ + "\xe5\x9c\x9f\0" /* offset 6305 */ + "\xe5\xa3\xab\0" /* offset 6309 */ + "\xe5\xa4\x82\0" /* offset 6313 */ + "\xe5\xa4\x8a\0" /* offset 6317 */ + "\xe5\xa4\x95\0" /* offset 6321 */ + "\xe5\xa4\xa7\0" /* offset 6325 */ + "\xe5\xa5\xb3\0" /* offset 6329 */ + "\xe5\xad\x90\0" /* offset 6333 */ + "\xe5\xae\x80\0" /* offset 6337 */ + "\xe5\xaf\xb8\0" /* offset 6341 */ + "\xe5\xb0\x8f\0" /* offset 6345 */ + "\xe5\xb0\xa2\0" /* offset 6349 */ + "\xe5\xb0\xb8\0" /* offset 6353 */ + "\xe5\xb1\xae\0" /* offset 6357 */ + "\xe5\xb1\xb1\0" /* offset 6361 */ + "\xe5\xb7\x9b\0" /* offset 6365 */ + "\xe5\xb7\xa5\0" /* offset 6369 */ + "\xe5\xb7\xb1\0" /* offset 6373 */ + "\xe5\xb7\xbe\0" /* offset 6377 */ + "\xe5\xb9\xb2\0" /* offset 6381 */ + "\xe5\xb9\xba\0" /* offset 6385 */ + "\xe5\xb9\xbf\0" /* offset 6389 */ + "\xe5\xbb\xb4\0" /* offset 6393 */ + "\xe5\xbb\xbe\0" /* offset 6397 */ + "\xe5\xbc\x8b\0" /* offset 6401 */ + "\xe5\xbc\x93\0" /* offset 6405 */ + "\xe5\xbd\x90\0" /* offset 6409 */ + "\xe5\xbd\xa1\0" /* offset 6413 */ + "\xe5\xbd\xb3\0" /* offset 6417 */ + "\xe5\xbf\x83\0" /* offset 6421 */ + "\xe6\x88\x88\0" /* offset 6425 */ + "\xe6\x88\xb6\0" /* offset 6429 */ + "\xe6\x89\x8b\0" /* offset 6433 */ + "\xe6\x94\xaf\0" /* offset 6437 */ + "\xe6\x94\xb4\0" /* offset 6441 */ + "\xe6\x96\x87\0" /* offset 6445 */ + "\xe6\x96\x97\0" /* offset 6449 */ + "\xe6\x96\xa4\0" /* offset 6453 */ + "\xe6\x96\xb9\0" /* offset 6457 */ + "\xe6\x97\xa0\0" /* offset 6461 */ + "\xe6\x97\xa5\0" /* offset 6465 */ + "\xe6\x9b\xb0\0" /* offset 6469 */ + "\xe6\x9c\x88\0" /* offset 6473 */ + "\xe6\x9c\xa8\0" /* offset 6477 */ + "\xe6\xac\xa0\0" /* offset 6481 */ + "\xe6\xad\xa2\0" /* offset 6485 */ + "\xe6\xad\xb9\0" /* offset 6489 */ + "\xe6\xae\xb3\0" /* offset 6493 */ + "\xe6\xaf\x8b\0" /* offset 6497 */ + "\xe6\xaf\x94\0" /* offset 6501 */ + "\xe6\xaf\x9b\0" /* offset 6505 */ + "\xe6\xb0\x8f\0" /* offset 6509 */ + "\xe6\xb0\x94\0" /* offset 6513 */ + "\xe6\xb0\xb4\0" /* offset 6517 */ + "\xe7\x81\xab\0" /* offset 6521 */ + "\xe7\x88\xaa\0" /* offset 6525 */ + "\xe7\x88\xb6\0" /* offset 6529 */ + "\xe7\x88\xbb\0" /* offset 6533 */ + "\xe7\x88\xbf\0" /* offset 6537 */ + "\xe7\x89\x87\0" /* offset 6541 */ + "\xe7\x89\x99\0" /* offset 6545 */ + "\xe7\x89\x9b\0" /* offset 6549 */ + "\xe7\x8a\xac\0" /* offset 6553 */ + "\xe7\x8e\x84\0" /* offset 6557 */ + "\xe7\x8e\x89\0" /* offset 6561 */ + "\xe7\x93\x9c\0" /* offset 6565 */ + "\xe7\x93\xa6\0" /* offset 6569 */ + "\xe7\x94\x98\0" /* offset 6573 */ + "\xe7\x94\x9f\0" /* offset 6577 */ + "\xe7\x94\xa8\0" /* offset 6581 */ + "\xe7\x94\xb0\0" /* offset 6585 */ + "\xe7\x96\x8b\0" /* offset 6589 */ + "\xe7\x96\x92\0" /* offset 6593 */ + "\xe7\x99\xb6\0" /* offset 6597 */ + "\xe7\x99\xbd\0" /* offset 6601 */ + "\xe7\x9a\xae\0" /* offset 6605 */ + "\xe7\x9a\xbf\0" /* offset 6609 */ + "\xe7\x9b\xae\0" /* offset 6613 */ + "\xe7\x9f\x9b\0" /* offset 6617 */ + "\xe7\x9f\xa2\0" /* offset 6621 */ + "\xe7\x9f\xb3\0" /* offset 6625 */ + "\xe7\xa4\xba\0" /* offset 6629 */ + "\xe7\xa6\xb8\0" /* offset 6633 */ + "\xe7\xa6\xbe\0" /* offset 6637 */ + "\xe7\xa9\xb4\0" /* offset 6641 */ + "\xe7\xab\x8b\0" /* offset 6645 */ + "\xe7\xab\xb9\0" /* offset 6649 */ + "\xe7\xb1\xb3\0" /* offset 6653 */ + "\xe7\xb3\xb8\0" /* offset 6657 */ + "\xe7\xbc\xb6\0" /* offset 6661 */ + "\xe7\xbd\x91\0" /* offset 6665 */ + "\xe7\xbe\x8a\0" /* offset 6669 */ + "\xe7\xbe\xbd\0" /* offset 6673 */ + "\xe8\x80\x81\0" /* offset 6677 */ + "\xe8\x80\x8c\0" /* offset 6681 */ + "\xe8\x80\x92\0" /* offset 6685 */ + "\xe8\x80\xb3\0" /* offset 6689 */ + "\xe8\x81\xbf\0" /* offset 6693 */ + "\xe8\x82\x89\0" /* offset 6697 */ + "\xe8\x87\xa3\0" /* offset 6701 */ + "\xe8\x87\xaa\0" /* offset 6705 */ + "\xe8\x87\xb3\0" /* offset 6709 */ + "\xe8\x87\xbc\0" /* offset 6713 */ + "\xe8\x88\x8c\0" /* offset 6717 */ + "\xe8\x88\x9b\0" /* offset 6721 */ + "\xe8\x88\x9f\0" /* offset 6725 */ + "\xe8\x89\xae\0" /* offset 6729 */ + "\xe8\x89\xb2\0" /* offset 6733 */ + "\xe8\x89\xb8\0" /* offset 6737 */ + "\xe8\x99\x8d\0" /* offset 6741 */ + "\xe8\x99\xab\0" /* offset 6745 */ + "\xe8\xa1\x80\0" /* offset 6749 */ + "\xe8\xa1\x8c\0" /* offset 6753 */ + "\xe8\xa1\xa3\0" /* offset 6757 */ + "\xe8\xa5\xbe\0" /* offset 6761 */ + "\xe8\xa6\x8b\0" /* offset 6765 */ + "\xe8\xa7\x92\0" /* offset 6769 */ + "\xe8\xa8\x80\0" /* offset 6773 */ + "\xe8\xb0\xb7\0" /* offset 6777 */ + "\xe8\xb1\x86\0" /* offset 6781 */ + "\xe8\xb1\x95\0" /* offset 6785 */ + "\xe8\xb1\xb8\0" /* offset 6789 */ + "\xe8\xb2\x9d\0" /* offset 6793 */ + "\xe8\xb5\xa4\0" /* offset 6797 */ + "\xe8\xb5\xb0\0" /* offset 6801 */ + "\xe8\xb6\xb3\0" /* offset 6805 */ + "\xe8\xba\xab\0" /* offset 6809 */ + "\xe8\xbb\x8a\0" /* offset 6813 */ + "\xe8\xbe\x9b\0" /* offset 6817 */ + "\xe8\xbe\xb0\0" /* offset 6821 */ + "\xe8\xbe\xb5\0" /* offset 6825 */ + "\xe9\x82\x91\0" /* offset 6829 */ + "\xe9\x85\x89\0" /* offset 6833 */ + "\xe9\x87\x86\0" /* offset 6837 */ + "\xe9\x87\x8c\0" /* offset 6841 */ + "\xe9\x87\x91\0" /* offset 6845 */ + "\xe9\x95\xb7\0" /* offset 6849 */ + "\xe9\x96\x80\0" /* offset 6853 */ + "\xe9\x98\x9c\0" /* offset 6857 */ + "\xe9\x9a\xb6\0" /* offset 6861 */ + "\xe9\x9a\xb9\0" /* offset 6865 */ + "\xe9\x9b\xa8\0" /* offset 6869 */ + "\xe9\x9d\x91\0" /* offset 6873 */ + "\xe9\x9d\x9e\0" /* offset 6877 */ + "\xe9\x9d\xa2\0" /* offset 6881 */ + "\xe9\x9d\xa9\0" /* offset 6885 */ + "\xe9\x9f\x8b\0" /* offset 6889 */ + "\xe9\x9f\xad\0" /* offset 6893 */ + "\xe9\x9f\xb3\0" /* offset 6897 */ + "\xe9\xa0\x81\0" /* offset 6901 */ + "\xe9\xa2\xa8\0" /* offset 6905 */ + "\xe9\xa3\x9b\0" /* offset 6909 */ + "\xe9\xa3\x9f\0" /* offset 6913 */ + "\xe9\xa6\x96\0" /* offset 6917 */ + "\xe9\xa6\x99\0" /* offset 6921 */ + "\xe9\xa6\xac\0" /* offset 6925 */ + "\xe9\xaa\xa8\0" /* offset 6929 */ + "\xe9\xab\x98\0" /* offset 6933 */ + "\xe9\xab\x9f\0" /* offset 6937 */ + "\xe9\xac\xa5\0" /* offset 6941 */ + "\xe9\xac\xaf\0" /* offset 6945 */ + "\xe9\xac\xb2\0" /* offset 6949 */ + "\xe9\xac\xbc\0" /* offset 6953 */ + "\xe9\xad\x9a\0" /* offset 6957 */ + "\xe9\xb3\xa5\0" /* offset 6961 */ + "\xe9\xb9\xb5\0" /* offset 6965 */ + "\xe9\xb9\xbf\0" /* offset 6969 */ + "\xe9\xba\xa5\0" /* offset 6973 */ + "\xe9\xba\xbb\0" /* offset 6977 */ + "\xe9\xbb\x83\0" /* offset 6981 */ + "\xe9\xbb\x8d\0" /* offset 6985 */ + "\xe9\xbb\x91\0" /* offset 6989 */ + "\xe9\xbb\xb9\0" /* offset 6993 */ + "\xe9\xbb\xbd\0" /* offset 6997 */ + "\xe9\xbc\x8e\0" /* offset 7001 */ + "\xe9\xbc\x93\0" /* offset 7005 */ + "\xe9\xbc\xa0\0" /* offset 7009 */ + "\xe9\xbc\xbb\0" /* offset 7013 */ + "\xe9\xbd\x8a\0" /* offset 7017 */ + "\xe9\xbd\x92\0" /* offset 7021 */ + "\xe9\xbe\x8d\0" /* offset 7025 */ + "\xe9\xbe\x9c\0" /* offset 7029 */ + "\xe9\xbe\xa0\0" /* offset 7033 */ + "\xe3\x80\x92\0" /* offset 7037 */ + "\xe5\x8d\x84\0" /* offset 7041 */ + "\xe5\x8d\x85\0" /* offset 7045 */ + "\xe3\x81\x8b\xe3\x82\x99\0" /* offset 7049 */ + "\xe3\x81\x8d\xe3\x82\x99\0" /* offset 7056 */ + "\xe3\x81\x8f\xe3\x82\x99\0" /* offset 7063 */ + "\xe3\x81\x91\xe3\x82\x99\0" /* offset 7070 */ + "\xe3\x81\x93\xe3\x82\x99\0" /* offset 7077 */ + "\xe3\x81\x95\xe3\x82\x99\0" /* offset 7084 */ + "\xe3\x81\x97\xe3\x82\x99\0" /* offset 7091 */ + "\xe3\x81\x99\xe3\x82\x99\0" /* offset 7098 */ + "\xe3\x81\x9b\xe3\x82\x99\0" /* offset 7105 */ + "\xe3\x81\x9d\xe3\x82\x99\0" /* offset 7112 */ + "\xe3\x81\x9f\xe3\x82\x99\0" /* offset 7119 */ + "\xe3\x81\xa1\xe3\x82\x99\0" /* offset 7126 */ + "\xe3\x81\xa4\xe3\x82\x99\0" /* offset 7133 */ + "\xe3\x81\xa6\xe3\x82\x99\0" /* offset 7140 */ + "\xe3\x81\xa8\xe3\x82\x99\0" /* offset 7147 */ + "\xe3\x81\xaf\xe3\x82\x99\0" /* offset 7154 */ + "\xe3\x81\xaf\xe3\x82\x9a\0" /* offset 7161 */ + "\xe3\x81\xb2\xe3\x82\x99\0" /* offset 7168 */ + "\xe3\x81\xb2\xe3\x82\x9a\0" /* offset 7175 */ + "\xe3\x81\xb5\xe3\x82\x99\0" /* offset 7182 */ + "\xe3\x81\xb5\xe3\x82\x9a\0" /* offset 7189 */ + "\xe3\x81\xb8\xe3\x82\x99\0" /* offset 7196 */ + "\xe3\x81\xb8\xe3\x82\x9a\0" /* offset 7203 */ + "\xe3\x81\xbb\xe3\x82\x99\0" /* offset 7210 */ + "\xe3\x81\xbb\xe3\x82\x9a\0" /* offset 7217 */ + "\xe3\x81\x86\xe3\x82\x99\0" /* offset 7224 */ + "\x20\xe3\x82\x99\0" /* offset 7231 */ + "\x20\xe3\x82\x9a\0" /* offset 7236 */ + "\xe3\x82\x9d\xe3\x82\x99\0" /* offset 7241 */ + "\xe3\x82\x88\xe3\x82\x8a\0" /* offset 7248 */ + "\xe3\x82\xab\xe3\x82\x99\0" /* offset 7255 */ + "\xe3\x82\xad\xe3\x82\x99\0" /* offset 7262 */ + "\xe3\x82\xaf\xe3\x82\x99\0" /* offset 7269 */ + "\xe3\x82\xb1\xe3\x82\x99\0" /* offset 7276 */ + "\xe3\x82\xb3\xe3\x82\x99\0" /* offset 7283 */ + "\xe3\x82\xb5\xe3\x82\x99\0" /* offset 7290 */ + "\xe3\x82\xb7\xe3\x82\x99\0" /* offset 7297 */ + "\xe3\x82\xb9\xe3\x82\x99\0" /* offset 7304 */ + "\xe3\x82\xbb\xe3\x82\x99\0" /* offset 7311 */ + "\xe3\x82\xbd\xe3\x82\x99\0" /* offset 7318 */ + "\xe3\x82\xbf\xe3\x82\x99\0" /* offset 7325 */ + "\xe3\x83\x81\xe3\x82\x99\0" /* offset 7332 */ + "\xe3\x83\x84\xe3\x82\x99\0" /* offset 7339 */ + "\xe3\x83\x86\xe3\x82\x99\0" /* offset 7346 */ + "\xe3\x83\x88\xe3\x82\x99\0" /* offset 7353 */ + "\xe3\x83\x8f\xe3\x82\x99\0" /* offset 7360 */ + "\xe3\x83\x8f\xe3\x82\x9a\0" /* offset 7367 */ + "\xe3\x83\x92\xe3\x82\x99\0" /* offset 7374 */ + "\xe3\x83\x92\xe3\x82\x9a\0" /* offset 7381 */ + "\xe3\x83\x95\xe3\x82\x99\0" /* offset 7388 */ + "\xe3\x83\x95\xe3\x82\x9a\0" /* offset 7395 */ + "\xe3\x83\x98\xe3\x82\x99\0" /* offset 7402 */ + "\xe3\x83\x98\xe3\x82\x9a\0" /* offset 7409 */ + "\xe3\x83\x9b\xe3\x82\x99\0" /* offset 7416 */ + "\xe3\x83\x9b\xe3\x82\x9a\0" /* offset 7423 */ + "\xe3\x82\xa6\xe3\x82\x99\0" /* offset 7430 */ + "\xe3\x83\xaf\xe3\x82\x99\0" /* offset 7437 */ + "\xe3\x83\xb0\xe3\x82\x99\0" /* offset 7444 */ + "\xe3\x83\xb1\xe3\x82\x99\0" /* offset 7451 */ + "\xe3\x83\xb2\xe3\x82\x99\0" /* offset 7458 */ + "\xe3\x83\xbd\xe3\x82\x99\0" /* offset 7465 */ + "\xe3\x82\xb3\xe3\x83\x88\0" /* offset 7472 */ + "\xe1\x84\x80\0" /* offset 7479 */ + "\xe1\x84\x81\0" /* offset 7483 */ + "\xe1\x86\xaa\0" /* offset 7487 */ + "\xe1\x84\x82\0" /* offset 7491 */ + "\xe1\x86\xac\0" /* offset 7495 */ + "\xe1\x86\xad\0" /* offset 7499 */ + "\xe1\x84\x83\0" /* offset 7503 */ + "\xe1\x84\x84\0" /* offset 7507 */ + "\xe1\x84\x85\0" /* offset 7511 */ + "\xe1\x86\xb0\0" /* offset 7515 */ + "\xe1\x86\xb1\0" /* offset 7519 */ + "\xe1\x86\xb2\0" /* offset 7523 */ + "\xe1\x86\xb3\0" /* offset 7527 */ + "\xe1\x86\xb4\0" /* offset 7531 */ + "\xe1\x86\xb5\0" /* offset 7535 */ + "\xe1\x84\x9a\0" /* offset 7539 */ + "\xe1\x84\x86\0" /* offset 7543 */ + "\xe1\x84\x87\0" /* offset 7547 */ + "\xe1\x84\x88\0" /* offset 7551 */ + "\xe1\x84\xa1\0" /* offset 7555 */ + "\xe1\x84\x89\0" /* offset 7559 */ + "\xe1\x84\x8a\0" /* offset 7563 */ + "\xe1\x84\x8b\0" /* offset 7567 */ + "\xe1\x84\x8c\0" /* offset 7571 */ + "\xe1\x84\x8d\0" /* offset 7575 */ + "\xe1\x84\x8e\0" /* offset 7579 */ + "\xe1\x84\x8f\0" /* offset 7583 */ + "\xe1\x84\x90\0" /* offset 7587 */ + "\xe1\x84\x91\0" /* offset 7591 */ + "\xe1\x84\x92\0" /* offset 7595 */ + "\xe1\x85\xa1\0" /* offset 7599 */ + "\xe1\x85\xa2\0" /* offset 7603 */ + "\xe1\x85\xa3\0" /* offset 7607 */ + "\xe1\x85\xa4\0" /* offset 7611 */ + "\xe1\x85\xa5\0" /* offset 7615 */ + "\xe1\x85\xa6\0" /* offset 7619 */ + "\xe1\x85\xa7\0" /* offset 7623 */ + "\xe1\x85\xa8\0" /* offset 7627 */ + "\xe1\x85\xa9\0" /* offset 7631 */ + "\xe1\x85\xaa\0" /* offset 7635 */ + "\xe1\x85\xab\0" /* offset 7639 */ + "\xe1\x85\xac\0" /* offset 7643 */ + "\xe1\x85\xad\0" /* offset 7647 */ + "\xe1\x85\xae\0" /* offset 7651 */ + "\xe1\x85\xaf\0" /* offset 7655 */ + "\xe1\x85\xb0\0" /* offset 7659 */ + "\xe1\x85\xb1\0" /* offset 7663 */ + "\xe1\x85\xb2\0" /* offset 7667 */ + "\xe1\x85\xb3\0" /* offset 7671 */ + "\xe1\x85\xb4\0" /* offset 7675 */ + "\xe1\x85\xb5\0" /* offset 7679 */ + "\xe1\x85\xa0\0" /* offset 7683 */ + "\xe1\x84\x94\0" /* offset 7687 */ + "\xe1\x84\x95\0" /* offset 7691 */ + "\xe1\x87\x87\0" /* offset 7695 */ + "\xe1\x87\x88\0" /* offset 7699 */ + "\xe1\x87\x8c\0" /* offset 7703 */ + "\xe1\x87\x8e\0" /* offset 7707 */ + "\xe1\x87\x93\0" /* offset 7711 */ + "\xe1\x87\x97\0" /* offset 7715 */ + "\xe1\x87\x99\0" /* offset 7719 */ + "\xe1\x84\x9c\0" /* offset 7723 */ + "\xe1\x87\x9d\0" /* offset 7727 */ + "\xe1\x87\x9f\0" /* offset 7731 */ + "\xe1\x84\x9d\0" /* offset 7735 */ + "\xe1\x84\x9e\0" /* offset 7739 */ + "\xe1\x84\xa0\0" /* offset 7743 */ + "\xe1\x84\xa2\0" /* offset 7747 */ + "\xe1\x84\xa3\0" /* offset 7751 */ + "\xe1\x84\xa7\0" /* offset 7755 */ + "\xe1\x84\xa9\0" /* offset 7759 */ + "\xe1\x84\xab\0" /* offset 7763 */ + "\xe1\x84\xac\0" /* offset 7767 */ + "\xe1\x84\xad\0" /* offset 7771 */ + "\xe1\x84\xae\0" /* offset 7775 */ + "\xe1\x84\xaf\0" /* offset 7779 */ + "\xe1\x84\xb2\0" /* offset 7783 */ + "\xe1\x84\xb6\0" /* offset 7787 */ + "\xe1\x85\x80\0" /* offset 7791 */ + "\xe1\x85\x87\0" /* offset 7795 */ + "\xe1\x85\x8c\0" /* offset 7799 */ + "\xe1\x87\xb1\0" /* offset 7803 */ + "\xe1\x87\xb2\0" /* offset 7807 */ + "\xe1\x85\x97\0" /* offset 7811 */ + "\xe1\x85\x98\0" /* offset 7815 */ + "\xe1\x85\x99\0" /* offset 7819 */ + "\xe1\x86\x84\0" /* offset 7823 */ + "\xe1\x86\x85\0" /* offset 7827 */ + "\xe1\x86\x88\0" /* offset 7831 */ + "\xe1\x86\x91\0" /* offset 7835 */ + "\xe1\x86\x92\0" /* offset 7839 */ + "\xe1\x86\x94\0" /* offset 7843 */ + "\xe1\x86\x9e\0" /* offset 7847 */ + "\xe1\x86\xa1\0" /* offset 7851 */ + "\xe4\xb8\x89\0" /* offset 7855 */ + "\xe5\x9b\x9b\0" /* offset 7859 */ + "\xe4\xb8\x8a\0" /* offset 7863 */ + "\xe4\xb8\xad\0" /* offset 7867 */ + "\xe4\xb8\x8b\0" /* offset 7871 */ + "\xe7\x94\xb2\0" /* offset 7875 */ + "\xe4\xb8\x99\0" /* offset 7879 */ + "\xe4\xb8\x81\0" /* offset 7883 */ + "\xe5\xa4\xa9\0" /* offset 7887 */ + "\xe5\x9c\xb0\0" /* offset 7891 */ + "\x28\xe1\x84\x80\x29\0" /* offset 7895 */ + "\x28\xe1\x84\x82\x29\0" /* offset 7901 */ + "\x28\xe1\x84\x83\x29\0" /* offset 7907 */ + "\x28\xe1\x84\x85\x29\0" /* offset 7913 */ + "\x28\xe1\x84\x86\x29\0" /* offset 7919 */ + "\x28\xe1\x84\x87\x29\0" /* offset 7925 */ + "\x28\xe1\x84\x89\x29\0" /* offset 7931 */ + "\x28\xe1\x84\x8b\x29\0" /* offset 7937 */ + "\x28\xe1\x84\x8c\x29\0" /* offset 7943 */ + "\x28\xe1\x84\x8e\x29\0" /* offset 7949 */ + "\x28\xe1\x84\x8f\x29\0" /* offset 7955 */ + "\x28\xe1\x84\x90\x29\0" /* offset 7961 */ + "\x28\xe1\x84\x91\x29\0" /* offset 7967 */ + "\x28\xe1\x84\x92\x29\0" /* offset 7973 */ + "\x28\xe1\x84\x80\xe1\x85\xa1\x29\0" /* offset 7979 */ + "\x28\xe1\x84\x82\xe1\x85\xa1\x29\0" /* offset 7988 */ + "\x28\xe1\x84\x83\xe1\x85\xa1\x29\0" /* offset 7997 */ + "\x28\xe1\x84\x85\xe1\x85\xa1\x29\0" /* offset 8006 */ + "\x28\xe1\x84\x86\xe1\x85\xa1\x29\0" /* offset 8015 */ + "\x28\xe1\x84\x87\xe1\x85\xa1\x29\0" /* offset 8024 */ + "\x28\xe1\x84\x89\xe1\x85\xa1\x29\0" /* offset 8033 */ + "\x28\xe1\x84\x8b\xe1\x85\xa1\x29\0" /* offset 8042 */ + "\x28\xe1\x84\x8c\xe1\x85\xa1\x29\0" /* offset 8051 */ + "\x28\xe1\x84\x8e\xe1\x85\xa1\x29\0" /* offset 8060 */ + "\x28\xe1\x84\x8f\xe1\x85\xa1\x29\0" /* offset 8069 */ + "\x28\xe1\x84\x90\xe1\x85\xa1\x29\0" /* offset 8078 */ + "\x28\xe1\x84\x91\xe1\x85\xa1\x29\0" /* offset 8087 */ + "\x28\xe1\x84\x92\xe1\x85\xa1\x29\0" /* offset 8096 */ + "\x28\xe1\x84\x8c\xe1\x85\xae\x29\0" /* offset 8105 */ + "\x28\xe1\x84\x8b\xe1\x85\xa9\xe1\x84\x8c\xe1\x85\xa5\xe1\x86\xab\x29\0" /* offset 8114 */ + "\x28\xe1\x84\x8b\xe1\x85\xa9\xe1\x84\x92\xe1\x85\xae\x29\0" /* offset 8132 */ + "\x28\xe4\xb8\x80\x29\0" /* offset 8147 */ + "\x28\xe4\xba\x8c\x29\0" /* offset 8153 */ + "\x28\xe4\xb8\x89\x29\0" /* offset 8159 */ + "\x28\xe5\x9b\x9b\x29\0" /* offset 8165 */ + "\x28\xe4\xba\x94\x29\0" /* offset 8171 */ + "\x28\xe5\x85\xad\x29\0" /* offset 8177 */ + "\x28\xe4\xb8\x83\x29\0" /* offset 8183 */ + "\x28\xe5\x85\xab\x29\0" /* offset 8189 */ + "\x28\xe4\xb9\x9d\x29\0" /* offset 8195 */ + "\x28\xe5\x8d\x81\x29\0" /* offset 8201 */ + "\x28\xe6\x9c\x88\x29\0" /* offset 8207 */ + "\x28\xe7\x81\xab\x29\0" /* offset 8213 */ + "\x28\xe6\xb0\xb4\x29\0" /* offset 8219 */ + "\x28\xe6\x9c\xa8\x29\0" /* offset 8225 */ + "\x28\xe9\x87\x91\x29\0" /* offset 8231 */ + "\x28\xe5\x9c\x9f\x29\0" /* offset 8237 */ + "\x28\xe6\x97\xa5\x29\0" /* offset 8243 */ + "\x28\xe6\xa0\xaa\x29\0" /* offset 8249 */ + "\x28\xe6\x9c\x89\x29\0" /* offset 8255 */ + "\x28\xe7\xa4\xbe\x29\0" /* offset 8261 */ + "\x28\xe5\x90\x8d\x29\0" /* offset 8267 */ + "\x28\xe7\x89\xb9\x29\0" /* offset 8273 */ + "\x28\xe8\xb2\xa1\x29\0" /* offset 8279 */ + "\x28\xe7\xa5\x9d\x29\0" /* offset 8285 */ + "\x28\xe5\x8a\xb4\x29\0" /* offset 8291 */ + "\x28\xe4\xbb\xa3\x29\0" /* offset 8297 */ + "\x28\xe5\x91\xbc\x29\0" /* offset 8303 */ + "\x28\xe5\xad\xa6\x29\0" /* offset 8309 */ + "\x28\xe7\x9b\xa3\x29\0" /* offset 8315 */ + "\x28\xe4\xbc\x81\x29\0" /* offset 8321 */ + "\x28\xe8\xb3\x87\x29\0" /* offset 8327 */ + "\x28\xe5\x8d\x94\x29\0" /* offset 8333 */ + "\x28\xe7\xa5\xad\x29\0" /* offset 8339 */ + "\x28\xe4\xbc\x91\x29\0" /* offset 8345 */ + "\x28\xe8\x87\xaa\x29\0" /* offset 8351 */ + "\x28\xe8\x87\xb3\x29\0" /* offset 8357 */ + "\xe5\x95\x8f\0" /* offset 8363 */ + "\xe5\xb9\xbc\0" /* offset 8367 */ + "\xe7\xae\x8f\0" /* offset 8371 */ + "\x50\x54\x45\0" /* offset 8375 */ + "\x32\x31\0" /* offset 8379 */ + "\x32\x32\0" /* offset 8382 */ + "\x32\x33\0" /* offset 8385 */ + "\x32\x34\0" /* offset 8388 */ + "\x32\x35\0" /* offset 8391 */ + "\x32\x36\0" /* offset 8394 */ + "\x32\x37\0" /* offset 8397 */ + "\x32\x38\0" /* offset 8400 */ + "\x32\x39\0" /* offset 8403 */ + "\x33\x30\0" /* offset 8406 */ + "\x33\x31\0" /* offset 8409 */ + "\x33\x32\0" /* offset 8412 */ + "\x33\x33\0" /* offset 8415 */ + "\x33\x34\0" /* offset 8418 */ + "\x33\x35\0" /* offset 8421 */ + "\xe1\x84\x80\xe1\x85\xa1\0" /* offset 8424 */ + "\xe1\x84\x82\xe1\x85\xa1\0" /* offset 8431 */ + "\xe1\x84\x83\xe1\x85\xa1\0" /* offset 8438 */ + "\xe1\x84\x85\xe1\x85\xa1\0" /* offset 8445 */ + "\xe1\x84\x86\xe1\x85\xa1\0" /* offset 8452 */ + "\xe1\x84\x87\xe1\x85\xa1\0" /* offset 8459 */ + "\xe1\x84\x89\xe1\x85\xa1\0" /* offset 8466 */ + "\xe1\x84\x8b\xe1\x85\xa1\0" /* offset 8473 */ + "\xe1\x84\x8c\xe1\x85\xa1\0" /* offset 8480 */ + "\xe1\x84\x8e\xe1\x85\xa1\0" /* offset 8487 */ + "\xe1\x84\x8f\xe1\x85\xa1\0" /* offset 8494 */ + "\xe1\x84\x90\xe1\x85\xa1\0" /* offset 8501 */ + "\xe1\x84\x91\xe1\x85\xa1\0" /* offset 8508 */ + "\xe1\x84\x92\xe1\x85\xa1\0" /* offset 8515 */ + "\xe1\x84\x8e\xe1\x85\xa1\xe1\x86\xb7\xe1\x84\x80\xe1\x85\xa9\0" /* offset 8522 */ + "\xe1\x84\x8c\xe1\x85\xae\xe1\x84\x8b\xe1\x85\xb4\0" /* offset 8538 */ + "\xe1\x84\x8b\xe1\x85\xae\0" /* offset 8551 */ + "\xe4\xba\x94\0" /* offset 8558 */ + "\xe5\x85\xad\0" /* offset 8562 */ + "\xe4\xb8\x83\0" /* offset 8566 */ + "\xe4\xb9\x9d\0" /* offset 8570 */ + "\xe6\xa0\xaa\0" /* offset 8574 */ + "\xe6\x9c\x89\0" /* offset 8578 */ + "\xe7\xa4\xbe\0" /* offset 8582 */ + "\xe5\x90\x8d\0" /* offset 8586 */ + "\xe7\x89\xb9\0" /* offset 8590 */ + "\xe8\xb2\xa1\0" /* offset 8594 */ + "\xe7\xa5\x9d\0" /* offset 8598 */ + "\xe5\x8a\xb4\0" /* offset 8602 */ + "\xe7\xa7\x98\0" /* offset 8606 */ + "\xe7\x94\xb7\0" /* offset 8610 */ + "\xe9\x81\xa9\0" /* offset 8614 */ + "\xe5\x84\xaa\0" /* offset 8618 */ + "\xe5\x8d\xb0\0" /* offset 8622 */ + "\xe6\xb3\xa8\0" /* offset 8626 */ + "\xe9\xa0\x85\0" /* offset 8630 */ + "\xe4\xbc\x91\0" /* offset 8634 */ + "\xe5\x86\x99\0" /* offset 8638 */ + "\xe6\xad\xa3\0" /* offset 8642 */ + "\xe5\xb7\xa6\0" /* offset 8646 */ + "\xe5\x8f\xb3\0" /* offset 8650 */ + "\xe5\x8c\xbb\0" /* offset 8654 */ + "\xe5\xae\x97\0" /* offset 8658 */ + "\xe5\xad\xa6\0" /* offset 8662 */ + "\xe7\x9b\xa3\0" /* offset 8666 */ + "\xe4\xbc\x81\0" /* offset 8670 */ + "\xe8\xb3\x87\0" /* offset 8674 */ + "\xe5\x8d\x94\0" /* offset 8678 */ + "\xe5\xa4\x9c\0" /* offset 8682 */ + "\x33\x36\0" /* offset 8686 */ + "\x33\x37\0" /* offset 8689 */ + "\x33\x38\0" /* offset 8692 */ + "\x33\x39\0" /* offset 8695 */ + "\x34\x30\0" /* offset 8698 */ + "\x34\x31\0" /* offset 8701 */ + "\x34\x32\0" /* offset 8704 */ + "\x34\x33\0" /* offset 8707 */ + "\x34\x34\0" /* offset 8710 */ + "\x34\x35\0" /* offset 8713 */ + "\x34\x36\0" /* offset 8716 */ + "\x34\x37\0" /* offset 8719 */ + "\x34\x38\0" /* offset 8722 */ + "\x34\x39\0" /* offset 8725 */ + "\x35\x30\0" /* offset 8728 */ + "\x31\xe6\x9c\x88\0" /* offset 8731 */ + "\x32\xe6\x9c\x88\0" /* offset 8736 */ + "\x33\xe6\x9c\x88\0" /* offset 8741 */ + "\x34\xe6\x9c\x88\0" /* offset 8746 */ + "\x35\xe6\x9c\x88\0" /* offset 8751 */ + "\x36\xe6\x9c\x88\0" /* offset 8756 */ + "\x37\xe6\x9c\x88\0" /* offset 8761 */ + "\x38\xe6\x9c\x88\0" /* offset 8766 */ + "\x39\xe6\x9c\x88\0" /* offset 8771 */ + "\x31\x30\xe6\x9c\x88\0" /* offset 8776 */ + "\x31\x31\xe6\x9c\x88\0" /* offset 8782 */ + "\x31\x32\xe6\x9c\x88\0" /* offset 8788 */ + "\x48\x67\0" /* offset 8794 */ + "\x65\x72\x67\0" /* offset 8797 */ + "\x65\x56\0" /* offset 8801 */ + "\x4c\x54\x44\0" /* offset 8804 */ + "\xe3\x82\xa2\0" /* offset 8808 */ + "\xe3\x82\xa4\0" /* offset 8812 */ + "\xe3\x82\xa6\0" /* offset 8816 */ + "\xe3\x82\xa8\0" /* offset 8820 */ + "\xe3\x82\xaa\0" /* offset 8824 */ + "\xe3\x82\xab\0" /* offset 8828 */ + "\xe3\x82\xad\0" /* offset 8832 */ + "\xe3\x82\xaf\0" /* offset 8836 */ + "\xe3\x82\xb1\0" /* offset 8840 */ + "\xe3\x82\xb3\0" /* offset 8844 */ + "\xe3\x82\xb5\0" /* offset 8848 */ + "\xe3\x82\xb7\0" /* offset 8852 */ + "\xe3\x82\xb9\0" /* offset 8856 */ + "\xe3\x82\xbb\0" /* offset 8860 */ + "\xe3\x82\xbd\0" /* offset 8864 */ + "\xe3\x82\xbf\0" /* offset 8868 */ + "\xe3\x83\x81\0" /* offset 8872 */ + "\xe3\x83\x84\0" /* offset 8876 */ + "\xe3\x83\x86\0" /* offset 8880 */ + "\xe3\x83\x88\0" /* offset 8884 */ + "\xe3\x83\x8a\0" /* offset 8888 */ + "\xe3\x83\x8b\0" /* offset 8892 */ + "\xe3\x83\x8c\0" /* offset 8896 */ + "\xe3\x83\x8d\0" /* offset 8900 */ + "\xe3\x83\x8e\0" /* offset 8904 */ + "\xe3\x83\x8f\0" /* offset 8908 */ + "\xe3\x83\x92\0" /* offset 8912 */ + "\xe3\x83\x95\0" /* offset 8916 */ + "\xe3\x83\x98\0" /* offset 8920 */ + "\xe3\x83\x9b\0" /* offset 8924 */ + "\xe3\x83\x9e\0" /* offset 8928 */ + "\xe3\x83\x9f\0" /* offset 8932 */ + "\xe3\x83\xa0\0" /* offset 8936 */ + "\xe3\x83\xa1\0" /* offset 8940 */ + "\xe3\x83\xa2\0" /* offset 8944 */ + "\xe3\x83\xa4\0" /* offset 8948 */ + "\xe3\x83\xa6\0" /* offset 8952 */ + "\xe3\x83\xa8\0" /* offset 8956 */ + "\xe3\x83\xa9\0" /* offset 8960 */ + "\xe3\x83\xaa\0" /* offset 8964 */ + "\xe3\x83\xab\0" /* offset 8968 */ + "\xe3\x83\xac\0" /* offset 8972 */ + "\xe3\x83\xad\0" /* offset 8976 */ + "\xe3\x83\xaf\0" /* offset 8980 */ + "\xe3\x83\xb0\0" /* offset 8984 */ + "\xe3\x83\xb1\0" /* offset 8988 */ + "\xe3\x83\xb2\0" /* offset 8992 */ + "\xe3\x82\xa2\xe3\x83\x8f\xe3\x82\x9a\xe3\x83\xbc\xe3\x83\x88\0" /* offset 8996 */ + "\xe3\x82\xa2\xe3\x83\xab\xe3\x83\x95\xe3\x82\xa1\0" /* offset 9012 */ + "\xe3\x82\xa2\xe3\x83\xb3\xe3\x83\x98\xe3\x82\x9a\xe3\x82\xa2\0" /* offset 9025 */ + "\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9041 */ + "\xe3\x82\xa4\xe3\x83\x8b\xe3\x83\xb3\xe3\x82\xaf\xe3\x82\x99\0" /* offset 9051 */ + "\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x81\0" /* offset 9067 */ + "\xe3\x82\xa6\xe3\x82\xa9\xe3\x83\xb3\0" /* offset 9077 */ + "\xe3\x82\xa8\xe3\x82\xb9\xe3\x82\xaf\xe3\x83\xbc\xe3\x83\x88\xe3\x82\x99\0" /* offset 9087 */ + "\xe3\x82\xa8\xe3\x83\xbc\xe3\x82\xab\xe3\x83\xbc\0" /* offset 9106 */ + "\xe3\x82\xaa\xe3\x83\xb3\xe3\x82\xb9\0" /* offset 9119 */ + "\xe3\x82\xaa\xe3\x83\xbc\xe3\x83\xa0\0" /* offset 9129 */ + "\xe3\x82\xab\xe3\x82\xa4\xe3\x83\xaa\0" /* offset 9139 */ + "\xe3\x82\xab\xe3\x83\xa9\xe3\x83\x83\xe3\x83\x88\0" /* offset 9149 */ + "\xe3\x82\xab\xe3\x83\xad\xe3\x83\xaa\xe3\x83\xbc\0" /* offset 9162 */ + "\xe3\x82\xab\xe3\x82\x99\xe3\x83\xad\xe3\x83\xb3\0" /* offset 9175 */ + "\xe3\x82\xab\xe3\x82\x99\xe3\x83\xb3\xe3\x83\x9e\0" /* offset 9188 */ + "\xe3\x82\xad\xe3\x82\x99\xe3\x82\xab\xe3\x82\x99\0" /* offset 9201 */ + "\xe3\x82\xad\xe3\x82\x99\xe3\x83\x8b\xe3\x83\xbc\0" /* offset 9214 */ + "\xe3\x82\xad\xe3\x83\xa5\xe3\x83\xaa\xe3\x83\xbc\0" /* offset 9227 */ + "\xe3\x82\xad\xe3\x82\x99\xe3\x83\xab\xe3\x82\xbf\xe3\x82\x99\xe3\x83\xbc\0" /* offset 9240 */ + "\xe3\x82\xad\xe3\x83\xad\0" /* offset 9259 */ + "\xe3\x82\xad\xe3\x83\xad\xe3\x82\xaf\xe3\x82\x99\xe3\x83\xa9\xe3\x83\xa0\0" /* offset 9266 */ + "\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88\xe3\x83\xab\0" /* offset 9285 */ + "\xe3\x82\xad\xe3\x83\xad\xe3\x83\xaf\xe3\x83\x83\xe3\x83\x88\0" /* offset 9304 */ + "\xe3\x82\xaf\xe3\x82\x99\xe3\x83\xa9\xe3\x83\xa0\0" /* offset 9320 */ + "\xe3\x82\xaf\xe3\x82\x99\xe3\x83\xa9\xe3\x83\xa0\xe3\x83\x88\xe3\x83\xb3\0" /* offset 9333 */ + "\xe3\x82\xaf\xe3\x83\xab\xe3\x82\xbb\xe3\x82\x99\xe3\x82\xa4\xe3\x83\xad\0" /* offset 9352 */ + "\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xbc\xe3\x83\x8d\0" /* offset 9371 */ + "\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb9\0" /* offset 9384 */ + "\xe3\x82\xb3\xe3\x83\xab\xe3\x83\x8a\0" /* offset 9394 */ + "\xe3\x82\xb3\xe3\x83\xbc\xe3\x83\x9b\xe3\x82\x9a\0" /* offset 9404 */ + "\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xaf\xe3\x83\xab\0" /* offset 9417 */ + "\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x81\xe3\x83\xbc\xe3\x83\xa0\0" /* offset 9430 */ + "\xe3\x82\xb7\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xaf\xe3\x82\x99\0" /* offset 9446 */ + "\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x81\0" /* offset 9462 */ + "\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x88\0" /* offset 9472 */ + "\xe3\x82\xbf\xe3\x82\x99\xe3\x83\xbc\xe3\x82\xb9\0" /* offset 9482 */ + "\xe3\x83\x86\xe3\x82\x99\xe3\x82\xb7\0" /* offset 9495 */ + "\xe3\x83\x88\xe3\x82\x99\xe3\x83\xab\0" /* offset 9505 */ + "\xe3\x83\x88\xe3\x83\xb3\0" /* offset 9515 */ + "\xe3\x83\x8a\xe3\x83\x8e\0" /* offset 9522 */ + "\xe3\x83\x8e\xe3\x83\x83\xe3\x83\x88\0" /* offset 9529 */ + "\xe3\x83\x8f\xe3\x82\xa4\xe3\x83\x84\0" /* offset 9539 */ + "\xe3\x83\x8f\xe3\x82\x9a\xe3\x83\xbc\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x88\0" /* offset 9549 */ + "\xe3\x83\x8f\xe3\x82\x9a\xe3\x83\xbc\xe3\x83\x84\0" /* offset 9568 */ + "\xe3\x83\x8f\xe3\x82\x99\xe3\x83\xbc\xe3\x83\xac\xe3\x83\xab\0" /* offset 9581 */ + "\xe3\x83\x92\xe3\x82\x9a\xe3\x82\xa2\xe3\x82\xb9\xe3\x83\x88\xe3\x83\xab\0" /* offset 9597 */ + "\xe3\x83\x92\xe3\x82\x9a\xe3\x82\xaf\xe3\x83\xab\0" /* offset 9616 */ + "\xe3\x83\x92\xe3\x82\x9a\xe3\x82\xb3\0" /* offset 9629 */ + "\xe3\x83\x92\xe3\x82\x99\xe3\x83\xab\0" /* offset 9639 */ + "\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xa9\xe3\x83\x83\xe3\x83\x88\xe3\x82\x99\0" /* offset 9649 */ + "\xe3\x83\x95\xe3\x82\xa3\xe3\x83\xbc\xe3\x83\x88\0" /* offset 9668 */ + "\xe3\x83\x95\xe3\x82\x99\xe3\x83\x83\xe3\x82\xb7\xe3\x82\xa7\xe3\x83\xab\0" /* offset 9681 */ + "\xe3\x83\x95\xe3\x83\xa9\xe3\x83\xb3\0" /* offset 9700 */ + "\xe3\x83\x98\xe3\x82\xaf\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9710 */ + "\xe3\x83\x98\xe3\x82\x9a\xe3\x82\xbd\0" /* offset 9726 */ + "\xe3\x83\x98\xe3\x82\x9a\xe3\x83\x8b\xe3\x83\x92\0" /* offset 9736 */ + "\xe3\x83\x98\xe3\x83\xab\xe3\x83\x84\0" /* offset 9749 */ + "\xe3\x83\x98\xe3\x82\x9a\xe3\x83\xb3\xe3\x82\xb9\0" /* offset 9759 */ + "\xe3\x83\x98\xe3\x82\x9a\xe3\x83\xbc\xe3\x82\xb7\xe3\x82\x99\0" /* offset 9772 */ + "\xe3\x83\x98\xe3\x82\x99\xe3\x83\xbc\xe3\x82\xbf\0" /* offset 9788 */ + "\xe3\x83\x9b\xe3\x82\x9a\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" /* offset 9801 */ + "\xe3\x83\x9b\xe3\x82\x99\xe3\x83\xab\xe3\x83\x88\0" /* offset 9817 */ + "\xe3\x83\x9b\xe3\x83\xb3\0" /* offset 9830 */ + "\xe3\x83\x9b\xe3\x82\x9a\xe3\x83\xb3\xe3\x83\x88\xe3\x82\x99\0" /* offset 9837 */ + "\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9853 */ + "\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xb3\0" /* offset 9863 */ + "\xe3\x83\x9e\xe3\x82\xa4\xe3\x82\xaf\xe3\x83\xad\0" /* offset 9873 */ + "\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xab\0" /* offset 9886 */ + "\xe3\x83\x9e\xe3\x83\x83\xe3\x83\x8f\0" /* offset 9896 */ + "\xe3\x83\x9e\xe3\x83\xab\xe3\x82\xaf\0" /* offset 9906 */ + "\xe3\x83\x9e\xe3\x83\xb3\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0" /* offset 9916 */ + "\xe3\x83\x9f\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xb3\0" /* offset 9932 */ + "\xe3\x83\x9f\xe3\x83\xaa\0" /* offset 9945 */ + "\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\x8f\xe3\x82\x99\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9952 */ + "\xe3\x83\xa1\xe3\x82\xab\xe3\x82\x99\0" /* offset 9971 */ + "\xe3\x83\xa1\xe3\x82\xab\xe3\x82\x99\xe3\x83\x88\xe3\x83\xb3\0" /* offset 9981 */ + "\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88\xe3\x83\xab\0" /* offset 9997 */ + "\xe3\x83\xa4\xe3\x83\xbc\xe3\x83\x88\xe3\x82\x99\0" /* offset 10010 */ + "\xe3\x83\xa4\xe3\x83\xbc\xe3\x83\xab\0" /* offset 10023 */ + "\xe3\x83\xa6\xe3\x82\xa2\xe3\x83\xb3\0" /* offset 10033 */ + "\xe3\x83\xaa\xe3\x83\x83\xe3\x83\x88\xe3\x83\xab\0" /* offset 10043 */ + "\xe3\x83\xaa\xe3\x83\xa9\0" /* offset 10056 */ + "\xe3\x83\xab\xe3\x83\x92\xe3\x82\x9a\xe3\x83\xbc\0" /* offset 10063 */ + "\xe3\x83\xab\xe3\x83\xbc\xe3\x83\x95\xe3\x82\x99\xe3\x83\xab\0" /* offset 10076 */ + "\xe3\x83\xac\xe3\x83\xa0\0" /* offset 10092 */ + "\xe3\x83\xac\xe3\x83\xb3\xe3\x83\x88\xe3\x82\xb1\xe3\x82\x99\xe3\x83\xb3\0" /* offset 10099 */ + "\xe3\x83\xaf\xe3\x83\x83\xe3\x83\x88\0" /* offset 10118 */ + "\x30\xe7\x82\xb9\0" /* offset 10128 */ + "\x31\xe7\x82\xb9\0" /* offset 10133 */ + "\x32\xe7\x82\xb9\0" /* offset 10138 */ + "\x33\xe7\x82\xb9\0" /* offset 10143 */ + "\x34\xe7\x82\xb9\0" /* offset 10148 */ + "\x35\xe7\x82\xb9\0" /* offset 10153 */ + "\x36\xe7\x82\xb9\0" /* offset 10158 */ + "\x37\xe7\x82\xb9\0" /* offset 10163 */ + "\x38\xe7\x82\xb9\0" /* offset 10168 */ + "\x39\xe7\x82\xb9\0" /* offset 10173 */ + "\x31\x30\xe7\x82\xb9\0" /* offset 10178 */ + "\x31\x31\xe7\x82\xb9\0" /* offset 10184 */ + "\x31\x32\xe7\x82\xb9\0" /* offset 10190 */ + "\x31\x33\xe7\x82\xb9\0" /* offset 10196 */ + "\x31\x34\xe7\x82\xb9\0" /* offset 10202 */ + "\x31\x35\xe7\x82\xb9\0" /* offset 10208 */ + "\x31\x36\xe7\x82\xb9\0" /* offset 10214 */ + "\x31\x37\xe7\x82\xb9\0" /* offset 10220 */ + "\x31\x38\xe7\x82\xb9\0" /* offset 10226 */ + "\x31\x39\xe7\x82\xb9\0" /* offset 10232 */ + "\x32\x30\xe7\x82\xb9\0" /* offset 10238 */ + "\x32\x31\xe7\x82\xb9\0" /* offset 10244 */ + "\x32\x32\xe7\x82\xb9\0" /* offset 10250 */ + "\x32\x33\xe7\x82\xb9\0" /* offset 10256 */ + "\x32\x34\xe7\x82\xb9\0" /* offset 10262 */ + "\x68\x50\x61\0" /* offset 10268 */ + "\x64\x61\0" /* offset 10272 */ + "\x41\x55\0" /* offset 10275 */ + "\x62\x61\x72\0" /* offset 10278 */ + "\x6f\x56\0" /* offset 10282 */ + "\x70\x63\0" /* offset 10285 */ + "\x64\x6d\0" /* offset 10288 */ + "\x64\x6d\x32\0" /* offset 10291 */ + "\x64\x6d\x33\0" /* offset 10295 */ + "\x49\x55\0" /* offset 10299 */ + "\xe5\xb9\xb3\xe6\x88\x90\0" /* offset 10302 */ + "\xe6\x98\xad\xe5\x92\x8c\0" /* offset 10309 */ + "\xe5\xa4\xa7\xe6\xad\xa3\0" /* offset 10316 */ + "\xe6\x98\x8e\xe6\xb2\xbb\0" /* offset 10323 */ + "\xe6\xa0\xaa\xe5\xbc\x8f\xe4\xbc\x9a\xe7\xa4\xbe\0" /* offset 10330 */ + "\x70\x41\0" /* offset 10343 */ + "\x6e\x41\0" /* offset 10346 */ + "\xce\xbc\x41\0" /* offset 10349 */ + "\x6d\x41\0" /* offset 10353 */ + "\x6b\x41\0" /* offset 10356 */ + "\x4b\x42\0" /* offset 10359 */ + "\x4d\x42\0" /* offset 10362 */ + "\x47\x42\0" /* offset 10365 */ + "\x63\x61\x6c\0" /* offset 10368 */ + "\x6b\x63\x61\x6c\0" /* offset 10372 */ + "\x70\x46\0" /* offset 10377 */ + "\x6e\x46\0" /* offset 10380 */ + "\xce\xbc\x46\0" /* offset 10383 */ + "\xce\xbc\x67\0" /* offset 10387 */ + "\x6d\x67\0" /* offset 10391 */ + "\x6b\x67\0" /* offset 10394 */ + "\x48\x7a\0" /* offset 10397 */ + "\x6b\x48\x7a\0" /* offset 10400 */ + "\x4d\x48\x7a\0" /* offset 10404 */ + "\x47\x48\x7a\0" /* offset 10408 */ + "\x54\x48\x7a\0" /* offset 10412 */ + "\xce\xbc\x6c\0" /* offset 10416 */ + "\x6d\x6c\0" /* offset 10420 */ + "\x64\x6c\0" /* offset 10423 */ + "\x6b\x6c\0" /* offset 10426 */ + "\x66\x6d\0" /* offset 10429 */ + "\x6e\x6d\0" /* offset 10432 */ + "\xce\xbc\x6d\0" /* offset 10435 */ + "\x6d\x6d\0" /* offset 10439 */ + "\x63\x6d\0" /* offset 10442 */ + "\x6b\x6d\0" /* offset 10445 */ + "\x6d\x6d\x32\0" /* offset 10448 */ + "\x63\x6d\x32\0" /* offset 10452 */ + "\x6d\x32\0" /* offset 10456 */ + "\x6b\x6d\x32\0" /* offset 10459 */ + "\x6d\x6d\x33\0" /* offset 10463 */ + "\x63\x6d\x33\0" /* offset 10467 */ + "\x6d\x33\0" /* offset 10471 */ + "\x6b\x6d\x33\0" /* offset 10474 */ + "\x6d\xe2\x88\x95\x73\0" /* offset 10478 */ + "\x6d\xe2\x88\x95\x73\x32\0" /* offset 10484 */ + "\x50\x61\0" /* offset 10491 */ + "\x6b\x50\x61\0" /* offset 10494 */ + "\x4d\x50\x61\0" /* offset 10498 */ + "\x47\x50\x61\0" /* offset 10502 */ + "\x72\x61\x64\0" /* offset 10506 */ + "\x72\x61\x64\xe2\x88\x95\x73\0" /* offset 10510 */ + "\x72\x61\x64\xe2\x88\x95\x73\x32\0" /* offset 10518 */ + "\x70\x73\0" /* offset 10527 */ + "\x6e\x73\0" /* offset 10530 */ + "\xce\xbc\x73\0" /* offset 10533 */ + "\x6d\x73\0" /* offset 10537 */ + "\x70\x56\0" /* offset 10540 */ + "\x6e\x56\0" /* offset 10543 */ + "\xce\xbc\x56\0" /* offset 10546 */ + "\x6d\x56\0" /* offset 10550 */ + "\x6b\x56\0" /* offset 10553 */ + "\x4d\x56\0" /* offset 10556 */ + "\x70\x57\0" /* offset 10559 */ + "\x6e\x57\0" /* offset 10562 */ + "\xce\xbc\x57\0" /* offset 10565 */ + "\x6d\x57\0" /* offset 10569 */ + "\x6b\x57\0" /* offset 10572 */ + "\x4d\x57\0" /* offset 10575 */ + "\x6b\xce\xa9\0" /* offset 10578 */ + "\x4d\xce\xa9\0" /* offset 10582 */ + "\x61\x2e\x6d\x2e\0" /* offset 10586 */ + "\x42\x71\0" /* offset 10591 */ + "\x63\x63\0" /* offset 10594 */ + "\x63\x64\0" /* offset 10597 */ + "\x43\xe2\x88\x95\x6b\x67\0" /* offset 10600 */ + "\x43\x6f\x2e\0" /* offset 10607 */ + "\x64\x42\0" /* offset 10611 */ + "\x47\x79\0" /* offset 10614 */ + "\x68\x61\0" /* offset 10617 */ + "\x48\x50\0" /* offset 10620 */ + "\x69\x6e\0" /* offset 10623 */ + "\x4b\x4b\0" /* offset 10626 */ + "\x4b\x4d\0" /* offset 10629 */ + "\x6b\x74\0" /* offset 10632 */ + "\x6c\x6d\0" /* offset 10635 */ + "\x6c\x6e\0" /* offset 10638 */ + "\x6c\x6f\x67\0" /* offset 10641 */ + "\x6c\x78\0" /* offset 10645 */ + "\x6d\x62\0" /* offset 10648 */ + "\x6d\x69\x6c\0" /* offset 10651 */ + "\x6d\x6f\x6c\0" /* offset 10655 */ + "\x50\x48\0" /* offset 10659 */ + "\x70\x2e\x6d\x2e\0" /* offset 10662 */ + "\x50\x50\x4d\0" /* offset 10667 */ + "\x50\x52\0" /* offset 10671 */ + "\x73\x72\0" /* offset 10674 */ + "\x53\x76\0" /* offset 10677 */ + "\x57\x62\0" /* offset 10680 */ + "\x56\xe2\x88\x95\x6d\0" /* offset 10683 */ + "\x41\xe2\x88\x95\x6d\0" /* offset 10689 */ + "\x31\xe6\x97\xa5\0" /* offset 10695 */ + "\x32\xe6\x97\xa5\0" /* offset 10700 */ + "\x33\xe6\x97\xa5\0" /* offset 10705 */ + "\x34\xe6\x97\xa5\0" /* offset 10710 */ + "\x35\xe6\x97\xa5\0" /* offset 10715 */ + "\x36\xe6\x97\xa5\0" /* offset 10720 */ + "\x37\xe6\x97\xa5\0" /* offset 10725 */ + "\x38\xe6\x97\xa5\0" /* offset 10730 */ + "\x39\xe6\x97\xa5\0" /* offset 10735 */ + "\x31\x30\xe6\x97\xa5\0" /* offset 10740 */ + "\x31\x31\xe6\x97\xa5\0" /* offset 10746 */ + "\x31\x32\xe6\x97\xa5\0" /* offset 10752 */ + "\x31\x33\xe6\x97\xa5\0" /* offset 10758 */ + "\x31\x34\xe6\x97\xa5\0" /* offset 10764 */ + "\x31\x35\xe6\x97\xa5\0" /* offset 10770 */ + "\x31\x36\xe6\x97\xa5\0" /* offset 10776 */ + "\x31\x37\xe6\x97\xa5\0" /* offset 10782 */ + "\x31\x38\xe6\x97\xa5\0" /* offset 10788 */ + "\x31\x39\xe6\x97\xa5\0" /* offset 10794 */ + "\x32\x30\xe6\x97\xa5\0" /* offset 10800 */ + "\x32\x31\xe6\x97\xa5\0" /* offset 10806 */ + "\x32\x32\xe6\x97\xa5\0" /* offset 10812 */ + "\x32\x33\xe6\x97\xa5\0" /* offset 10818 */ + "\x32\x34\xe6\x97\xa5\0" /* offset 10824 */ + "\x32\x35\xe6\x97\xa5\0" /* offset 10830 */ + "\x32\x36\xe6\x97\xa5\0" /* offset 10836 */ + "\x32\x37\xe6\x97\xa5\0" /* offset 10842 */ + "\x32\x38\xe6\x97\xa5\0" /* offset 10848 */ + "\x32\x39\xe6\x97\xa5\0" /* offset 10854 */ + "\x33\x30\xe6\x97\xa5\0" /* offset 10860 */ + "\x33\x31\xe6\x97\xa5\0" /* offset 10866 */ + "\x67\x61\x6c\0" /* offset 10872 */ + "\xea\x9d\xaf\0" /* offset 10876 */ + "\xe8\xb1\x88\0" /* offset 10880 */ + "\xe6\x9b\xb4\0" /* offset 10884 */ + "\xe8\xb3\x88\0" /* offset 10888 */ + "\xe6\xbb\x91\0" /* offset 10892 */ + "\xe4\xb8\xb2\0" /* offset 10896 */ + "\xe5\x8f\xa5\0" /* offset 10900 */ + "\xe5\xa5\x91\0" /* offset 10904 */ + "\xe5\x96\x87\0" /* offset 10908 */ + "\xe5\xa5\x88\0" /* offset 10912 */ + "\xe6\x87\xb6\0" /* offset 10916 */ + "\xe7\x99\xa9\0" /* offset 10920 */ + "\xe7\xbe\x85\0" /* offset 10924 */ + "\xe8\x98\xbf\0" /* offset 10928 */ + "\xe8\x9e\xba\0" /* offset 10932 */ + "\xe8\xa3\xb8\0" /* offset 10936 */ + "\xe9\x82\x8f\0" /* offset 10940 */ + "\xe6\xa8\x82\0" /* offset 10944 */ + "\xe6\xb4\x9b\0" /* offset 10948 */ + "\xe7\x83\x99\0" /* offset 10952 */ + "\xe7\x8f\x9e\0" /* offset 10956 */ + "\xe8\x90\xbd\0" /* offset 10960 */ + "\xe9\x85\xaa\0" /* offset 10964 */ + "\xe9\xa7\xb1\0" /* offset 10968 */ + "\xe4\xba\x82\0" /* offset 10972 */ + "\xe5\x8d\xb5\0" /* offset 10976 */ + "\xe6\xac\x84\0" /* offset 10980 */ + "\xe7\x88\x9b\0" /* offset 10984 */ + "\xe8\x98\xad\0" /* offset 10988 */ + "\xe9\xb8\x9e\0" /* offset 10992 */ + "\xe5\xb5\x90\0" /* offset 10996 */ + "\xe6\xbf\xab\0" /* offset 11000 */ + "\xe8\x97\x8d\0" /* offset 11004 */ + "\xe8\xa5\xa4\0" /* offset 11008 */ + "\xe6\x8b\x89\0" /* offset 11012 */ + "\xe8\x87\x98\0" /* offset 11016 */ + "\xe8\xa0\x9f\0" /* offset 11020 */ + "\xe5\xbb\x8a\0" /* offset 11024 */ + "\xe6\x9c\x97\0" /* offset 11028 */ + "\xe6\xb5\xaa\0" /* offset 11032 */ + "\xe7\x8b\xbc\0" /* offset 11036 */ + "\xe9\x83\x8e\0" /* offset 11040 */ + "\xe4\xbe\x86\0" /* offset 11044 */ + "\xe5\x86\xb7\0" /* offset 11048 */ + "\xe5\x8b\x9e\0" /* offset 11052 */ + "\xe6\x93\x84\0" /* offset 11056 */ + "\xe6\xab\x93\0" /* offset 11060 */ + "\xe7\x88\x90\0" /* offset 11064 */ + "\xe7\x9b\xa7\0" /* offset 11068 */ + "\xe8\x98\x86\0" /* offset 11072 */ + "\xe8\x99\x9c\0" /* offset 11076 */ + "\xe8\xb7\xaf\0" /* offset 11080 */ + "\xe9\x9c\xb2\0" /* offset 11084 */ + "\xe9\xad\xaf\0" /* offset 11088 */ + "\xe9\xb7\xba\0" /* offset 11092 */ + "\xe7\xa2\x8c\0" /* offset 11096 */ + "\xe7\xa5\xbf\0" /* offset 11100 */ + "\xe7\xb6\xa0\0" /* offset 11104 */ + "\xe8\x8f\x89\0" /* offset 11108 */ + "\xe9\x8c\x84\0" /* offset 11112 */ + "\xe8\xab\x96\0" /* offset 11116 */ + "\xe5\xa3\x9f\0" /* offset 11120 */ + "\xe5\xbc\x84\0" /* offset 11124 */ + "\xe7\xb1\xa0\0" /* offset 11128 */ + "\xe8\x81\xbe\0" /* offset 11132 */ + "\xe7\x89\xa2\0" /* offset 11136 */ + "\xe7\xa3\x8a\0" /* offset 11140 */ + "\xe8\xb3\x82\0" /* offset 11144 */ + "\xe9\x9b\xb7\0" /* offset 11148 */ + "\xe5\xa3\x98\0" /* offset 11152 */ + "\xe5\xb1\xa2\0" /* offset 11156 */ + "\xe6\xa8\x93\0" /* offset 11160 */ + "\xe6\xb7\x9a\0" /* offset 11164 */ + "\xe6\xbc\x8f\0" /* offset 11168 */ + "\xe7\xb4\xaf\0" /* offset 11172 */ + "\xe7\xb8\xb7\0" /* offset 11176 */ + "\xe9\x99\x8b\0" /* offset 11180 */ + "\xe5\x8b\x92\0" /* offset 11184 */ + "\xe8\x82\x8b\0" /* offset 11188 */ + "\xe5\x87\x9c\0" /* offset 11192 */ + "\xe5\x87\x8c\0" /* offset 11196 */ + "\xe7\xa8\x9c\0" /* offset 11200 */ + "\xe7\xb6\xbe\0" /* offset 11204 */ + "\xe8\x8f\xb1\0" /* offset 11208 */ + "\xe9\x99\xb5\0" /* offset 11212 */ + "\xe8\xae\x80\0" /* offset 11216 */ + "\xe6\x8b\x8f\0" /* offset 11220 */ + "\xe8\xab\xbe\0" /* offset 11224 */ + "\xe4\xb8\xb9\0" /* offset 11228 */ + "\xe5\xaf\xa7\0" /* offset 11232 */ + "\xe6\x80\x92\0" /* offset 11236 */ + "\xe7\x8e\x87\0" /* offset 11240 */ + "\xe7\x95\xb0\0" /* offset 11244 */ + "\xe5\x8c\x97\0" /* offset 11248 */ + "\xe7\xa3\xbb\0" /* offset 11252 */ + "\xe4\xbe\xbf\0" /* offset 11256 */ + "\xe5\xbe\xa9\0" /* offset 11260 */ + "\xe4\xb8\x8d\0" /* offset 11264 */ + "\xe6\xb3\x8c\0" /* offset 11268 */ + "\xe6\x95\xb8\0" /* offset 11272 */ + "\xe7\xb4\xa2\0" /* offset 11276 */ + "\xe5\x8f\x83\0" /* offset 11280 */ + "\xe5\xa1\x9e\0" /* offset 11284 */ + "\xe7\x9c\x81\0" /* offset 11288 */ + "\xe8\x91\x89\0" /* offset 11292 */ + "\xe8\xaa\xaa\0" /* offset 11296 */ + "\xe6\xae\xba\0" /* offset 11300 */ + "\xe6\xb2\x88\0" /* offset 11304 */ + "\xe6\x8b\xbe\0" /* offset 11308 */ + "\xe8\x8b\xa5\0" /* offset 11312 */ + "\xe6\x8e\xa0\0" /* offset 11316 */ + "\xe7\x95\xa5\0" /* offset 11320 */ + "\xe4\xba\xae\0" /* offset 11324 */ + "\xe5\x85\xa9\0" /* offset 11328 */ + "\xe5\x87\x89\0" /* offset 11332 */ + "\xe6\xa2\x81\0" /* offset 11336 */ + "\xe7\xb3\xa7\0" /* offset 11340 */ + "\xe8\x89\xaf\0" /* offset 11344 */ + "\xe8\xab\x92\0" /* offset 11348 */ + "\xe9\x87\x8f\0" /* offset 11352 */ + "\xe5\x8b\xb5\0" /* offset 11356 */ + "\xe5\x91\x82\0" /* offset 11360 */ + "\xe5\xbb\xac\0" /* offset 11364 */ + "\xe6\x97\x85\0" /* offset 11368 */ + "\xe6\xbf\xbe\0" /* offset 11372 */ + "\xe7\xa4\xaa\0" /* offset 11376 */ + "\xe9\x96\xad\0" /* offset 11380 */ + "\xe9\xa9\xaa\0" /* offset 11384 */ + "\xe9\xba\x97\0" /* offset 11388 */ + "\xe9\xbb\x8e\0" /* offset 11392 */ + "\xe6\x9b\x86\0" /* offset 11396 */ + "\xe6\xad\xb7\0" /* offset 11400 */ + "\xe8\xbd\xa2\0" /* offset 11404 */ + "\xe5\xb9\xb4\0" /* offset 11408 */ + "\xe6\x86\x90\0" /* offset 11412 */ + "\xe6\x88\x80\0" /* offset 11416 */ + "\xe6\x92\x9a\0" /* offset 11420 */ + "\xe6\xbc\xa3\0" /* offset 11424 */ + "\xe7\x85\x89\0" /* offset 11428 */ + "\xe7\x92\x89\0" /* offset 11432 */ + "\xe7\xa7\x8a\0" /* offset 11436 */ + "\xe7\xb7\xb4\0" /* offset 11440 */ + "\xe8\x81\xaf\0" /* offset 11444 */ + "\xe8\xbc\xa6\0" /* offset 11448 */ + "\xe8\x93\xae\0" /* offset 11452 */ + "\xe9\x80\xa3\0" /* offset 11456 */ + "\xe9\x8d\x8a\0" /* offset 11460 */ + "\xe5\x88\x97\0" /* offset 11464 */ + "\xe5\x8a\xa3\0" /* offset 11468 */ + "\xe5\x92\xbd\0" /* offset 11472 */ + "\xe7\x83\x88\0" /* offset 11476 */ + "\xe8\xa3\x82\0" /* offset 11480 */ + "\xe5\xbb\x89\0" /* offset 11484 */ + "\xe5\xbf\xb5\0" /* offset 11488 */ + "\xe6\x8d\xbb\0" /* offset 11492 */ + "\xe6\xae\xae\0" /* offset 11496 */ + "\xe7\xb0\xbe\0" /* offset 11500 */ + "\xe7\x8d\xb5\0" /* offset 11504 */ + "\xe4\xbb\xa4\0" /* offset 11508 */ + "\xe5\x9b\xb9\0" /* offset 11512 */ + "\xe5\xb6\xba\0" /* offset 11516 */ + "\xe6\x80\x9c\0" /* offset 11520 */ + "\xe7\x8e\xb2\0" /* offset 11524 */ + "\xe7\x91\xa9\0" /* offset 11528 */ + "\xe7\xbe\x9a\0" /* offset 11532 */ + "\xe8\x81\x86\0" /* offset 11536 */ + "\xe9\x88\xb4\0" /* offset 11540 */ + "\xe9\x9b\xb6\0" /* offset 11544 */ + "\xe9\x9d\x88\0" /* offset 11548 */ + "\xe9\xa0\x98\0" /* offset 11552 */ + "\xe4\xbe\x8b\0" /* offset 11556 */ + "\xe7\xa6\xae\0" /* offset 11560 */ + "\xe9\x86\xb4\0" /* offset 11564 */ + "\xe9\x9a\xb8\0" /* offset 11568 */ + "\xe6\x83\xa1\0" /* offset 11572 */ + "\xe4\xba\x86\0" /* offset 11576 */ + "\xe5\x83\x9a\0" /* offset 11580 */ + "\xe5\xaf\xae\0" /* offset 11584 */ + "\xe5\xb0\xbf\0" /* offset 11588 */ + "\xe6\x96\x99\0" /* offset 11592 */ + "\xe7\x87\x8e\0" /* offset 11596 */ + "\xe7\x99\x82\0" /* offset 11600 */ + "\xe8\x93\xbc\0" /* offset 11604 */ + "\xe9\x81\xbc\0" /* offset 11608 */ + "\xe6\x9a\x88\0" /* offset 11612 */ + "\xe9\x98\xae\0" /* offset 11616 */ + "\xe5\x8a\x89\0" /* offset 11620 */ + "\xe6\x9d\xbb\0" /* offset 11624 */ + "\xe6\x9f\xb3\0" /* offset 11628 */ + "\xe6\xb5\x81\0" /* offset 11632 */ + "\xe6\xba\x9c\0" /* offset 11636 */ + "\xe7\x90\x89\0" /* offset 11640 */ + "\xe7\x95\x99\0" /* offset 11644 */ + "\xe7\xa1\xab\0" /* offset 11648 */ + "\xe7\xb4\x90\0" /* offset 11652 */ + "\xe9\xa1\x9e\0" /* offset 11656 */ + "\xe6\x88\xae\0" /* offset 11660 */ + "\xe9\x99\xb8\0" /* offset 11664 */ + "\xe5\x80\xab\0" /* offset 11668 */ + "\xe5\xb4\x99\0" /* offset 11672 */ + "\xe6\xb7\xaa\0" /* offset 11676 */ + "\xe8\xbc\xaa\0" /* offset 11680 */ + "\xe5\xbe\x8b\0" /* offset 11684 */ + "\xe6\x85\x84\0" /* offset 11688 */ + "\xe6\xa0\x97\0" /* offset 11692 */ + "\xe9\x9a\x86\0" /* offset 11696 */ + "\xe5\x88\xa9\0" /* offset 11700 */ + "\xe5\x90\x8f\0" /* offset 11704 */ + "\xe5\xb1\xa5\0" /* offset 11708 */ + "\xe6\x98\x93\0" /* offset 11712 */ + "\xe6\x9d\x8e\0" /* offset 11716 */ + "\xe6\xa2\xa8\0" /* offset 11720 */ + "\xe6\xb3\xa5\0" /* offset 11724 */ + "\xe7\x90\x86\0" /* offset 11728 */ + "\xe7\x97\xa2\0" /* offset 11732 */ + "\xe7\xbd\xb9\0" /* offset 11736 */ + "\xe8\xa3\x8f\0" /* offset 11740 */ + "\xe8\xa3\xa1\0" /* offset 11744 */ + "\xe9\x9b\xa2\0" /* offset 11748 */ + "\xe5\x8c\xbf\0" /* offset 11752 */ + "\xe6\xba\xba\0" /* offset 11756 */ + "\xe5\x90\x9d\0" /* offset 11760 */ + "\xe7\x87\x90\0" /* offset 11764 */ + "\xe7\x92\x98\0" /* offset 11768 */ + "\xe8\x97\xba\0" /* offset 11772 */ + "\xe9\x9a\xa3\0" /* offset 11776 */ + "\xe9\xb1\x97\0" /* offset 11780 */ + "\xe9\xba\x9f\0" /* offset 11784 */ + "\xe6\x9e\x97\0" /* offset 11788 */ + "\xe6\xb7\x8b\0" /* offset 11792 */ + "\xe8\x87\xa8\0" /* offset 11796 */ + "\xe7\xac\xa0\0" /* offset 11800 */ + "\xe7\xb2\x92\0" /* offset 11804 */ + "\xe7\x8b\x80\0" /* offset 11808 */ + "\xe7\x82\x99\0" /* offset 11812 */ + "\xe8\xad\x98\0" /* offset 11816 */ + "\xe4\xbb\x80\0" /* offset 11820 */ + "\xe8\x8c\xb6\0" /* offset 11824 */ + "\xe5\x88\xba\0" /* offset 11828 */ + "\xe5\x88\x87\0" /* offset 11832 */ + "\xe5\xba\xa6\0" /* offset 11836 */ + "\xe6\x8b\x93\0" /* offset 11840 */ + "\xe7\xb3\x96\0" /* offset 11844 */ + "\xe5\xae\x85\0" /* offset 11848 */ + "\xe6\xb4\x9e\0" /* offset 11852 */ + "\xe6\x9a\xb4\0" /* offset 11856 */ + "\xe8\xbc\xbb\0" /* offset 11860 */ + "\xe9\x99\x8d\0" /* offset 11864 */ + "\xe5\xbb\x93\0" /* offset 11868 */ + "\xe5\x85\x80\0" /* offset 11872 */ + "\xe5\x97\x80\0" /* offset 11876 */ + "\xe5\xa1\x9a\0" /* offset 11880 */ + "\xe6\x99\xb4\0" /* offset 11884 */ + "\xe5\x87\x9e\0" /* offset 11888 */ + "\xe7\x8c\xaa\0" /* offset 11892 */ + "\xe7\x9b\x8a\0" /* offset 11896 */ + "\xe7\xa4\xbc\0" /* offset 11900 */ + "\xe7\xa5\x9e\0" /* offset 11904 */ + "\xe7\xa5\xa5\0" /* offset 11908 */ + "\xe7\xa6\x8f\0" /* offset 11912 */ + "\xe9\x9d\x96\0" /* offset 11916 */ + "\xe7\xb2\xbe\0" /* offset 11920 */ + "\xe8\x98\x92\0" /* offset 11924 */ + "\xe8\xab\xb8\0" /* offset 11928 */ + "\xe9\x80\xb8\0" /* offset 11932 */ + "\xe9\x83\xbd\0" /* offset 11936 */ + "\xe9\xa3\xaf\0" /* offset 11940 */ + "\xe9\xa3\xbc\0" /* offset 11944 */ + "\xe9\xa4\xa8\0" /* offset 11948 */ + "\xe9\xb6\xb4\0" /* offset 11952 */ + "\xe4\xbe\xae\0" /* offset 11956 */ + "\xe5\x83\xa7\0" /* offset 11960 */ + "\xe5\x85\x8d\0" /* offset 11964 */ + "\xe5\x8b\x89\0" /* offset 11968 */ + "\xe5\x8b\xa4\0" /* offset 11972 */ + "\xe5\x8d\x91\0" /* offset 11976 */ + "\xe5\x96\x9d\0" /* offset 11980 */ + "\xe5\x98\x86\0" /* offset 11984 */ + "\xe5\x99\xa8\0" /* offset 11988 */ + "\xe5\xa1\x80\0" /* offset 11992 */ + "\xe5\xa2\xa8\0" /* offset 11996 */ + "\xe5\xb1\xa4\0" /* offset 12000 */ + "\xe6\x82\x94\0" /* offset 12004 */ + "\xe6\x85\xa8\0" /* offset 12008 */ + "\xe6\x86\x8e\0" /* offset 12012 */ + "\xe6\x87\xb2\0" /* offset 12016 */ + "\xe6\x95\x8f\0" /* offset 12020 */ + "\xe6\x97\xa2\0" /* offset 12024 */ + "\xe6\x9a\x91\0" /* offset 12028 */ + "\xe6\xa2\x85\0" /* offset 12032 */ + "\xe6\xb5\xb7\0" /* offset 12036 */ + "\xe6\xb8\x9a\0" /* offset 12040 */ + "\xe6\xbc\xa2\0" /* offset 12044 */ + "\xe7\x85\xae\0" /* offset 12048 */ + "\xe7\x88\xab\0" /* offset 12052 */ + "\xe7\x90\xa2\0" /* offset 12056 */ + "\xe7\xa2\x91\0" /* offset 12060 */ + "\xe7\xa5\x89\0" /* offset 12064 */ + "\xe7\xa5\x88\0" /* offset 12068 */ + "\xe7\xa5\x90\0" /* offset 12072 */ + "\xe7\xa5\x96\0" /* offset 12076 */ + "\xe7\xa6\x8d\0" /* offset 12080 */ + "\xe7\xa6\x8e\0" /* offset 12084 */ + "\xe7\xa9\x80\0" /* offset 12088 */ + "\xe7\xaa\x81\0" /* offset 12092 */ + "\xe7\xaf\x80\0" /* offset 12096 */ + "\xe7\xb8\x89\0" /* offset 12100 */ + "\xe7\xb9\x81\0" /* offset 12104 */ + "\xe7\xbd\xb2\0" /* offset 12108 */ + "\xe8\x80\x85\0" /* offset 12112 */ + "\xe8\x87\xad\0" /* offset 12116 */ + "\xe8\x89\xb9\0" /* offset 12120 */ + "\xe8\x91\x97\0" /* offset 12124 */ + "\xe8\xa4\x90\0" /* offset 12128 */ + "\xe8\xa6\x96\0" /* offset 12132 */ + "\xe8\xac\x81\0" /* offset 12136 */ + "\xe8\xac\xb9\0" /* offset 12140 */ + "\xe8\xb3\x93\0" /* offset 12144 */ + "\xe8\xb4\x88\0" /* offset 12148 */ + "\xe8\xbe\xb6\0" /* offset 12152 */ + "\xe9\x9b\xa3\0" /* offset 12156 */ + "\xe9\x9f\xbf\0" /* offset 12160 */ + "\xe9\xa0\xbb\0" /* offset 12164 */ + "\xe6\x81\xb5\0" /* offset 12168 */ + "\xf0\xa4\x8b\xae\0" /* offset 12172 */ + "\xe8\x88\x98\0" /* offset 12177 */ + "\xe4\xb8\xa6\0" /* offset 12181 */ + "\xe5\x86\xb5\0" /* offset 12185 */ + "\xe5\x85\xa8\0" /* offset 12189 */ + "\xe4\xbe\x80\0" /* offset 12193 */ + "\xe5\x85\x85\0" /* offset 12197 */ + "\xe5\x86\x80\0" /* offset 12201 */ + "\xe5\x8b\x87\0" /* offset 12205 */ + "\xe5\x8b\xba\0" /* offset 12209 */ + "\xe5\x95\x95\0" /* offset 12213 */ + "\xe5\x96\x99\0" /* offset 12217 */ + "\xe5\x97\xa2\0" /* offset 12221 */ + "\xe5\xa2\xb3\0" /* offset 12225 */ + "\xe5\xa5\x84\0" /* offset 12229 */ + "\xe5\xa5\x94\0" /* offset 12233 */ + "\xe5\xa9\xa2\0" /* offset 12237 */ + "\xe5\xac\xa8\0" /* offset 12241 */ + "\xe5\xbb\x92\0" /* offset 12245 */ + "\xe5\xbb\x99\0" /* offset 12249 */ + "\xe5\xbd\xa9\0" /* offset 12253 */ + "\xe5\xbe\xad\0" /* offset 12257 */ + "\xe6\x83\x98\0" /* offset 12261 */ + "\xe6\x85\x8e\0" /* offset 12265 */ + "\xe6\x84\x88\0" /* offset 12269 */ + "\xe6\x85\xa0\0" /* offset 12273 */ + "\xe6\x88\xb4\0" /* offset 12277 */ + "\xe6\x8f\x84\0" /* offset 12281 */ + "\xe6\x90\x9c\0" /* offset 12285 */ + "\xe6\x91\x92\0" /* offset 12289 */ + "\xe6\x95\x96\0" /* offset 12293 */ + "\xe6\x9c\x9b\0" /* offset 12297 */ + "\xe6\x9d\x96\0" /* offset 12301 */ + "\xe6\xbb\x9b\0" /* offset 12305 */ + "\xe6\xbb\x8b\0" /* offset 12309 */ + "\xe7\x80\x9e\0" /* offset 12313 */ + "\xe7\x9e\xa7\0" /* offset 12317 */ + "\xe7\x88\xb5\0" /* offset 12321 */ + "\xe7\x8a\xaf\0" /* offset 12325 */ + "\xe7\x91\xb1\0" /* offset 12329 */ + "\xe7\x94\x86\0" /* offset 12333 */ + "\xe7\x94\xbb\0" /* offset 12337 */ + "\xe7\x98\x9d\0" /* offset 12341 */ + "\xe7\x98\x9f\0" /* offset 12345 */ + "\xe7\x9b\x9b\0" /* offset 12349 */ + "\xe7\x9b\xb4\0" /* offset 12353 */ + "\xe7\x9d\x8a\0" /* offset 12357 */ + "\xe7\x9d\x80\0" /* offset 12361 */ + "\xe7\xa3\x8c\0" /* offset 12365 */ + "\xe7\xaa\xb1\0" /* offset 12369 */ + "\xe7\xb1\xbb\0" /* offset 12373 */ + "\xe7\xb5\x9b\0" /* offset 12377 */ + "\xe7\xbc\xbe\0" /* offset 12381 */ + "\xe8\x8d\x92\0" /* offset 12385 */ + "\xe8\x8f\xaf\0" /* offset 12389 */ + "\xe8\x9d\xb9\0" /* offset 12393 */ + "\xe8\xa5\x81\0" /* offset 12397 */ + "\xe8\xa6\x86\0" /* offset 12401 */ + "\xe8\xaa\xbf\0" /* offset 12405 */ + "\xe8\xab\x8b\0" /* offset 12409 */ + "\xe8\xab\xad\0" /* offset 12413 */ + "\xe8\xae\x8a\0" /* offset 12417 */ + "\xe8\xbc\xb8\0" /* offset 12421 */ + "\xe9\x81\xb2\0" /* offset 12425 */ + "\xe9\x86\x99\0" /* offset 12429 */ + "\xe9\x89\xb6\0" /* offset 12433 */ + "\xe9\x99\xbc\0" /* offset 12437 */ + "\xe9\x9f\x9b\0" /* offset 12441 */ + "\xe9\xa0\x8b\0" /* offset 12445 */ + "\xe9\xac\x92\0" /* offset 12449 */ + "\xf0\xa2\xa1\x8a\0" /* offset 12453 */ + "\xf0\xa2\xa1\x84\0" /* offset 12458 */ + "\xf0\xa3\x8f\x95\0" /* offset 12463 */ + "\xe3\xae\x9d\0" /* offset 12468 */ + "\xe4\x80\x98\0" /* offset 12472 */ + "\xe4\x80\xb9\0" /* offset 12476 */ + "\xf0\xa5\x89\x89\0" /* offset 12480 */ + "\xf0\xa5\xb3\x90\0" /* offset 12485 */ + "\xf0\xa7\xbb\x93\0" /* offset 12490 */ + "\xe9\xbd\x83\0" /* offset 12495 */ + "\xe9\xbe\x8e\0" /* offset 12499 */ + "\x66\x66\0" /* offset 12503 */ + "\x66\x69\0" /* offset 12506 */ + "\x66\x6c\0" /* offset 12509 */ + "\x66\x66\x69\0" /* offset 12512 */ + "\x66\x66\x6c\0" /* offset 12516 */ + "\x73\x74\0" /* offset 12520 */ + "\xd5\xb4\xd5\xb6\0" /* offset 12523 */ + "\xd5\xb4\xd5\xa5\0" /* offset 12528 */ + "\xd5\xb4\xd5\xab\0" /* offset 12533 */ + "\xd5\xbe\xd5\xb6\0" /* offset 12538 */ + "\xd5\xb4\xd5\xad\0" /* offset 12543 */ + "\xd7\x99\xd6\xb4\0" /* offset 12548 */ + "\xd7\xb2\xd6\xb7\0" /* offset 12553 */ + "\xd7\xa2\0" /* offset 12558 */ + "\xd7\x94\0" /* offset 12561 */ + "\xd7\x9b\0" /* offset 12564 */ + "\xd7\x9c\0" /* offset 12567 */ + "\xd7\x9d\0" /* offset 12570 */ + "\xd7\xa8\0" /* offset 12573 */ + "\xd7\xaa\0" /* offset 12576 */ + "\xd7\xa9\xd7\x81\0" /* offset 12579 */ + "\xd7\xa9\xd7\x82\0" /* offset 12584 */ + "\xd7\xa9\xd6\xbc\xd7\x81\0" /* offset 12589 */ + "\xd7\xa9\xd6\xbc\xd7\x82\0" /* offset 12596 */ + "\xd7\x90\xd6\xb7\0" /* offset 12603 */ + "\xd7\x90\xd6\xb8\0" /* offset 12608 */ + "\xd7\x90\xd6\xbc\0" /* offset 12613 */ + "\xd7\x91\xd6\xbc\0" /* offset 12618 */ + "\xd7\x92\xd6\xbc\0" /* offset 12623 */ + "\xd7\x93\xd6\xbc\0" /* offset 12628 */ + "\xd7\x94\xd6\xbc\0" /* offset 12633 */ + "\xd7\x95\xd6\xbc\0" /* offset 12638 */ + "\xd7\x96\xd6\xbc\0" /* offset 12643 */ + "\xd7\x98\xd6\xbc\0" /* offset 12648 */ + "\xd7\x99\xd6\xbc\0" /* offset 12653 */ + "\xd7\x9a\xd6\xbc\0" /* offset 12658 */ + "\xd7\x9b\xd6\xbc\0" /* offset 12663 */ + "\xd7\x9c\xd6\xbc\0" /* offset 12668 */ + "\xd7\x9e\xd6\xbc\0" /* offset 12673 */ + "\xd7\xa0\xd6\xbc\0" /* offset 12678 */ + "\xd7\xa1\xd6\xbc\0" /* offset 12683 */ + "\xd7\xa3\xd6\xbc\0" /* offset 12688 */ + "\xd7\xa4\xd6\xbc\0" /* offset 12693 */ + "\xd7\xa6\xd6\xbc\0" /* offset 12698 */ + "\xd7\xa7\xd6\xbc\0" /* offset 12703 */ + "\xd7\xa8\xd6\xbc\0" /* offset 12708 */ + "\xd7\xa9\xd6\xbc\0" /* offset 12713 */ + "\xd7\xaa\xd6\xbc\0" /* offset 12718 */ + "\xd7\x95\xd6\xb9\0" /* offset 12723 */ + "\xd7\x91\xd6\xbf\0" /* offset 12728 */ + "\xd7\x9b\xd6\xbf\0" /* offset 12733 */ + "\xd7\xa4\xd6\xbf\0" /* offset 12738 */ + "\xd7\x90\xd7\x9c\0" /* offset 12743 */ + "\xd9\xb1\0" /* offset 12748 */ + "\xd9\xbb\0" /* offset 12751 */ + "\xd9\xbe\0" /* offset 12754 */ + "\xda\x80\0" /* offset 12757 */ + "\xd9\xba\0" /* offset 12760 */ + "\xd9\xbf\0" /* offset 12763 */ + "\xd9\xb9\0" /* offset 12766 */ + "\xda\xa4\0" /* offset 12769 */ + "\xda\xa6\0" /* offset 12772 */ + "\xda\x84\0" /* offset 12775 */ + "\xda\x83\0" /* offset 12778 */ + "\xda\x86\0" /* offset 12781 */ + "\xda\x87\0" /* offset 12784 */ + "\xda\x8d\0" /* offset 12787 */ + "\xda\x8c\0" /* offset 12790 */ + "\xda\x8e\0" /* offset 12793 */ + "\xda\x88\0" /* offset 12796 */ + "\xda\x98\0" /* offset 12799 */ + "\xda\x91\0" /* offset 12802 */ + "\xda\xa9\0" /* offset 12805 */ + "\xda\xaf\0" /* offset 12808 */ + "\xda\xb3\0" /* offset 12811 */ + "\xda\xb1\0" /* offset 12814 */ + "\xda\xba\0" /* offset 12817 */ + "\xda\xbb\0" /* offset 12820 */ + "\xdb\x81\0" /* offset 12823 */ + "\xda\xbe\0" /* offset 12826 */ + "\xdb\x92\0" /* offset 12829 */ + "\xda\xad\0" /* offset 12832 */ + "\xdb\x87\0" /* offset 12835 */ + "\xdb\x86\0" /* offset 12838 */ + "\xdb\x88\0" /* offset 12841 */ + "\xdb\x8b\0" /* offset 12844 */ + "\xdb\x85\0" /* offset 12847 */ + "\xdb\x89\0" /* offset 12850 */ + "\xdb\x90\0" /* offset 12853 */ + "\xd9\x89\0" /* offset 12856 */ + "\xd9\x8a\xd9\x94\xd8\xa7\0" /* offset 12859 */ + "\xd9\x8a\xd9\x94\xdb\x95\0" /* offset 12866 */ + "\xd9\x8a\xd9\x94\xd9\x88\0" /* offset 12873 */ + "\xd9\x8a\xd9\x94\xdb\x87\0" /* offset 12880 */ + "\xd9\x8a\xd9\x94\xdb\x86\0" /* offset 12887 */ + "\xd9\x8a\xd9\x94\xdb\x88\0" /* offset 12894 */ + "\xd9\x8a\xd9\x94\xdb\x90\0" /* offset 12901 */ + "\xd9\x8a\xd9\x94\xd9\x89\0" /* offset 12908 */ + "\xdb\x8c\0" /* offset 12915 */ + "\xd9\x8a\xd9\x94\xd8\xac\0" /* offset 12918 */ + "\xd9\x8a\xd9\x94\xd8\xad\0" /* offset 12925 */ + "\xd9\x8a\xd9\x94\xd9\x85\0" /* offset 12932 */ + "\xd9\x8a\xd9\x94\xd9\x8a\0" /* offset 12939 */ + "\xd8\xa8\xd8\xac\0" /* offset 12946 */ + "\xd8\xa8\xd8\xad\0" /* offset 12951 */ + "\xd8\xa8\xd8\xae\0" /* offset 12956 */ + "\xd8\xa8\xd9\x85\0" /* offset 12961 */ + "\xd8\xa8\xd9\x89\0" /* offset 12966 */ + "\xd8\xa8\xd9\x8a\0" /* offset 12971 */ + "\xd8\xaa\xd8\xac\0" /* offset 12976 */ + "\xd8\xaa\xd8\xad\0" /* offset 12981 */ + "\xd8\xaa\xd8\xae\0" /* offset 12986 */ + "\xd8\xaa\xd9\x85\0" /* offset 12991 */ + "\xd8\xaa\xd9\x89\0" /* offset 12996 */ + "\xd8\xaa\xd9\x8a\0" /* offset 13001 */ + "\xd8\xab\xd8\xac\0" /* offset 13006 */ + "\xd8\xab\xd9\x85\0" /* offset 13011 */ + "\xd8\xab\xd9\x89\0" /* offset 13016 */ + "\xd8\xab\xd9\x8a\0" /* offset 13021 */ + "\xd8\xac\xd8\xad\0" /* offset 13026 */ + "\xd8\xac\xd9\x85\0" /* offset 13031 */ + "\xd8\xad\xd8\xac\0" /* offset 13036 */ + "\xd8\xad\xd9\x85\0" /* offset 13041 */ + "\xd8\xae\xd8\xac\0" /* offset 13046 */ + "\xd8\xae\xd8\xad\0" /* offset 13051 */ + "\xd8\xae\xd9\x85\0" /* offset 13056 */ + "\xd8\xb3\xd8\xac\0" /* offset 13061 */ + "\xd8\xb3\xd8\xad\0" /* offset 13066 */ + "\xd8\xb3\xd8\xae\0" /* offset 13071 */ + "\xd8\xb3\xd9\x85\0" /* offset 13076 */ + "\xd8\xb5\xd8\xad\0" /* offset 13081 */ + "\xd8\xb5\xd9\x85\0" /* offset 13086 */ + "\xd8\xb6\xd8\xac\0" /* offset 13091 */ + "\xd8\xb6\xd8\xad\0" /* offset 13096 */ + "\xd8\xb6\xd8\xae\0" /* offset 13101 */ + "\xd8\xb6\xd9\x85\0" /* offset 13106 */ + "\xd8\xb7\xd8\xad\0" /* offset 13111 */ + "\xd8\xb7\xd9\x85\0" /* offset 13116 */ + "\xd8\xb8\xd9\x85\0" /* offset 13121 */ + "\xd8\xb9\xd8\xac\0" /* offset 13126 */ + "\xd8\xb9\xd9\x85\0" /* offset 13131 */ + "\xd8\xba\xd8\xac\0" /* offset 13136 */ + "\xd8\xba\xd9\x85\0" /* offset 13141 */ + "\xd9\x81\xd8\xac\0" /* offset 13146 */ + "\xd9\x81\xd8\xad\0" /* offset 13151 */ + "\xd9\x81\xd8\xae\0" /* offset 13156 */ + "\xd9\x81\xd9\x85\0" /* offset 13161 */ + "\xd9\x81\xd9\x89\0" /* offset 13166 */ + "\xd9\x81\xd9\x8a\0" /* offset 13171 */ + "\xd9\x82\xd8\xad\0" /* offset 13176 */ + "\xd9\x82\xd9\x85\0" /* offset 13181 */ + "\xd9\x82\xd9\x89\0" /* offset 13186 */ + "\xd9\x82\xd9\x8a\0" /* offset 13191 */ + "\xd9\x83\xd8\xa7\0" /* offset 13196 */ + "\xd9\x83\xd8\xac\0" /* offset 13201 */ + "\xd9\x83\xd8\xad\0" /* offset 13206 */ + "\xd9\x83\xd8\xae\0" /* offset 13211 */ + "\xd9\x83\xd9\x84\0" /* offset 13216 */ + "\xd9\x83\xd9\x85\0" /* offset 13221 */ + "\xd9\x83\xd9\x89\0" /* offset 13226 */ + "\xd9\x83\xd9\x8a\0" /* offset 13231 */ + "\xd9\x84\xd8\xac\0" /* offset 13236 */ + "\xd9\x84\xd8\xad\0" /* offset 13241 */ + "\xd9\x84\xd8\xae\0" /* offset 13246 */ + "\xd9\x84\xd9\x85\0" /* offset 13251 */ + "\xd9\x84\xd9\x89\0" /* offset 13256 */ + "\xd9\x84\xd9\x8a\0" /* offset 13261 */ + "\xd9\x85\xd8\xac\0" /* offset 13266 */ + "\xd9\x85\xd8\xad\0" /* offset 13271 */ + "\xd9\x85\xd8\xae\0" /* offset 13276 */ + "\xd9\x85\xd9\x85\0" /* offset 13281 */ + "\xd9\x85\xd9\x89\0" /* offset 13286 */ + "\xd9\x85\xd9\x8a\0" /* offset 13291 */ + "\xd9\x86\xd8\xac\0" /* offset 13296 */ + "\xd9\x86\xd8\xad\0" /* offset 13301 */ + "\xd9\x86\xd8\xae\0" /* offset 13306 */ + "\xd9\x86\xd9\x85\0" /* offset 13311 */ + "\xd9\x86\xd9\x89\0" /* offset 13316 */ + "\xd9\x86\xd9\x8a\0" /* offset 13321 */ + "\xd9\x87\xd8\xac\0" /* offset 13326 */ + "\xd9\x87\xd9\x85\0" /* offset 13331 */ + "\xd9\x87\xd9\x89\0" /* offset 13336 */ + "\xd9\x87\xd9\x8a\0" /* offset 13341 */ + "\xd9\x8a\xd8\xac\0" /* offset 13346 */ + "\xd9\x8a\xd8\xad\0" /* offset 13351 */ + "\xd9\x8a\xd8\xae\0" /* offset 13356 */ + "\xd9\x8a\xd9\x85\0" /* offset 13361 */ + "\xd9\x8a\xd9\x89\0" /* offset 13366 */ + "\xd9\x8a\xd9\x8a\0" /* offset 13371 */ + "\xd8\xb0\xd9\xb0\0" /* offset 13376 */ + "\xd8\xb1\xd9\xb0\0" /* offset 13381 */ + "\xd9\x89\xd9\xb0\0" /* offset 13386 */ + "\x20\xd9\x8c\xd9\x91\0" /* offset 13391 */ + "\x20\xd9\x8d\xd9\x91\0" /* offset 13397 */ + "\x20\xd9\x8e\xd9\x91\0" /* offset 13403 */ + "\x20\xd9\x8f\xd9\x91\0" /* offset 13409 */ + "\x20\xd9\x90\xd9\x91\0" /* offset 13415 */ + "\x20\xd9\x91\xd9\xb0\0" /* offset 13421 */ + "\xd9\x8a\xd9\x94\xd8\xb1\0" /* offset 13427 */ + "\xd9\x8a\xd9\x94\xd8\xb2\0" /* offset 13434 */ + "\xd9\x8a\xd9\x94\xd9\x86\0" /* offset 13441 */ + "\xd8\xa8\xd8\xb1\0" /* offset 13448 */ + "\xd8\xa8\xd8\xb2\0" /* offset 13453 */ + "\xd8\xa8\xd9\x86\0" /* offset 13458 */ + "\xd8\xaa\xd8\xb1\0" /* offset 13463 */ + "\xd8\xaa\xd8\xb2\0" /* offset 13468 */ + "\xd8\xaa\xd9\x86\0" /* offset 13473 */ + "\xd8\xab\xd8\xb1\0" /* offset 13478 */ + "\xd8\xab\xd8\xb2\0" /* offset 13483 */ + "\xd8\xab\xd9\x86\0" /* offset 13488 */ + "\xd9\x85\xd8\xa7\0" /* offset 13493 */ + "\xd9\x86\xd8\xb1\0" /* offset 13498 */ + "\xd9\x86\xd8\xb2\0" /* offset 13503 */ + "\xd9\x86\xd9\x86\0" /* offset 13508 */ + "\xd9\x8a\xd8\xb1\0" /* offset 13513 */ + "\xd9\x8a\xd8\xb2\0" /* offset 13518 */ + "\xd9\x8a\xd9\x86\0" /* offset 13523 */ + "\xd9\x8a\xd9\x94\xd8\xae\0" /* offset 13528 */ + "\xd9\x8a\xd9\x94\xd9\x87\0" /* offset 13535 */ + "\xd8\xa8\xd9\x87\0" /* offset 13542 */ + "\xd8\xaa\xd9\x87\0" /* offset 13547 */ + "\xd8\xb5\xd8\xae\0" /* offset 13552 */ + "\xd9\x84\xd9\x87\0" /* offset 13557 */ + "\xd9\x86\xd9\x87\0" /* offset 13562 */ + "\xd9\x87\xd9\xb0\0" /* offset 13567 */ + "\xd9\x8a\xd9\x87\0" /* offset 13572 */ + "\xd8\xab\xd9\x87\0" /* offset 13577 */ + "\xd8\xb3\xd9\x87\0" /* offset 13582 */ + "\xd8\xb4\xd9\x85\0" /* offset 13587 */ + "\xd8\xb4\xd9\x87\0" /* offset 13592 */ + "\xd9\x80\xd9\x8e\xd9\x91\0" /* offset 13597 */ + "\xd9\x80\xd9\x8f\xd9\x91\0" /* offset 13604 */ + "\xd9\x80\xd9\x90\xd9\x91\0" /* offset 13611 */ + "\xd8\xb7\xd9\x89\0" /* offset 13618 */ + "\xd8\xb7\xd9\x8a\0" /* offset 13623 */ + "\xd8\xb9\xd9\x89\0" /* offset 13628 */ + "\xd8\xb9\xd9\x8a\0" /* offset 13633 */ + "\xd8\xba\xd9\x89\0" /* offset 13638 */ + "\xd8\xba\xd9\x8a\0" /* offset 13643 */ + "\xd8\xb3\xd9\x89\0" /* offset 13648 */ + "\xd8\xb3\xd9\x8a\0" /* offset 13653 */ + "\xd8\xb4\xd9\x89\0" /* offset 13658 */ + "\xd8\xb4\xd9\x8a\0" /* offset 13663 */ + "\xd8\xad\xd9\x89\0" /* offset 13668 */ + "\xd8\xad\xd9\x8a\0" /* offset 13673 */ + "\xd8\xac\xd9\x89\0" /* offset 13678 */ + "\xd8\xac\xd9\x8a\0" /* offset 13683 */ + "\xd8\xae\xd9\x89\0" /* offset 13688 */ + "\xd8\xae\xd9\x8a\0" /* offset 13693 */ + "\xd8\xb5\xd9\x89\0" /* offset 13698 */ + "\xd8\xb5\xd9\x8a\0" /* offset 13703 */ + "\xd8\xb6\xd9\x89\0" /* offset 13708 */ + "\xd8\xb6\xd9\x8a\0" /* offset 13713 */ + "\xd8\xb4\xd8\xac\0" /* offset 13718 */ + "\xd8\xb4\xd8\xad\0" /* offset 13723 */ + "\xd8\xb4\xd8\xae\0" /* offset 13728 */ + "\xd8\xb4\xd8\xb1\0" /* offset 13733 */ + "\xd8\xb3\xd8\xb1\0" /* offset 13738 */ + "\xd8\xb5\xd8\xb1\0" /* offset 13743 */ + "\xd8\xb6\xd8\xb1\0" /* offset 13748 */ + "\xd8\xa7\xd9\x8b\0" /* offset 13753 */ + "\xd8\xaa\xd8\xac\xd9\x85\0" /* offset 13758 */ + "\xd8\xaa\xd8\xad\xd8\xac\0" /* offset 13765 */ + "\xd8\xaa\xd8\xad\xd9\x85\0" /* offset 13772 */ + "\xd8\xaa\xd8\xae\xd9\x85\0" /* offset 13779 */ + "\xd8\xaa\xd9\x85\xd8\xac\0" /* offset 13786 */ + "\xd8\xaa\xd9\x85\xd8\xad\0" /* offset 13793 */ + "\xd8\xaa\xd9\x85\xd8\xae\0" /* offset 13800 */ + "\xd8\xac\xd9\x85\xd8\xad\0" /* offset 13807 */ + "\xd8\xad\xd9\x85\xd9\x8a\0" /* offset 13814 */ + "\xd8\xad\xd9\x85\xd9\x89\0" /* offset 13821 */ + "\xd8\xb3\xd8\xad\xd8\xac\0" /* offset 13828 */ + "\xd8\xb3\xd8\xac\xd8\xad\0" /* offset 13835 */ + "\xd8\xb3\xd8\xac\xd9\x89\0" /* offset 13842 */ + "\xd8\xb3\xd9\x85\xd8\xad\0" /* offset 13849 */ + "\xd8\xb3\xd9\x85\xd8\xac\0" /* offset 13856 */ + "\xd8\xb3\xd9\x85\xd9\x85\0" /* offset 13863 */ + "\xd8\xb5\xd8\xad\xd8\xad\0" /* offset 13870 */ + "\xd8\xb5\xd9\x85\xd9\x85\0" /* offset 13877 */ + "\xd8\xb4\xd8\xad\xd9\x85\0" /* offset 13884 */ + "\xd8\xb4\xd8\xac\xd9\x8a\0" /* offset 13891 */ + "\xd8\xb4\xd9\x85\xd8\xae\0" /* offset 13898 */ + "\xd8\xb4\xd9\x85\xd9\x85\0" /* offset 13905 */ + "\xd8\xb6\xd8\xad\xd9\x89\0" /* offset 13912 */ + "\xd8\xb6\xd8\xae\xd9\x85\0" /* offset 13919 */ + "\xd8\xb7\xd9\x85\xd8\xad\0" /* offset 13926 */ + "\xd8\xb7\xd9\x85\xd9\x85\0" /* offset 13933 */ + "\xd8\xb7\xd9\x85\xd9\x8a\0" /* offset 13940 */ + "\xd8\xb9\xd8\xac\xd9\x85\0" /* offset 13947 */ + "\xd8\xb9\xd9\x85\xd9\x85\0" /* offset 13954 */ + "\xd8\xb9\xd9\x85\xd9\x89\0" /* offset 13961 */ + "\xd8\xba\xd9\x85\xd9\x85\0" /* offset 13968 */ + "\xd8\xba\xd9\x85\xd9\x8a\0" /* offset 13975 */ + "\xd8\xba\xd9\x85\xd9\x89\0" /* offset 13982 */ + "\xd9\x81\xd8\xae\xd9\x85\0" /* offset 13989 */ + "\xd9\x82\xd9\x85\xd8\xad\0" /* offset 13996 */ + "\xd9\x82\xd9\x85\xd9\x85\0" /* offset 14003 */ + "\xd9\x84\xd8\xad\xd9\x85\0" /* offset 14010 */ + "\xd9\x84\xd8\xad\xd9\x8a\0" /* offset 14017 */ + "\xd9\x84\xd8\xad\xd9\x89\0" /* offset 14024 */ + "\xd9\x84\xd8\xac\xd8\xac\0" /* offset 14031 */ + "\xd9\x84\xd8\xae\xd9\x85\0" /* offset 14038 */ + "\xd9\x84\xd9\x85\xd8\xad\0" /* offset 14045 */ + "\xd9\x85\xd8\xad\xd8\xac\0" /* offset 14052 */ + "\xd9\x85\xd8\xad\xd9\x85\0" /* offset 14059 */ + "\xd9\x85\xd8\xad\xd9\x8a\0" /* offset 14066 */ + "\xd9\x85\xd8\xac\xd8\xad\0" /* offset 14073 */ + "\xd9\x85\xd8\xac\xd9\x85\0" /* offset 14080 */ + "\xd9\x85\xd8\xae\xd8\xac\0" /* offset 14087 */ + "\xd9\x85\xd8\xae\xd9\x85\0" /* offset 14094 */ + "\xd9\x85\xd8\xac\xd8\xae\0" /* offset 14101 */ + "\xd9\x87\xd9\x85\xd8\xac\0" /* offset 14108 */ + "\xd9\x87\xd9\x85\xd9\x85\0" /* offset 14115 */ + "\xd9\x86\xd8\xad\xd9\x85\0" /* offset 14122 */ + "\xd9\x86\xd8\xad\xd9\x89\0" /* offset 14129 */ + "\xd9\x86\xd8\xac\xd9\x85\0" /* offset 14136 */ + "\xd9\x86\xd8\xac\xd9\x89\0" /* offset 14143 */ + "\xd9\x86\xd9\x85\xd9\x8a\0" /* offset 14150 */ + "\xd9\x86\xd9\x85\xd9\x89\0" /* offset 14157 */ + "\xd9\x8a\xd9\x85\xd9\x85\0" /* offset 14164 */ + "\xd8\xa8\xd8\xae\xd9\x8a\0" /* offset 14171 */ + "\xd8\xaa\xd8\xac\xd9\x8a\0" /* offset 14178 */ + "\xd8\xaa\xd8\xac\xd9\x89\0" /* offset 14185 */ + "\xd8\xaa\xd8\xae\xd9\x8a\0" /* offset 14192 */ + "\xd8\xaa\xd8\xae\xd9\x89\0" /* offset 14199 */ + "\xd8\xaa\xd9\x85\xd9\x8a\0" /* offset 14206 */ + "\xd8\xaa\xd9\x85\xd9\x89\0" /* offset 14213 */ + "\xd8\xac\xd9\x85\xd9\x8a\0" /* offset 14220 */ + "\xd8\xac\xd8\xad\xd9\x89\0" /* offset 14227 */ + "\xd8\xac\xd9\x85\xd9\x89\0" /* offset 14234 */ + "\xd8\xb3\xd8\xae\xd9\x89\0" /* offset 14241 */ + "\xd8\xb5\xd8\xad\xd9\x8a\0" /* offset 14248 */ + "\xd8\xb4\xd8\xad\xd9\x8a\0" /* offset 14255 */ + "\xd8\xb6\xd8\xad\xd9\x8a\0" /* offset 14262 */ + "\xd9\x84\xd8\xac\xd9\x8a\0" /* offset 14269 */ + "\xd9\x84\xd9\x85\xd9\x8a\0" /* offset 14276 */ + "\xd9\x8a\xd8\xad\xd9\x8a\0" /* offset 14283 */ + "\xd9\x8a\xd8\xac\xd9\x8a\0" /* offset 14290 */ + "\xd9\x8a\xd9\x85\xd9\x8a\0" /* offset 14297 */ + "\xd9\x85\xd9\x85\xd9\x8a\0" /* offset 14304 */ + "\xd9\x82\xd9\x85\xd9\x8a\0" /* offset 14311 */ + "\xd9\x86\xd8\xad\xd9\x8a\0" /* offset 14318 */ + "\xd8\xb9\xd9\x85\xd9\x8a\0" /* offset 14325 */ + "\xd9\x83\xd9\x85\xd9\x8a\0" /* offset 14332 */ + "\xd9\x86\xd8\xac\xd8\xad\0" /* offset 14339 */ + "\xd9\x85\xd8\xae\xd9\x8a\0" /* offset 14346 */ + "\xd9\x84\xd8\xac\xd9\x85\0" /* offset 14353 */ + "\xd9\x83\xd9\x85\xd9\x85\0" /* offset 14360 */ + "\xd8\xac\xd8\xad\xd9\x8a\0" /* offset 14367 */ + "\xd8\xad\xd8\xac\xd9\x8a\0" /* offset 14374 */ + "\xd9\x85\xd8\xac\xd9\x8a\0" /* offset 14381 */ + "\xd9\x81\xd9\x85\xd9\x8a\0" /* offset 14388 */ + "\xd8\xa8\xd8\xad\xd9\x8a\0" /* offset 14395 */ + "\xd8\xb3\xd8\xae\xd9\x8a\0" /* offset 14402 */ + "\xd9\x86\xd8\xac\xd9\x8a\0" /* offset 14409 */ + "\xd8\xb5\xd9\x84\xdb\x92\0" /* offset 14416 */ + "\xd9\x82\xd9\x84\xdb\x92\0" /* offset 14423 */ + "\xd8\xa7\xd9\x84\xd9\x84\xd9\x87\0" /* offset 14430 */ + "\xd8\xa7\xd9\x83\xd8\xa8\xd8\xb1\0" /* offset 14439 */ + "\xd9\x85\xd8\xad\xd9\x85\xd8\xaf\0" /* offset 14448 */ + "\xd8\xb5\xd9\x84\xd8\xb9\xd9\x85\0" /* offset 14457 */ + "\xd8\xb1\xd8\xb3\xd9\x88\xd9\x84\0" /* offset 14466 */ + "\xd8\xb9\xd9\x84\xd9\x8a\xd9\x87\0" /* offset 14475 */ + "\xd9\x88\xd8\xb3\xd9\x84\xd9\x85\0" /* offset 14484 */ + "\xd8\xb5\xd9\x84\xd9\x89\0" /* offset 14493 */ + "\xd8\xb5\xd9\x84\xd9\x89\x20\xd8\xa7\xd9\x84\xd9\x84\xd9\x87\x20\xd8\xb9\xd9\x84\xd9\x8a\xd9\x87\x20\xd9\x88\xd8\xb3\xd9\x84\xd9\x85\0" /* offset 14500 */ + "\xd8\xac\xd9\x84\x20\xd8\xac\xd9\x84\xd8\xa7\xd9\x84\xd9\x87\0" /* offset 14534 */ + "\xd8\xb1\xdb\x8c\xd8\xa7\xd9\x84\0" /* offset 14550 */ + "\x2c\0" /* offset 14559 */ + "\xe3\x80\x81\0" /* offset 14561 */ + "\xe3\x80\x82\0" /* offset 14565 */ + "\x3a\0" /* offset 14569 */ + "\x21\0" /* offset 14571 */ + "\x3f\0" /* offset 14573 */ + "\xe3\x80\x96\0" /* offset 14575 */ + "\xe3\x80\x97\0" /* offset 14579 */ + "\xe2\x80\x94\0" /* offset 14583 */ + "\xe2\x80\x93\0" /* offset 14587 */ + "\x5f\0" /* offset 14591 */ + "\x7b\0" /* offset 14593 */ + "\x7d\0" /* offset 14595 */ + "\xe3\x80\x94\0" /* offset 14597 */ + "\xe3\x80\x95\0" /* offset 14601 */ + "\xe3\x80\x90\0" /* offset 14605 */ + "\xe3\x80\x91\0" /* offset 14609 */ + "\xe3\x80\x8a\0" /* offset 14613 */ + "\xe3\x80\x8b\0" /* offset 14617 */ + "\xe3\x80\x8c\0" /* offset 14621 */ + "\xe3\x80\x8d\0" /* offset 14625 */ + "\xe3\x80\x8e\0" /* offset 14629 */ + "\xe3\x80\x8f\0" /* offset 14633 */ + "\x5b\0" /* offset 14637 */ + "\x5d\0" /* offset 14639 */ + "\x23\0" /* offset 14641 */ + "\x26\0" /* offset 14643 */ + "\x2a\0" /* offset 14645 */ + "\x2d\0" /* offset 14647 */ + "\x3c\0" /* offset 14649 */ + "\x3e\0" /* offset 14651 */ + "\x5c\0" /* offset 14653 */ + "\x24\0" /* offset 14655 */ + "\x25\0" /* offset 14657 */ + "\x40\0" /* offset 14659 */ + "\x20\xd9\x8b\0" /* offset 14661 */ + "\xd9\x80\xd9\x8b\0" /* offset 14665 */ + "\x20\xd9\x8c\0" /* offset 14670 */ + "\x20\xd9\x8d\0" /* offset 14674 */ + "\x20\xd9\x8e\0" /* offset 14678 */ + "\xd9\x80\xd9\x8e\0" /* offset 14682 */ + "\x20\xd9\x8f\0" /* offset 14687 */ + "\xd9\x80\xd9\x8f\0" /* offset 14691 */ + "\x20\xd9\x90\0" /* offset 14696 */ + "\xd9\x80\xd9\x90\0" /* offset 14700 */ + "\x20\xd9\x91\0" /* offset 14705 */ + "\xd9\x80\xd9\x91\0" /* offset 14709 */ + "\x20\xd9\x92\0" /* offset 14714 */ + "\xd9\x80\xd9\x92\0" /* offset 14718 */ + "\xd8\xa1\0" /* offset 14723 */ + "\xd8\xa7\0" /* offset 14726 */ + "\xd8\xa8\0" /* offset 14729 */ + "\xd8\xa9\0" /* offset 14732 */ + "\xd8\xaa\0" /* offset 14735 */ + "\xd8\xab\0" /* offset 14738 */ + "\xd8\xac\0" /* offset 14741 */ + "\xd8\xad\0" /* offset 14744 */ + "\xd8\xae\0" /* offset 14747 */ + "\xd8\xaf\0" /* offset 14750 */ + "\xd8\xb0\0" /* offset 14753 */ + "\xd8\xb1\0" /* offset 14756 */ + "\xd8\xb2\0" /* offset 14759 */ + "\xd8\xb3\0" /* offset 14762 */ + "\xd8\xb4\0" /* offset 14765 */ + "\xd8\xb5\0" /* offset 14768 */ + "\xd8\xb6\0" /* offset 14771 */ + "\xd8\xb7\0" /* offset 14774 */ + "\xd8\xb8\0" /* offset 14777 */ + "\xd8\xb9\0" /* offset 14780 */ + "\xd8\xba\0" /* offset 14783 */ + "\xd9\x81\0" /* offset 14786 */ + "\xd9\x82\0" /* offset 14789 */ + "\xd9\x83\0" /* offset 14792 */ + "\xd9\x84\0" /* offset 14795 */ + "\xd9\x85\0" /* offset 14798 */ + "\xd9\x86\0" /* offset 14801 */ + "\xd9\x87\0" /* offset 14804 */ + "\xd9\x88\0" /* offset 14807 */ + "\xd9\x8a\0" /* offset 14810 */ + "\xd9\x84\xd8\xa7\xd9\x93\0" /* offset 14813 */ + "\xd9\x84\xd8\xa7\xd9\x94\0" /* offset 14820 */ + "\xd9\x84\xd8\xa7\xd9\x95\0" /* offset 14827 */ + "\xd9\x84\xd8\xa7\0" /* offset 14834 */ + "\x22\0" /* offset 14839 */ + "\x27\0" /* offset 14841 */ + "\x2f\0" /* offset 14843 */ + "\x5e\0" /* offset 14845 */ + "\x7c\0" /* offset 14847 */ + "\x7e\0" /* offset 14849 */ + "\xe2\xa6\x85\0" /* offset 14851 */ + "\xe2\xa6\x86\0" /* offset 14855 */ + "\xe3\x83\xbb\0" /* offset 14859 */ + "\xe3\x82\xa1\0" /* offset 14863 */ + "\xe3\x82\xa3\0" /* offset 14867 */ + "\xe3\x82\xa5\0" /* offset 14871 */ + "\xe3\x82\xa7\0" /* offset 14875 */ + "\xe3\x82\xa9\0" /* offset 14879 */ + "\xe3\x83\xa3\0" /* offset 14883 */ + "\xe3\x83\xa5\0" /* offset 14887 */ + "\xe3\x83\xa7\0" /* offset 14891 */ + "\xe3\x83\x83\0" /* offset 14895 */ + "\xe3\x83\xbc\0" /* offset 14899 */ + "\xe3\x83\xb3\0" /* offset 14903 */ + "\xe3\x82\x99\0" /* offset 14907 */ + "\xe3\x82\x9a\0" /* offset 14911 */ + "\xc2\xa2\0" /* offset 14915 */ + "\xc2\xa3\0" /* offset 14918 */ + "\xc2\xac\0" /* offset 14921 */ + "\xc2\xa6\0" /* offset 14924 */ + "\xc2\xa5\0" /* offset 14927 */ + "\xe2\x82\xa9\0" /* offset 14930 */ + "\xe2\x94\x82\0" /* offset 14934 */ + "\xe2\x86\x90\0" /* offset 14938 */ + "\xe2\x86\x91\0" /* offset 14942 */ + "\xe2\x86\x92\0" /* offset 14946 */ + "\xe2\x86\x93\0" /* offset 14950 */ + "\xe2\x96\xa0\0" /* offset 14954 */ + "\xe2\x97\x8b\0" /* offset 14958 */ + "\xf0\x91\x82\x99\xf0\x91\x82\xba\0" /* offset 14962 */ + "\xf0\x91\x82\x9b\xf0\x91\x82\xba\0" /* offset 14971 */ + "\xf0\x91\x82\xa5\xf0\x91\x82\xba\0" /* offset 14980 */ + "\xf0\x9d\x85\x97\xf0\x9d\x85\xa5\0" /* offset 14989 */ + "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\0" /* offset 14998 */ + "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xae\0" /* offset 15007 */ + "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf\0" /* offset 15020 */ + "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb0\0" /* offset 15033 */ + "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb1\0" /* offset 15046 */ + "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb2\0" /* offset 15059 */ + "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5\0" /* offset 15072 */ + "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5\0" /* offset 15081 */ + "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5\xf0\x9d\x85\xae\0" /* offset 15090 */ + "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5\xf0\x9d\x85\xae\0" /* offset 15103 */ + "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf\0" /* offset 15116 */ + "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf\0" /* offset 15129 */ + "\xc4\xb1\0" /* offset 15142 */ + "\xc8\xb7\0" /* offset 15145 */ + "\xce\x91\0" /* offset 15148 */ + "\xce\x92\0" /* offset 15151 */ + "\xce\x94\0" /* offset 15154 */ + "\xce\x95\0" /* offset 15157 */ + "\xce\x96\0" /* offset 15160 */ + "\xce\x97\0" /* offset 15163 */ + "\xce\x99\0" /* offset 15166 */ + "\xce\x9a\0" /* offset 15169 */ + "\xce\x9b\0" /* offset 15172 */ + "\xce\x9c\0" /* offset 15175 */ + "\xce\x9d\0" /* offset 15178 */ + "\xce\x9e\0" /* offset 15181 */ + "\xce\x9f\0" /* offset 15184 */ + "\xce\xa1\0" /* offset 15187 */ + "\xce\xa4\0" /* offset 15190 */ + "\xce\xa6\0" /* offset 15193 */ + "\xce\xa7\0" /* offset 15196 */ + "\xce\xa8\0" /* offset 15199 */ + "\xe2\x88\x87\0" /* offset 15202 */ + "\xce\xb1\0" /* offset 15206 */ + "\xce\xb6\0" /* offset 15209 */ + "\xce\xb7\0" /* offset 15212 */ + "\xce\xbb\0" /* offset 15215 */ + "\xce\xbd\0" /* offset 15218 */ + "\xce\xbe\0" /* offset 15221 */ + "\xce\xbf\0" /* offset 15224 */ + "\xcf\x83\0" /* offset 15227 */ + "\xcf\x84\0" /* offset 15230 */ + "\xcf\x85\0" /* offset 15233 */ + "\xcf\x88\0" /* offset 15236 */ + "\xcf\x89\0" /* offset 15239 */ + "\xe2\x88\x82\0" /* offset 15242 */ + "\xcf\x9c\0" /* offset 15246 */ + "\xcf\x9d\0" /* offset 15249 */ + "\x30\x2e\0" /* offset 15252 */ + "\x30\x2c\0" /* offset 15255 */ + "\x31\x2c\0" /* offset 15258 */ + "\x32\x2c\0" /* offset 15261 */ + "\x33\x2c\0" /* offset 15264 */ + "\x34\x2c\0" /* offset 15267 */ + "\x35\x2c\0" /* offset 15270 */ + "\x36\x2c\0" /* offset 15273 */ + "\x37\x2c\0" /* offset 15276 */ + "\x38\x2c\0" /* offset 15279 */ + "\x39\x2c\0" /* offset 15282 */ + "\x28\x41\x29\0" /* offset 15285 */ + "\x28\x42\x29\0" /* offset 15289 */ + "\x28\x43\x29\0" /* offset 15293 */ + "\x28\x44\x29\0" /* offset 15297 */ + "\x28\x45\x29\0" /* offset 15301 */ + "\x28\x46\x29\0" /* offset 15305 */ + "\x28\x47\x29\0" /* offset 15309 */ + "\x28\x48\x29\0" /* offset 15313 */ + "\x28\x49\x29\0" /* offset 15317 */ + "\x28\x4a\x29\0" /* offset 15321 */ + "\x28\x4b\x29\0" /* offset 15325 */ + "\x28\x4c\x29\0" /* offset 15329 */ + "\x28\x4d\x29\0" /* offset 15333 */ + "\x28\x4e\x29\0" /* offset 15337 */ + "\x28\x4f\x29\0" /* offset 15341 */ + "\x28\x50\x29\0" /* offset 15345 */ + "\x28\x51\x29\0" /* offset 15349 */ + "\x28\x52\x29\0" /* offset 15353 */ + "\x28\x53\x29\0" /* offset 15357 */ + "\x28\x54\x29\0" /* offset 15361 */ + "\x28\x55\x29\0" /* offset 15365 */ + "\x28\x56\x29\0" /* offset 15369 */ + "\x28\x57\x29\0" /* offset 15373 */ + "\x28\x58\x29\0" /* offset 15377 */ + "\x28\x59\x29\0" /* offset 15381 */ + "\x28\x5a\x29\0" /* offset 15385 */ + "\xe3\x80\x94\x53\xe3\x80\x95\0" /* offset 15389 */ + "\x43\x44\0" /* offset 15397 */ + "\x57\x5a\0" /* offset 15400 */ + "\x48\x56\0" /* offset 15403 */ + "\x53\x44\0" /* offset 15406 */ + "\x53\x53\0" /* offset 15409 */ + "\x50\x50\x56\0" /* offset 15412 */ + "\x57\x43\0" /* offset 15416 */ + "\x44\x4a\0" /* offset 15419 */ + "\xe3\x81\xbb\xe3\x81\x8b\0" /* offset 15422 */ + "\xe3\x82\xb3\xe3\x82\xb3\0" /* offset 15429 */ + "\xe5\xad\x97\0" /* offset 15436 */ + "\xe5\x8f\x8c\0" /* offset 15440 */ + "\xe5\xa4\x9a\0" /* offset 15444 */ + "\xe8\xa7\xa3\0" /* offset 15448 */ + "\xe4\xba\xa4\0" /* offset 15452 */ + "\xe6\x98\xa0\0" /* offset 15456 */ + "\xe7\x84\xa1\0" /* offset 15460 */ + "\xe5\x89\x8d\0" /* offset 15464 */ + "\xe5\xbe\x8c\0" /* offset 15468 */ + "\xe5\x86\x8d\0" /* offset 15472 */ + "\xe6\x96\xb0\0" /* offset 15476 */ + "\xe5\x88\x9d\0" /* offset 15480 */ + "\xe7\xb5\x82\0" /* offset 15484 */ + "\xe8\xb2\xa9\0" /* offset 15488 */ + "\xe5\xa3\xb0\0" /* offset 15492 */ + "\xe5\x90\xb9\0" /* offset 15496 */ + "\xe6\xbc\x94\0" /* offset 15500 */ + "\xe6\x8a\x95\0" /* offset 15504 */ + "\xe6\x8d\x95\0" /* offset 15508 */ + "\xe9\x81\x8a\0" /* offset 15512 */ + "\xe6\x8c\x87\0" /* offset 15516 */ + "\xe6\x89\x93\0" /* offset 15520 */ + "\xe7\xa6\x81\0" /* offset 15524 */ + "\xe7\xa9\xba\0" /* offset 15528 */ + "\xe5\x90\x88\0" /* offset 15532 */ + "\xe6\xba\x80\0" /* offset 15536 */ + "\xe7\x94\xb3\0" /* offset 15540 */ + "\xe5\x89\xb2\0" /* offset 15544 */ + "\xe5\x96\xb6\0" /* offset 15548 */ + "\xe3\x80\x94\xe6\x9c\xac\xe3\x80\x95\0" /* offset 15552 */ + "\xe3\x80\x94\xe4\xb8\x89\xe3\x80\x95\0" /* offset 15562 */ + "\xe3\x80\x94\xe4\xba\x8c\xe3\x80\x95\0" /* offset 15572 */ + "\xe3\x80\x94\xe5\xae\x89\xe3\x80\x95\0" /* offset 15582 */ + "\xe3\x80\x94\xe7\x82\xb9\xe3\x80\x95\0" /* offset 15592 */ + "\xe3\x80\x94\xe6\x89\x93\xe3\x80\x95\0" /* offset 15602 */ + "\xe3\x80\x94\xe7\x9b\x97\xe3\x80\x95\0" /* offset 15612 */ + "\xe3\x80\x94\xe5\x8b\x9d\xe3\x80\x95\0" /* offset 15622 */ + "\xe3\x80\x94\xe6\x95\x97\xe3\x80\x95\0" /* offset 15632 */ + "\xe5\xbe\x97\0" /* offset 15642 */ + "\xe5\x8f\xaf\0" /* offset 15646 */ + "\xe4\xb8\xbd\0" /* offset 15650 */ + "\xe4\xb8\xb8\0" /* offset 15654 */ + "\xe4\xb9\x81\0" /* offset 15658 */ + "\xf0\xa0\x84\xa2\0" /* offset 15662 */ + "\xe4\xbd\xa0\0" /* offset 15667 */ + "\xe4\xbe\xbb\0" /* offset 15671 */ + "\xe5\x80\x82\0" /* offset 15675 */ + "\xe5\x81\xba\0" /* offset 15679 */ + "\xe5\x82\x99\0" /* offset 15683 */ + "\xe5\x83\x8f\0" /* offset 15687 */ + "\xe3\x92\x9e\0" /* offset 15691 */ + "\xf0\xa0\x98\xba\0" /* offset 15695 */ + "\xe5\x85\x94\0" /* offset 15700 */ + "\xe5\x85\xa4\0" /* offset 15704 */ + "\xe5\x85\xb7\0" /* offset 15708 */ + "\xf0\xa0\x94\x9c\0" /* offset 15712 */ + "\xe3\x92\xb9\0" /* offset 15717 */ + "\xe5\x85\xa7\0" /* offset 15721 */ + "\xf0\xa0\x95\x8b\0" /* offset 15725 */ + "\xe5\x86\x97\0" /* offset 15730 */ + "\xe5\x86\xa4\0" /* offset 15734 */ + "\xe4\xbb\x8c\0" /* offset 15738 */ + "\xe5\x86\xac\0" /* offset 15742 */ + "\xf0\xa9\x87\x9f\0" /* offset 15746 */ + "\xe5\x88\x83\0" /* offset 15751 */ + "\xe3\x93\x9f\0" /* offset 15755 */ + "\xe5\x88\xbb\0" /* offset 15759 */ + "\xe5\x89\x86\0" /* offset 15763 */ + "\xe5\x89\xb7\0" /* offset 15767 */ + "\xe3\x94\x95\0" /* offset 15771 */ + "\xe5\x8c\x85\0" /* offset 15775 */ + "\xe5\x8c\x86\0" /* offset 15779 */ + "\xe5\x8d\x89\0" /* offset 15783 */ + "\xe5\x8d\x9a\0" /* offset 15787 */ + "\xe5\x8d\xb3\0" /* offset 15791 */ + "\xe5\x8d\xbd\0" /* offset 15795 */ + "\xe5\x8d\xbf\0" /* offset 15799 */ + "\xf0\xa0\xa8\xac\0" /* offset 15803 */ + "\xe7\x81\xb0\0" /* offset 15808 */ + "\xe5\x8f\x8a\0" /* offset 15812 */ + "\xe5\x8f\x9f\0" /* offset 15816 */ + "\xf0\xa0\xad\xa3\0" /* offset 15820 */ + "\xe5\x8f\xab\0" /* offset 15825 */ + "\xe5\x8f\xb1\0" /* offset 15829 */ + "\xe5\x90\x86\0" /* offset 15833 */ + "\xe5\x92\x9e\0" /* offset 15837 */ + "\xe5\x90\xb8\0" /* offset 15841 */ + "\xe5\x91\x88\0" /* offset 15845 */ + "\xe5\x91\xa8\0" /* offset 15849 */ + "\xe5\x92\xa2\0" /* offset 15853 */ + "\xe5\x93\xb6\0" /* offset 15857 */ + "\xe5\x94\x90\0" /* offset 15861 */ + "\xe5\x95\x93\0" /* offset 15865 */ + "\xe5\x95\xa3\0" /* offset 15869 */ + "\xe5\x96\x84\0" /* offset 15873 */ + "\xe5\x96\xab\0" /* offset 15877 */ + "\xe5\x96\xb3\0" /* offset 15881 */ + "\xe5\x97\x82\0" /* offset 15885 */ + "\xe5\x9c\x96\0" /* offset 15889 */ + "\xe5\x9c\x97\0" /* offset 15893 */ + "\xe5\x99\x91\0" /* offset 15897 */ + "\xe5\x99\xb4\0" /* offset 15901 */ + "\xe5\xa3\xae\0" /* offset 15905 */ + "\xe5\x9f\x8e\0" /* offset 15909 */ + "\xe5\x9f\xb4\0" /* offset 15913 */ + "\xe5\xa0\x8d\0" /* offset 15917 */ + "\xe5\x9e\x8b\0" /* offset 15921 */ + "\xe5\xa0\xb2\0" /* offset 15925 */ + "\xe5\xa0\xb1\0" /* offset 15929 */ + "\xe5\xa2\xac\0" /* offset 15933 */ + "\xf0\xa1\x93\xa4\0" /* offset 15937 */ + "\xe5\xa3\xb2\0" /* offset 15942 */ + "\xe5\xa3\xb7\0" /* offset 15946 */ + "\xe5\xa4\x86\0" /* offset 15950 */ + "\xe5\xa4\xa2\0" /* offset 15954 */ + "\xe5\xa5\xa2\0" /* offset 15958 */ + "\xf0\xa1\x9a\xa8\0" /* offset 15962 */ + "\xf0\xa1\x9b\xaa\0" /* offset 15967 */ + "\xe5\xa7\xac\0" /* offset 15972 */ + "\xe5\xa8\x9b\0" /* offset 15976 */ + "\xe5\xa8\xa7\0" /* offset 15980 */ + "\xe5\xa7\x98\0" /* offset 15984 */ + "\xe5\xa9\xa6\0" /* offset 15988 */ + "\xe3\x9b\xae\0" /* offset 15992 */ + "\xe3\x9b\xbc\0" /* offset 15996 */ + "\xe5\xac\x88\0" /* offset 16000 */ + "\xe5\xac\xbe\0" /* offset 16004 */ + "\xf0\xa1\xa7\x88\0" /* offset 16008 */ + "\xe5\xaf\x83\0" /* offset 16013 */ + "\xe5\xaf\x98\0" /* offset 16017 */ + "\xe5\xaf\xb3\0" /* offset 16021 */ + "\xf0\xa1\xac\x98\0" /* offset 16025 */ + "\xe5\xaf\xbf\0" /* offset 16030 */ + "\xe5\xb0\x86\0" /* offset 16034 */ + "\xe5\xbd\x93\0" /* offset 16038 */ + "\xe3\x9e\x81\0" /* offset 16042 */ + "\xe5\xb1\xa0\0" /* offset 16046 */ + "\xe5\xb3\x80\0" /* offset 16050 */ + "\xe5\xb2\x8d\0" /* offset 16054 */ + "\xf0\xa1\xb7\xa4\0" /* offset 16058 */ + "\xe5\xb5\x83\0" /* offset 16063 */ + "\xf0\xa1\xb7\xa6\0" /* offset 16067 */ + "\xe5\xb5\xae\0" /* offset 16072 */ + "\xe5\xb5\xab\0" /* offset 16076 */ + "\xe5\xb5\xbc\0" /* offset 16080 */ + "\xe5\xb7\xa1\0" /* offset 16084 */ + "\xe5\xb7\xa2\0" /* offset 16088 */ + "\xe3\xa0\xaf\0" /* offset 16092 */ + "\xe5\xb7\xbd\0" /* offset 16096 */ + "\xe5\xb8\xa8\0" /* offset 16100 */ + "\xe5\xb8\xbd\0" /* offset 16104 */ + "\xe5\xb9\xa9\0" /* offset 16108 */ + "\xe3\xa1\xa2\0" /* offset 16112 */ + "\xf0\xa2\x86\x83\0" /* offset 16116 */ + "\xe3\xa1\xbc\0" /* offset 16121 */ + "\xe5\xba\xb0\0" /* offset 16125 */ + "\xe5\xba\xb3\0" /* offset 16129 */ + "\xe5\xba\xb6\0" /* offset 16133 */ + "\xf0\xaa\x8e\x92\0" /* offset 16137 */ + "\xf0\xa2\x8c\xb1\0" /* offset 16142 */ + "\xe8\x88\x81\0" /* offset 16147 */ + "\xe5\xbc\xa2\0" /* offset 16151 */ + "\xe3\xa3\x87\0" /* offset 16155 */ + "\xf0\xa3\x8a\xb8\0" /* offset 16159 */ + "\xf0\xa6\x87\x9a\0" /* offset 16164 */ + "\xe5\xbd\xa2\0" /* offset 16169 */ + "\xe5\xbd\xab\0" /* offset 16173 */ + "\xe3\xa3\xa3\0" /* offset 16177 */ + "\xe5\xbe\x9a\0" /* offset 16181 */ + "\xe5\xbf\x8d\0" /* offset 16185 */ + "\xe5\xbf\x97\0" /* offset 16189 */ + "\xe5\xbf\xb9\0" /* offset 16193 */ + "\xe6\x82\x81\0" /* offset 16197 */ + "\xe3\xa4\xba\0" /* offset 16201 */ + "\xe3\xa4\x9c\0" /* offset 16205 */ + "\xf0\xa2\x9b\x94\0" /* offset 16209 */ + "\xe6\x83\x87\0" /* offset 16214 */ + "\xe6\x85\x88\0" /* offset 16218 */ + "\xe6\x85\x8c\0" /* offset 16222 */ + "\xe6\x85\xba\0" /* offset 16226 */ + "\xe6\x86\xb2\0" /* offset 16230 */ + "\xe6\x86\xa4\0" /* offset 16234 */ + "\xe6\x86\xaf\0" /* offset 16238 */ + "\xe6\x87\x9e\0" /* offset 16242 */ + "\xe6\x88\x90\0" /* offset 16246 */ + "\xe6\x88\x9b\0" /* offset 16250 */ + "\xe6\x89\x9d\0" /* offset 16254 */ + "\xe6\x8a\xb1\0" /* offset 16258 */ + "\xe6\x8b\x94\0" /* offset 16262 */ + "\xe6\x8d\x90\0" /* offset 16266 */ + "\xf0\xa2\xac\x8c\0" /* offset 16270 */ + "\xe6\x8c\xbd\0" /* offset 16275 */ + "\xe6\x8b\xbc\0" /* offset 16279 */ + "\xe6\x8d\xa8\0" /* offset 16283 */ + "\xe6\x8e\x83\0" /* offset 16287 */ + "\xe6\x8f\xa4\0" /* offset 16291 */ + "\xf0\xa2\xaf\xb1\0" /* offset 16295 */ + "\xe6\x90\xa2\0" /* offset 16300 */ + "\xe6\x8f\x85\0" /* offset 16304 */ + "\xe6\x8e\xa9\0" /* offset 16308 */ + "\xe3\xa8\xae\0" /* offset 16312 */ + "\xe6\x91\xa9\0" /* offset 16316 */ + "\xe6\x91\xbe\0" /* offset 16320 */ + "\xe6\x92\x9d\0" /* offset 16324 */ + "\xe6\x91\xb7\0" /* offset 16328 */ + "\xe3\xa9\xac\0" /* offset 16332 */ + "\xe6\x95\xac\0" /* offset 16336 */ + "\xf0\xa3\x80\x8a\0" /* offset 16340 */ + "\xe6\x97\xa3\0" /* offset 16345 */ + "\xe6\x9b\xb8\0" /* offset 16349 */ + "\xe6\x99\x89\0" /* offset 16353 */ + "\xe3\xac\x99\0" /* offset 16357 */ + "\xe3\xac\x88\0" /* offset 16361 */ + "\xe3\xab\xa4\0" /* offset 16365 */ + "\xe5\x86\x92\0" /* offset 16369 */ + "\xe5\x86\x95\0" /* offset 16373 */ + "\xe6\x9c\x80\0" /* offset 16377 */ + "\xe6\x9a\x9c\0" /* offset 16381 */ + "\xe8\x82\xad\0" /* offset 16385 */ + "\xe4\x8f\x99\0" /* offset 16389 */ + "\xe6\x9c\xa1\0" /* offset 16393 */ + "\xe6\x9d\x9e\0" /* offset 16397 */ + "\xe6\x9d\x93\0" /* offset 16401 */ + "\xf0\xa3\x8f\x83\0" /* offset 16405 */ + "\xe3\xad\x89\0" /* offset 16410 */ + "\xe6\x9f\xba\0" /* offset 16414 */ + "\xe6\x9e\x85\0" /* offset 16418 */ + "\xe6\xa1\x92\0" /* offset 16422 */ + "\xf0\xa3\x91\xad\0" /* offset 16426 */ + "\xe6\xa2\x8e\0" /* offset 16431 */ + "\xe6\xa0\x9f\0" /* offset 16435 */ + "\xe6\xa4\x94\0" /* offset 16439 */ + "\xe6\xa5\x82\0" /* offset 16443 */ + "\xe6\xa6\xa3\0" /* offset 16447 */ + "\xe6\xa7\xaa\0" /* offset 16451 */ + "\xe6\xaa\xa8\0" /* offset 16455 */ + "\xf0\xa3\x9a\xa3\0" /* offset 16459 */ + "\xe6\xab\x9b\0" /* offset 16464 */ + "\xe3\xb0\x98\0" /* offset 16468 */ + "\xe6\xac\xa1\0" /* offset 16472 */ + "\xf0\xa3\xa2\xa7\0" /* offset 16476 */ + "\xe6\xad\x94\0" /* offset 16481 */ + "\xe3\xb1\x8e\0" /* offset 16485 */ + "\xe6\xad\xb2\0" /* offset 16489 */ + "\xe6\xae\x9f\0" /* offset 16493 */ + "\xe6\xae\xbb\0" /* offset 16497 */ + "\xf0\xa3\xaa\x8d\0" /* offset 16501 */ + "\xf0\xa1\xb4\x8b\0" /* offset 16506 */ + "\xf0\xa3\xab\xba\0" /* offset 16511 */ + "\xe6\xb1\x8e\0" /* offset 16516 */ + "\xf0\xa3\xb2\xbc\0" /* offset 16520 */ + "\xe6\xb2\xbf\0" /* offset 16525 */ + "\xe6\xb3\x8d\0" /* offset 16529 */ + "\xe6\xb1\xa7\0" /* offset 16533 */ + "\xe6\xb4\x96\0" /* offset 16537 */ + "\xe6\xb4\xbe\0" /* offset 16541 */ + "\xe6\xb5\xa9\0" /* offset 16545 */ + "\xe6\xb5\xb8\0" /* offset 16549 */ + "\xe6\xb6\x85\0" /* offset 16553 */ + "\xf0\xa3\xb4\x9e\0" /* offset 16557 */ + "\xe6\xb4\xb4\0" /* offset 16562 */ + "\xe6\xb8\xaf\0" /* offset 16566 */ + "\xe6\xb9\xae\0" /* offset 16570 */ + "\xe3\xb4\xb3\0" /* offset 16574 */ + "\xe6\xbb\x87\0" /* offset 16578 */ + "\xf0\xa3\xbb\x91\0" /* offset 16582 */ + "\xe6\xb7\xb9\0" /* offset 16587 */ + "\xe6\xbd\xae\0" /* offset 16591 */ + "\xf0\xa3\xbd\x9e\0" /* offset 16595 */ + "\xf0\xa3\xbe\x8e\0" /* offset 16600 */ + "\xe6\xbf\x86\0" /* offset 16605 */ + "\xe7\x80\xb9\0" /* offset 16609 */ + "\xe7\x80\x9b\0" /* offset 16613 */ + "\xe3\xb6\x96\0" /* offset 16617 */ + "\xe7\x81\x8a\0" /* offset 16621 */ + "\xe7\x81\xbd\0" /* offset 16625 */ + "\xe7\x81\xb7\0" /* offset 16629 */ + "\xe7\x82\xad\0" /* offset 16633 */ + "\xf0\xa0\x94\xa5\0" /* offset 16637 */ + "\xe7\x85\x85\0" /* offset 16642 */ + "\xf0\xa4\x89\xa3\0" /* offset 16646 */ + "\xe7\x86\x9c\0" /* offset 16651 */ + "\xf0\xa4\x8e\xab\0" /* offset 16655 */ + "\xe7\x88\xa8\0" /* offset 16660 */ + "\xe7\x89\x90\0" /* offset 16664 */ + "\xf0\xa4\x98\x88\0" /* offset 16668 */ + "\xe7\x8a\x80\0" /* offset 16673 */ + "\xe7\x8a\x95\0" /* offset 16677 */ + "\xf0\xa4\x9c\xb5\0" /* offset 16681 */ + "\xf0\xa4\xa0\x94\0" /* offset 16686 */ + "\xe7\x8d\xba\0" /* offset 16691 */ + "\xe7\x8e\x8b\0" /* offset 16695 */ + "\xe3\xba\xac\0" /* offset 16699 */ + "\xe7\x8e\xa5\0" /* offset 16703 */ + "\xe3\xba\xb8\0" /* offset 16707 */ + "\xe7\x91\x87\0" /* offset 16711 */ + "\xe7\x91\x9c\0" /* offset 16715 */ + "\xe7\x92\x85\0" /* offset 16719 */ + "\xe7\x93\x8a\0" /* offset 16723 */ + "\xe3\xbc\x9b\0" /* offset 16727 */ + "\xe7\x94\xa4\0" /* offset 16731 */ + "\xf0\xa4\xb0\xb6\0" /* offset 16735 */ + "\xe7\x94\xbe\0" /* offset 16740 */ + "\xf0\xa4\xb2\x92\0" /* offset 16744 */ + "\xf0\xa2\x86\x9f\0" /* offset 16749 */ + "\xe7\x98\x90\0" /* offset 16754 */ + "\xf0\xa4\xbe\xa1\0" /* offset 16758 */ + "\xf0\xa4\xbe\xb8\0" /* offset 16763 */ + "\xf0\xa5\x81\x84\0" /* offset 16768 */ + "\xe3\xbf\xbc\0" /* offset 16773 */ + "\xe4\x80\x88\0" /* offset 16777 */ + "\xf0\xa5\x83\xb3\0" /* offset 16781 */ + "\xf0\xa5\x83\xb2\0" /* offset 16786 */ + "\xf0\xa5\x84\x99\0" /* offset 16791 */ + "\xf0\xa5\x84\xb3\0" /* offset 16796 */ + "\xe7\x9c\x9e\0" /* offset 16801 */ + "\xe7\x9c\x9f\0" /* offset 16805 */ + "\xe7\x9e\x8b\0" /* offset 16809 */ + "\xe4\x81\x86\0" /* offset 16813 */ + "\xe4\x82\x96\0" /* offset 16817 */ + "\xf0\xa5\x90\x9d\0" /* offset 16821 */ + "\xe7\xa1\x8e\0" /* offset 16826 */ + "\xe4\x83\xa3\0" /* offset 16830 */ + "\xf0\xa5\x98\xa6\0" /* offset 16834 */ + "\xf0\xa5\x9a\x9a\0" /* offset 16839 */ + "\xf0\xa5\x9b\x85\0" /* offset 16844 */ + "\xe7\xa7\xab\0" /* offset 16849 */ + "\xe4\x84\xaf\0" /* offset 16853 */ + "\xe7\xa9\x8a\0" /* offset 16857 */ + "\xe7\xa9\x8f\0" /* offset 16861 */ + "\xf0\xa5\xa5\xbc\0" /* offset 16865 */ + "\xf0\xa5\xaa\xa7\0" /* offset 16870 */ + "\xe7\xab\xae\0" /* offset 16875 */ + "\xe4\x88\x82\0" /* offset 16879 */ + "\xf0\xa5\xae\xab\0" /* offset 16883 */ + "\xe7\xaf\x86\0" /* offset 16888 */ + "\xe7\xaf\x89\0" /* offset 16892 */ + "\xe4\x88\xa7\0" /* offset 16896 */ + "\xf0\xa5\xb2\x80\0" /* offset 16900 */ + "\xe7\xb3\x92\0" /* offset 16905 */ + "\xe4\x8a\xa0\0" /* offset 16909 */ + "\xe7\xb3\xa8\0" /* offset 16913 */ + "\xe7\xb3\xa3\0" /* offset 16917 */ + "\xe7\xb4\x80\0" /* offset 16921 */ + "\xf0\xa5\xbe\x86\0" /* offset 16925 */ + "\xe7\xb5\xa3\0" /* offset 16930 */ + "\xe4\x8c\x81\0" /* offset 16934 */ + "\xe7\xb7\x87\0" /* offset 16938 */ + "\xe7\xb8\x82\0" /* offset 16942 */ + "\xe7\xb9\x85\0" /* offset 16946 */ + "\xe4\x8c\xb4\0" /* offset 16950 */ + "\xf0\xa6\x88\xa8\0" /* offset 16954 */ + "\xf0\xa6\x89\x87\0" /* offset 16959 */ + "\xe4\x8d\x99\0" /* offset 16964 */ + "\xf0\xa6\x8b\x99\0" /* offset 16968 */ + "\xe7\xbd\xba\0" /* offset 16973 */ + "\xf0\xa6\x8c\xbe\0" /* offset 16977 */ + "\xe7\xbe\x95\0" /* offset 16982 */ + "\xe7\xbf\xba\0" /* offset 16986 */ + "\xf0\xa6\x93\x9a\0" /* offset 16990 */ + "\xf0\xa6\x94\xa3\0" /* offset 16995 */ + "\xe8\x81\xa0\0" /* offset 17000 */ + "\xf0\xa6\x96\xa8\0" /* offset 17004 */ + "\xe8\x81\xb0\0" /* offset 17009 */ + "\xf0\xa3\x8d\x9f\0" /* offset 17013 */ + "\xe4\x8f\x95\0" /* offset 17018 */ + "\xe8\x82\xb2\0" /* offset 17022 */ + "\xe8\x84\x83\0" /* offset 17026 */ + "\xe4\x90\x8b\0" /* offset 17030 */ + "\xe8\x84\xbe\0" /* offset 17034 */ + "\xe5\xaa\xb5\0" /* offset 17038 */ + "\xf0\xa6\x9e\xa7\0" /* offset 17042 */ + "\xf0\xa6\x9e\xb5\0" /* offset 17047 */ + "\xf0\xa3\x8e\x93\0" /* offset 17052 */ + "\xf0\xa3\x8e\x9c\0" /* offset 17057 */ + "\xe8\x88\x84\0" /* offset 17062 */ + "\xe8\xbe\x9e\0" /* offset 17066 */ + "\xe4\x91\xab\0" /* offset 17070 */ + "\xe8\x8a\x91\0" /* offset 17074 */ + "\xe8\x8a\x8b\0" /* offset 17078 */ + "\xe8\x8a\x9d\0" /* offset 17082 */ + "\xe5\x8a\xb3\0" /* offset 17086 */ + "\xe8\x8a\xb1\0" /* offset 17090 */ + "\xe8\x8a\xb3\0" /* offset 17094 */ + "\xe8\x8a\xbd\0" /* offset 17098 */ + "\xe8\x8b\xa6\0" /* offset 17102 */ + "\xf0\xa6\xac\xbc\0" /* offset 17106 */ + "\xe8\x8c\x9d\0" /* offset 17111 */ + "\xe8\x8d\xa3\0" /* offset 17115 */ + "\xe8\x8e\xad\0" /* offset 17119 */ + "\xe8\x8c\xa3\0" /* offset 17123 */ + "\xe8\x8e\xbd\0" /* offset 17127 */ + "\xe8\x8f\xa7\0" /* offset 17131 */ + "\xe8\x8d\x93\0" /* offset 17135 */ + "\xe8\x8f\x8a\0" /* offset 17139 */ + "\xe8\x8f\x8c\0" /* offset 17143 */ + "\xe8\x8f\x9c\0" /* offset 17147 */ + "\xf0\xa6\xb0\xb6\0" /* offset 17151 */ + "\xf0\xa6\xb5\xab\0" /* offset 17156 */ + "\xf0\xa6\xb3\x95\0" /* offset 17161 */ + "\xe4\x94\xab\0" /* offset 17166 */ + "\xe8\x93\xb1\0" /* offset 17170 */ + "\xe8\x93\xb3\0" /* offset 17174 */ + "\xe8\x94\x96\0" /* offset 17178 */ + "\xf0\xa7\x8f\x8a\0" /* offset 17182 */ + "\xe8\x95\xa4\0" /* offset 17187 */ + "\xf0\xa6\xbc\xac\0" /* offset 17191 */ + "\xe4\x95\x9d\0" /* offset 17196 */ + "\xe4\x95\xa1\0" /* offset 17200 */ + "\xf0\xa6\xbe\xb1\0" /* offset 17204 */ + "\xf0\xa7\x83\x92\0" /* offset 17209 */ + "\xe4\x95\xab\0" /* offset 17214 */ + "\xe8\x99\x90\0" /* offset 17218 */ + "\xe8\x99\xa7\0" /* offset 17222 */ + "\xe8\x99\xa9\0" /* offset 17226 */ + "\xe8\x9a\xa9\0" /* offset 17230 */ + "\xe8\x9a\x88\0" /* offset 17234 */ + "\xe8\x9c\x8e\0" /* offset 17238 */ + "\xe8\x9b\xa2\0" /* offset 17242 */ + "\xe8\x9c\xa8\0" /* offset 17246 */ + "\xe8\x9d\xab\0" /* offset 17250 */ + "\xe8\x9e\x86\0" /* offset 17254 */ + "\xe4\x97\x97\0" /* offset 17258 */ + "\xe8\x9f\xa1\0" /* offset 17262 */ + "\xe8\xa0\x81\0" /* offset 17266 */ + "\xe4\x97\xb9\0" /* offset 17270 */ + "\xe8\xa1\xa0\0" /* offset 17274 */ + "\xf0\xa7\x99\xa7\0" /* offset 17278 */ + "\xe8\xa3\x97\0" /* offset 17283 */ + "\xe8\xa3\x9e\0" /* offset 17287 */ + "\xe4\x98\xb5\0" /* offset 17291 */ + "\xe8\xa3\xba\0" /* offset 17295 */ + "\xe3\x92\xbb\0" /* offset 17299 */ + "\xf0\xa7\xa2\xae\0" /* offset 17303 */ + "\xf0\xa7\xa5\xa6\0" /* offset 17308 */ + "\xe4\x9a\xbe\0" /* offset 17313 */ + "\xe4\x9b\x87\0" /* offset 17317 */ + "\xe8\xaa\xa0\0" /* offset 17321 */ + "\xf0\xa7\xb2\xa8\0" /* offset 17325 */ + "\xe8\xb2\xab\0" /* offset 17330 */ + "\xe8\xb3\x81\0" /* offset 17334 */ + "\xe8\xb4\x9b\0" /* offset 17338 */ + "\xe8\xb5\xb7\0" /* offset 17342 */ + "\xf0\xa7\xbc\xaf\0" /* offset 17346 */ + "\xf0\xa0\xa0\x84\0" /* offset 17351 */ + "\xe8\xb7\x8b\0" /* offset 17356 */ + "\xe8\xb6\xbc\0" /* offset 17360 */ + "\xe8\xb7\xb0\0" /* offset 17364 */ + "\xf0\xa0\xa3\x9e\0" /* offset 17368 */ + "\xe8\xbb\x94\0" /* offset 17373 */ + "\xf0\xa8\x97\x92\0" /* offset 17377 */ + "\xf0\xa8\x97\xad\0" /* offset 17382 */ + "\xe9\x82\x94\0" /* offset 17387 */ + "\xe9\x83\xb1\0" /* offset 17391 */ + "\xe9\x84\x91\0" /* offset 17395 */ + "\xf0\xa8\x9c\xae\0" /* offset 17399 */ + "\xe9\x84\x9b\0" /* offset 17404 */ + "\xe9\x88\xb8\0" /* offset 17408 */ + "\xe9\x8b\x97\0" /* offset 17412 */ + "\xe9\x8b\x98\0" /* offset 17416 */ + "\xe9\x89\xbc\0" /* offset 17420 */ + "\xe9\x8f\xb9\0" /* offset 17424 */ + "\xe9\x90\x95\0" /* offset 17428 */ + "\xf0\xa8\xaf\xba\0" /* offset 17432 */ + "\xe9\x96\x8b\0" /* offset 17437 */ + "\xe4\xa6\x95\0" /* offset 17441 */ + "\xe9\x96\xb7\0" /* offset 17445 */ + "\xf0\xa8\xb5\xb7\0" /* offset 17449 */ + "\xe4\xa7\xa6\0" /* offset 17454 */ + "\xe9\x9b\x83\0" /* offset 17458 */ + "\xe5\xb6\xb2\0" /* offset 17462 */ + "\xe9\x9c\xa3\0" /* offset 17466 */ + "\xf0\xa9\x85\x85\0" /* offset 17470 */ + "\xf0\xa9\x88\x9a\0" /* offset 17475 */ + "\xe4\xa9\xae\0" /* offset 17480 */ + "\xe4\xa9\xb6\0" /* offset 17484 */ + "\xe9\x9f\xa0\0" /* offset 17488 */ + "\xf0\xa9\x90\x8a\0" /* offset 17492 */ + "\xe4\xaa\xb2\0" /* offset 17497 */ + "\xf0\xa9\x92\x96\0" /* offset 17501 */ + "\xe9\xa0\xa9\0" /* offset 17506 */ + "\xf0\xa9\x96\xb6\0" /* offset 17510 */ + "\xe9\xa3\xa2\0" /* offset 17515 */ + "\xe4\xac\xb3\0" /* offset 17519 */ + "\xe9\xa4\xa9\0" /* offset 17523 */ + "\xe9\xa6\xa7\0" /* offset 17527 */ + "\xe9\xa7\x82\0" /* offset 17531 */ + "\xe9\xa7\xbe\0" /* offset 17535 */ + "\xe4\xaf\x8e\0" /* offset 17539 */ + "\xf0\xa9\xac\xb0\0" /* offset 17543 */ + "\xe9\xb1\x80\0" /* offset 17548 */ + "\xe9\xb3\xbd\0" /* offset 17552 */ + "\xe4\xb3\x8e\0" /* offset 17556 */ + "\xe4\xb3\xad\0" /* offset 17560 */ + "\xe9\xb5\xa7\0" /* offset 17564 */ + "\xf0\xaa\x83\x8e\0" /* offset 17568 */ + "\xe4\xb3\xb8\0" /* offset 17573 */ + "\xf0\xaa\x84\x85\0" /* offset 17577 */ + "\xf0\xaa\x88\x8e\0" /* offset 17582 */ + "\xf0\xaa\x8a\x91\0" /* offset 17587 */ + "\xe4\xb5\x96\0" /* offset 17592 */ + "\xe9\xbb\xbe\0" /* offset 17596 */ + "\xe9\xbc\x85\0" /* offset 17600 */ + "\xe9\xbc\x8f\0" /* offset 17604 */ + "\xe9\xbc\x96\0" /* offset 17608 */ + "\xf0\xaa\x98\x80\0" /* offset 17612 */; + +typedef struct +{ + gunichar ch; + gunichar a; + gunichar b; +} decomposition_step; + +static const decomposition_step decomp_step_table[] = +{ + { 0x000c0, 0x00041, 0x00300 }, + { 0x000c1, 0x00041, 0x00301 }, + { 0x000c2, 0x00041, 0x00302 }, + { 0x000c3, 0x00041, 0x00303 }, + { 0x000c4, 0x00041, 0x00308 }, + { 0x000c5, 0x00041, 0x0030a }, + { 0x000c7, 0x00043, 0x00327 }, + { 0x000c8, 0x00045, 0x00300 }, + { 0x000c9, 0x00045, 0x00301 }, + { 0x000ca, 0x00045, 0x00302 }, + { 0x000cb, 0x00045, 0x00308 }, + { 0x000cc, 0x00049, 0x00300 }, + { 0x000cd, 0x00049, 0x00301 }, + { 0x000ce, 0x00049, 0x00302 }, + { 0x000cf, 0x00049, 0x00308 }, + { 0x000d1, 0x0004e, 0x00303 }, + { 0x000d2, 0x0004f, 0x00300 }, + { 0x000d3, 0x0004f, 0x00301 }, + { 0x000d4, 0x0004f, 0x00302 }, + { 0x000d5, 0x0004f, 0x00303 }, + { 0x000d6, 0x0004f, 0x00308 }, + { 0x000d9, 0x00055, 0x00300 }, + { 0x000da, 0x00055, 0x00301 }, + { 0x000db, 0x00055, 0x00302 }, + { 0x000dc, 0x00055, 0x00308 }, + { 0x000dd, 0x00059, 0x00301 }, + { 0x000e0, 0x00061, 0x00300 }, + { 0x000e1, 0x00061, 0x00301 }, + { 0x000e2, 0x00061, 0x00302 }, + { 0x000e3, 0x00061, 0x00303 }, + { 0x000e4, 0x00061, 0x00308 }, + { 0x000e5, 0x00061, 0x0030a }, + { 0x000e7, 0x00063, 0x00327 }, + { 0x000e8, 0x00065, 0x00300 }, + { 0x000e9, 0x00065, 0x00301 }, + { 0x000ea, 0x00065, 0x00302 }, + { 0x000eb, 0x00065, 0x00308 }, + { 0x000ec, 0x00069, 0x00300 }, + { 0x000ed, 0x00069, 0x00301 }, + { 0x000ee, 0x00069, 0x00302 }, + { 0x000ef, 0x00069, 0x00308 }, + { 0x000f1, 0x0006e, 0x00303 }, + { 0x000f2, 0x0006f, 0x00300 }, + { 0x000f3, 0x0006f, 0x00301 }, + { 0x000f4, 0x0006f, 0x00302 }, + { 0x000f5, 0x0006f, 0x00303 }, + { 0x000f6, 0x0006f, 0x00308 }, + { 0x000f9, 0x00075, 0x00300 }, + { 0x000fa, 0x00075, 0x00301 }, + { 0x000fb, 0x00075, 0x00302 }, + { 0x000fc, 0x00075, 0x00308 }, + { 0x000fd, 0x00079, 0x00301 }, + { 0x000ff, 0x00079, 0x00308 }, + { 0x00100, 0x00041, 0x00304 }, + { 0x00101, 0x00061, 0x00304 }, + { 0x00102, 0x00041, 0x00306 }, + { 0x00103, 0x00061, 0x00306 }, + { 0x00104, 0x00041, 0x00328 }, + { 0x00105, 0x00061, 0x00328 }, + { 0x00106, 0x00043, 0x00301 }, + { 0x00107, 0x00063, 0x00301 }, + { 0x00108, 0x00043, 0x00302 }, + { 0x00109, 0x00063, 0x00302 }, + { 0x0010a, 0x00043, 0x00307 }, + { 0x0010b, 0x00063, 0x00307 }, + { 0x0010c, 0x00043, 0x0030c }, + { 0x0010d, 0x00063, 0x0030c }, + { 0x0010e, 0x00044, 0x0030c }, + { 0x0010f, 0x00064, 0x0030c }, + { 0x00112, 0x00045, 0x00304 }, + { 0x00113, 0x00065, 0x00304 }, + { 0x00114, 0x00045, 0x00306 }, + { 0x00115, 0x00065, 0x00306 }, + { 0x00116, 0x00045, 0x00307 }, + { 0x00117, 0x00065, 0x00307 }, + { 0x00118, 0x00045, 0x00328 }, + { 0x00119, 0x00065, 0x00328 }, + { 0x0011a, 0x00045, 0x0030c }, + { 0x0011b, 0x00065, 0x0030c }, + { 0x0011c, 0x00047, 0x00302 }, + { 0x0011d, 0x00067, 0x00302 }, + { 0x0011e, 0x00047, 0x00306 }, + { 0x0011f, 0x00067, 0x00306 }, + { 0x00120, 0x00047, 0x00307 }, + { 0x00121, 0x00067, 0x00307 }, + { 0x00122, 0x00047, 0x00327 }, + { 0x00123, 0x00067, 0x00327 }, + { 0x00124, 0x00048, 0x00302 }, + { 0x00125, 0x00068, 0x00302 }, + { 0x00128, 0x00049, 0x00303 }, + { 0x00129, 0x00069, 0x00303 }, + { 0x0012a, 0x00049, 0x00304 }, + { 0x0012b, 0x00069, 0x00304 }, + { 0x0012c, 0x00049, 0x00306 }, + { 0x0012d, 0x00069, 0x00306 }, + { 0x0012e, 0x00049, 0x00328 }, + { 0x0012f, 0x00069, 0x00328 }, + { 0x00130, 0x00049, 0x00307 }, + { 0x00134, 0x0004a, 0x00302 }, + { 0x00135, 0x0006a, 0x00302 }, + { 0x00136, 0x0004b, 0x00327 }, + { 0x00137, 0x0006b, 0x00327 }, + { 0x00139, 0x0004c, 0x00301 }, + { 0x0013a, 0x0006c, 0x00301 }, + { 0x0013b, 0x0004c, 0x00327 }, + { 0x0013c, 0x0006c, 0x00327 }, + { 0x0013d, 0x0004c, 0x0030c }, + { 0x0013e, 0x0006c, 0x0030c }, + { 0x00143, 0x0004e, 0x00301 }, + { 0x00144, 0x0006e, 0x00301 }, + { 0x00145, 0x0004e, 0x00327 }, + { 0x00146, 0x0006e, 0x00327 }, + { 0x00147, 0x0004e, 0x0030c }, + { 0x00148, 0x0006e, 0x0030c }, + { 0x0014c, 0x0004f, 0x00304 }, + { 0x0014d, 0x0006f, 0x00304 }, + { 0x0014e, 0x0004f, 0x00306 }, + { 0x0014f, 0x0006f, 0x00306 }, + { 0x00150, 0x0004f, 0x0030b }, + { 0x00151, 0x0006f, 0x0030b }, + { 0x00154, 0x00052, 0x00301 }, + { 0x00155, 0x00072, 0x00301 }, + { 0x00156, 0x00052, 0x00327 }, + { 0x00157, 0x00072, 0x00327 }, + { 0x00158, 0x00052, 0x0030c }, + { 0x00159, 0x00072, 0x0030c }, + { 0x0015a, 0x00053, 0x00301 }, + { 0x0015b, 0x00073, 0x00301 }, + { 0x0015c, 0x00053, 0x00302 }, + { 0x0015d, 0x00073, 0x00302 }, + { 0x0015e, 0x00053, 0x00327 }, + { 0x0015f, 0x00073, 0x00327 }, + { 0x00160, 0x00053, 0x0030c }, + { 0x00161, 0x00073, 0x0030c }, + { 0x00162, 0x00054, 0x00327 }, + { 0x00163, 0x00074, 0x00327 }, + { 0x00164, 0x00054, 0x0030c }, + { 0x00165, 0x00074, 0x0030c }, + { 0x00168, 0x00055, 0x00303 }, + { 0x00169, 0x00075, 0x00303 }, + { 0x0016a, 0x00055, 0x00304 }, + { 0x0016b, 0x00075, 0x00304 }, + { 0x0016c, 0x00055, 0x00306 }, + { 0x0016d, 0x00075, 0x00306 }, + { 0x0016e, 0x00055, 0x0030a }, + { 0x0016f, 0x00075, 0x0030a }, + { 0x00170, 0x00055, 0x0030b }, + { 0x00171, 0x00075, 0x0030b }, + { 0x00172, 0x00055, 0x00328 }, + { 0x00173, 0x00075, 0x00328 }, + { 0x00174, 0x00057, 0x00302 }, + { 0x00175, 0x00077, 0x00302 }, + { 0x00176, 0x00059, 0x00302 }, + { 0x00177, 0x00079, 0x00302 }, + { 0x00178, 0x00059, 0x00308 }, + { 0x00179, 0x0005a, 0x00301 }, + { 0x0017a, 0x0007a, 0x00301 }, + { 0x0017b, 0x0005a, 0x00307 }, + { 0x0017c, 0x0007a, 0x00307 }, + { 0x0017d, 0x0005a, 0x0030c }, + { 0x0017e, 0x0007a, 0x0030c }, + { 0x001a0, 0x0004f, 0x0031b }, + { 0x001a1, 0x0006f, 0x0031b }, + { 0x001af, 0x00055, 0x0031b }, + { 0x001b0, 0x00075, 0x0031b }, + { 0x001cd, 0x00041, 0x0030c }, + { 0x001ce, 0x00061, 0x0030c }, + { 0x001cf, 0x00049, 0x0030c }, + { 0x001d0, 0x00069, 0x0030c }, + { 0x001d1, 0x0004f, 0x0030c }, + { 0x001d2, 0x0006f, 0x0030c }, + { 0x001d3, 0x00055, 0x0030c }, + { 0x001d4, 0x00075, 0x0030c }, + { 0x001d5, 0x000dc, 0x00304 }, + { 0x001d6, 0x000fc, 0x00304 }, + { 0x001d7, 0x000dc, 0x00301 }, + { 0x001d8, 0x000fc, 0x00301 }, + { 0x001d9, 0x000dc, 0x0030c }, + { 0x001da, 0x000fc, 0x0030c }, + { 0x001db, 0x000dc, 0x00300 }, + { 0x001dc, 0x000fc, 0x00300 }, + { 0x001de, 0x000c4, 0x00304 }, + { 0x001df, 0x000e4, 0x00304 }, + { 0x001e0, 0x00226, 0x00304 }, + { 0x001e1, 0x00227, 0x00304 }, + { 0x001e2, 0x000c6, 0x00304 }, + { 0x001e3, 0x000e6, 0x00304 }, + { 0x001e6, 0x00047, 0x0030c }, + { 0x001e7, 0x00067, 0x0030c }, + { 0x001e8, 0x0004b, 0x0030c }, + { 0x001e9, 0x0006b, 0x0030c }, + { 0x001ea, 0x0004f, 0x00328 }, + { 0x001eb, 0x0006f, 0x00328 }, + { 0x001ec, 0x001ea, 0x00304 }, + { 0x001ed, 0x001eb, 0x00304 }, + { 0x001ee, 0x001b7, 0x0030c }, + { 0x001ef, 0x00292, 0x0030c }, + { 0x001f0, 0x0006a, 0x0030c }, + { 0x001f4, 0x00047, 0x00301 }, + { 0x001f5, 0x00067, 0x00301 }, + { 0x001f8, 0x0004e, 0x00300 }, + { 0x001f9, 0x0006e, 0x00300 }, + { 0x001fa, 0x000c5, 0x00301 }, + { 0x001fb, 0x000e5, 0x00301 }, + { 0x001fc, 0x000c6, 0x00301 }, + { 0x001fd, 0x000e6, 0x00301 }, + { 0x001fe, 0x000d8, 0x00301 }, + { 0x001ff, 0x000f8, 0x00301 }, + { 0x00200, 0x00041, 0x0030f }, + { 0x00201, 0x00061, 0x0030f }, + { 0x00202, 0x00041, 0x00311 }, + { 0x00203, 0x00061, 0x00311 }, + { 0x00204, 0x00045, 0x0030f }, + { 0x00205, 0x00065, 0x0030f }, + { 0x00206, 0x00045, 0x00311 }, + { 0x00207, 0x00065, 0x00311 }, + { 0x00208, 0x00049, 0x0030f }, + { 0x00209, 0x00069, 0x0030f }, + { 0x0020a, 0x00049, 0x00311 }, + { 0x0020b, 0x00069, 0x00311 }, + { 0x0020c, 0x0004f, 0x0030f }, + { 0x0020d, 0x0006f, 0x0030f }, + { 0x0020e, 0x0004f, 0x00311 }, + { 0x0020f, 0x0006f, 0x00311 }, + { 0x00210, 0x00052, 0x0030f }, + { 0x00211, 0x00072, 0x0030f }, + { 0x00212, 0x00052, 0x00311 }, + { 0x00213, 0x00072, 0x00311 }, + { 0x00214, 0x00055, 0x0030f }, + { 0x00215, 0x00075, 0x0030f }, + { 0x00216, 0x00055, 0x00311 }, + { 0x00217, 0x00075, 0x00311 }, + { 0x00218, 0x00053, 0x00326 }, + { 0x00219, 0x00073, 0x00326 }, + { 0x0021a, 0x00054, 0x00326 }, + { 0x0021b, 0x00074, 0x00326 }, + { 0x0021e, 0x00048, 0x0030c }, + { 0x0021f, 0x00068, 0x0030c }, + { 0x00226, 0x00041, 0x00307 }, + { 0x00227, 0x00061, 0x00307 }, + { 0x00228, 0x00045, 0x00327 }, + { 0x00229, 0x00065, 0x00327 }, + { 0x0022a, 0x000d6, 0x00304 }, + { 0x0022b, 0x000f6, 0x00304 }, + { 0x0022c, 0x000d5, 0x00304 }, + { 0x0022d, 0x000f5, 0x00304 }, + { 0x0022e, 0x0004f, 0x00307 }, + { 0x0022f, 0x0006f, 0x00307 }, + { 0x00230, 0x0022e, 0x00304 }, + { 0x00231, 0x0022f, 0x00304 }, + { 0x00232, 0x00059, 0x00304 }, + { 0x00233, 0x00079, 0x00304 }, + { 0x00340, 0x00300, 0x00000 }, + { 0x00341, 0x00301, 0x00000 }, + { 0x00343, 0x00313, 0x00000 }, + { 0x00344, 0x00308, 0x00301 }, + { 0x00374, 0x002b9, 0x00000 }, + { 0x0037e, 0x0003b, 0x00000 }, + { 0x00385, 0x000a8, 0x00301 }, + { 0x00386, 0x00391, 0x00301 }, + { 0x00387, 0x000b7, 0x00000 }, + { 0x00388, 0x00395, 0x00301 }, + { 0x00389, 0x00397, 0x00301 }, + { 0x0038a, 0x00399, 0x00301 }, + { 0x0038c, 0x0039f, 0x00301 }, + { 0x0038e, 0x003a5, 0x00301 }, + { 0x0038f, 0x003a9, 0x00301 }, + { 0x00390, 0x003ca, 0x00301 }, + { 0x003aa, 0x00399, 0x00308 }, + { 0x003ab, 0x003a5, 0x00308 }, + { 0x003ac, 0x003b1, 0x00301 }, + { 0x003ad, 0x003b5, 0x00301 }, + { 0x003ae, 0x003b7, 0x00301 }, + { 0x003af, 0x003b9, 0x00301 }, + { 0x003b0, 0x003cb, 0x00301 }, + { 0x003ca, 0x003b9, 0x00308 }, + { 0x003cb, 0x003c5, 0x00308 }, + { 0x003cc, 0x003bf, 0x00301 }, + { 0x003cd, 0x003c5, 0x00301 }, + { 0x003ce, 0x003c9, 0x00301 }, + { 0x003d3, 0x003d2, 0x00301 }, + { 0x003d4, 0x003d2, 0x00308 }, + { 0x00400, 0x00415, 0x00300 }, + { 0x00401, 0x00415, 0x00308 }, + { 0x00403, 0x00413, 0x00301 }, + { 0x00407, 0x00406, 0x00308 }, + { 0x0040c, 0x0041a, 0x00301 }, + { 0x0040d, 0x00418, 0x00300 }, + { 0x0040e, 0x00423, 0x00306 }, + { 0x00419, 0x00418, 0x00306 }, + { 0x00439, 0x00438, 0x00306 }, + { 0x00450, 0x00435, 0x00300 }, + { 0x00451, 0x00435, 0x00308 }, + { 0x00453, 0x00433, 0x00301 }, + { 0x00457, 0x00456, 0x00308 }, + { 0x0045c, 0x0043a, 0x00301 }, + { 0x0045d, 0x00438, 0x00300 }, + { 0x0045e, 0x00443, 0x00306 }, + { 0x00476, 0x00474, 0x0030f }, + { 0x00477, 0x00475, 0x0030f }, + { 0x004c1, 0x00416, 0x00306 }, + { 0x004c2, 0x00436, 0x00306 }, + { 0x004d0, 0x00410, 0x00306 }, + { 0x004d1, 0x00430, 0x00306 }, + { 0x004d2, 0x00410, 0x00308 }, + { 0x004d3, 0x00430, 0x00308 }, + { 0x004d6, 0x00415, 0x00306 }, + { 0x004d7, 0x00435, 0x00306 }, + { 0x004da, 0x004d8, 0x00308 }, + { 0x004db, 0x004d9, 0x00308 }, + { 0x004dc, 0x00416, 0x00308 }, + { 0x004dd, 0x00436, 0x00308 }, + { 0x004de, 0x00417, 0x00308 }, + { 0x004df, 0x00437, 0x00308 }, + { 0x004e2, 0x00418, 0x00304 }, + { 0x004e3, 0x00438, 0x00304 }, + { 0x004e4, 0x00418, 0x00308 }, + { 0x004e5, 0x00438, 0x00308 }, + { 0x004e6, 0x0041e, 0x00308 }, + { 0x004e7, 0x0043e, 0x00308 }, + { 0x004ea, 0x004e8, 0x00308 }, + { 0x004eb, 0x004e9, 0x00308 }, + { 0x004ec, 0x0042d, 0x00308 }, + { 0x004ed, 0x0044d, 0x00308 }, + { 0x004ee, 0x00423, 0x00304 }, + { 0x004ef, 0x00443, 0x00304 }, + { 0x004f0, 0x00423, 0x00308 }, + { 0x004f1, 0x00443, 0x00308 }, + { 0x004f2, 0x00423, 0x0030b }, + { 0x004f3, 0x00443, 0x0030b }, + { 0x004f4, 0x00427, 0x00308 }, + { 0x004f5, 0x00447, 0x00308 }, + { 0x004f8, 0x0042b, 0x00308 }, + { 0x004f9, 0x0044b, 0x00308 }, + { 0x00622, 0x00627, 0x00653 }, + { 0x00623, 0x00627, 0x00654 }, + { 0x00624, 0x00648, 0x00654 }, + { 0x00625, 0x00627, 0x00655 }, + { 0x00626, 0x0064a, 0x00654 }, + { 0x006c0, 0x006d5, 0x00654 }, + { 0x006c2, 0x006c1, 0x00654 }, + { 0x006d3, 0x006d2, 0x00654 }, + { 0x00929, 0x00928, 0x0093c }, + { 0x00931, 0x00930, 0x0093c }, + { 0x00934, 0x00933, 0x0093c }, + { 0x00958, 0x00915, 0x0093c }, + { 0x00959, 0x00916, 0x0093c }, + { 0x0095a, 0x00917, 0x0093c }, + { 0x0095b, 0x0091c, 0x0093c }, + { 0x0095c, 0x00921, 0x0093c }, + { 0x0095d, 0x00922, 0x0093c }, + { 0x0095e, 0x0092b, 0x0093c }, + { 0x0095f, 0x0092f, 0x0093c }, + { 0x009cb, 0x009c7, 0x009be }, + { 0x009cc, 0x009c7, 0x009d7 }, + { 0x009dc, 0x009a1, 0x009bc }, + { 0x009dd, 0x009a2, 0x009bc }, + { 0x009df, 0x009af, 0x009bc }, + { 0x00a33, 0x00a32, 0x00a3c }, + { 0x00a36, 0x00a38, 0x00a3c }, + { 0x00a59, 0x00a16, 0x00a3c }, + { 0x00a5a, 0x00a17, 0x00a3c }, + { 0x00a5b, 0x00a1c, 0x00a3c }, + { 0x00a5e, 0x00a2b, 0x00a3c }, + { 0x00b48, 0x00b47, 0x00b56 }, + { 0x00b4b, 0x00b47, 0x00b3e }, + { 0x00b4c, 0x00b47, 0x00b57 }, + { 0x00b5c, 0x00b21, 0x00b3c }, + { 0x00b5d, 0x00b22, 0x00b3c }, + { 0x00b94, 0x00b92, 0x00bd7 }, + { 0x00bca, 0x00bc6, 0x00bbe }, + { 0x00bcb, 0x00bc7, 0x00bbe }, + { 0x00bcc, 0x00bc6, 0x00bd7 }, + { 0x00c48, 0x00c46, 0x00c56 }, + { 0x00cc0, 0x00cbf, 0x00cd5 }, + { 0x00cc7, 0x00cc6, 0x00cd5 }, + { 0x00cc8, 0x00cc6, 0x00cd6 }, + { 0x00cca, 0x00cc6, 0x00cc2 }, + { 0x00ccb, 0x00cca, 0x00cd5 }, + { 0x00d4a, 0x00d46, 0x00d3e }, + { 0x00d4b, 0x00d47, 0x00d3e }, + { 0x00d4c, 0x00d46, 0x00d57 }, + { 0x00dda, 0x00dd9, 0x00dca }, + { 0x00ddc, 0x00dd9, 0x00dcf }, + { 0x00ddd, 0x00ddc, 0x00dca }, + { 0x00dde, 0x00dd9, 0x00ddf }, + { 0x00f43, 0x00f42, 0x00fb7 }, + { 0x00f4d, 0x00f4c, 0x00fb7 }, + { 0x00f52, 0x00f51, 0x00fb7 }, + { 0x00f57, 0x00f56, 0x00fb7 }, + { 0x00f5c, 0x00f5b, 0x00fb7 }, + { 0x00f69, 0x00f40, 0x00fb5 }, + { 0x00f73, 0x00f71, 0x00f72 }, + { 0x00f75, 0x00f71, 0x00f74 }, + { 0x00f76, 0x00fb2, 0x00f80 }, + { 0x00f78, 0x00fb3, 0x00f80 }, + { 0x00f81, 0x00f71, 0x00f80 }, + { 0x00f93, 0x00f92, 0x00fb7 }, + { 0x00f9d, 0x00f9c, 0x00fb7 }, + { 0x00fa2, 0x00fa1, 0x00fb7 }, + { 0x00fa7, 0x00fa6, 0x00fb7 }, + { 0x00fac, 0x00fab, 0x00fb7 }, + { 0x00fb9, 0x00f90, 0x00fb5 }, + { 0x01026, 0x01025, 0x0102e }, + { 0x01b06, 0x01b05, 0x01b35 }, + { 0x01b08, 0x01b07, 0x01b35 }, + { 0x01b0a, 0x01b09, 0x01b35 }, + { 0x01b0c, 0x01b0b, 0x01b35 }, + { 0x01b0e, 0x01b0d, 0x01b35 }, + { 0x01b12, 0x01b11, 0x01b35 }, + { 0x01b3b, 0x01b3a, 0x01b35 }, + { 0x01b3d, 0x01b3c, 0x01b35 }, + { 0x01b40, 0x01b3e, 0x01b35 }, + { 0x01b41, 0x01b3f, 0x01b35 }, + { 0x01b43, 0x01b42, 0x01b35 }, + { 0x01e00, 0x00041, 0x00325 }, + { 0x01e01, 0x00061, 0x00325 }, + { 0x01e02, 0x00042, 0x00307 }, + { 0x01e03, 0x00062, 0x00307 }, + { 0x01e04, 0x00042, 0x00323 }, + { 0x01e05, 0x00062, 0x00323 }, + { 0x01e06, 0x00042, 0x00331 }, + { 0x01e07, 0x00062, 0x00331 }, + { 0x01e08, 0x000c7, 0x00301 }, + { 0x01e09, 0x000e7, 0x00301 }, + { 0x01e0a, 0x00044, 0x00307 }, + { 0x01e0b, 0x00064, 0x00307 }, + { 0x01e0c, 0x00044, 0x00323 }, + { 0x01e0d, 0x00064, 0x00323 }, + { 0x01e0e, 0x00044, 0x00331 }, + { 0x01e0f, 0x00064, 0x00331 }, + { 0x01e10, 0x00044, 0x00327 }, + { 0x01e11, 0x00064, 0x00327 }, + { 0x01e12, 0x00044, 0x0032d }, + { 0x01e13, 0x00064, 0x0032d }, + { 0x01e14, 0x00112, 0x00300 }, + { 0x01e15, 0x00113, 0x00300 }, + { 0x01e16, 0x00112, 0x00301 }, + { 0x01e17, 0x00113, 0x00301 }, + { 0x01e18, 0x00045, 0x0032d }, + { 0x01e19, 0x00065, 0x0032d }, + { 0x01e1a, 0x00045, 0x00330 }, + { 0x01e1b, 0x00065, 0x00330 }, + { 0x01e1c, 0x00228, 0x00306 }, + { 0x01e1d, 0x00229, 0x00306 }, + { 0x01e1e, 0x00046, 0x00307 }, + { 0x01e1f, 0x00066, 0x00307 }, + { 0x01e20, 0x00047, 0x00304 }, + { 0x01e21, 0x00067, 0x00304 }, + { 0x01e22, 0x00048, 0x00307 }, + { 0x01e23, 0x00068, 0x00307 }, + { 0x01e24, 0x00048, 0x00323 }, + { 0x01e25, 0x00068, 0x00323 }, + { 0x01e26, 0x00048, 0x00308 }, + { 0x01e27, 0x00068, 0x00308 }, + { 0x01e28, 0x00048, 0x00327 }, + { 0x01e29, 0x00068, 0x00327 }, + { 0x01e2a, 0x00048, 0x0032e }, + { 0x01e2b, 0x00068, 0x0032e }, + { 0x01e2c, 0x00049, 0x00330 }, + { 0x01e2d, 0x00069, 0x00330 }, + { 0x01e2e, 0x000cf, 0x00301 }, + { 0x01e2f, 0x000ef, 0x00301 }, + { 0x01e30, 0x0004b, 0x00301 }, + { 0x01e31, 0x0006b, 0x00301 }, + { 0x01e32, 0x0004b, 0x00323 }, + { 0x01e33, 0x0006b, 0x00323 }, + { 0x01e34, 0x0004b, 0x00331 }, + { 0x01e35, 0x0006b, 0x00331 }, + { 0x01e36, 0x0004c, 0x00323 }, + { 0x01e37, 0x0006c, 0x00323 }, + { 0x01e38, 0x01e36, 0x00304 }, + { 0x01e39, 0x01e37, 0x00304 }, + { 0x01e3a, 0x0004c, 0x00331 }, + { 0x01e3b, 0x0006c, 0x00331 }, + { 0x01e3c, 0x0004c, 0x0032d }, + { 0x01e3d, 0x0006c, 0x0032d }, + { 0x01e3e, 0x0004d, 0x00301 }, + { 0x01e3f, 0x0006d, 0x00301 }, + { 0x01e40, 0x0004d, 0x00307 }, + { 0x01e41, 0x0006d, 0x00307 }, + { 0x01e42, 0x0004d, 0x00323 }, + { 0x01e43, 0x0006d, 0x00323 }, + { 0x01e44, 0x0004e, 0x00307 }, + { 0x01e45, 0x0006e, 0x00307 }, + { 0x01e46, 0x0004e, 0x00323 }, + { 0x01e47, 0x0006e, 0x00323 }, + { 0x01e48, 0x0004e, 0x00331 }, + { 0x01e49, 0x0006e, 0x00331 }, + { 0x01e4a, 0x0004e, 0x0032d }, + { 0x01e4b, 0x0006e, 0x0032d }, + { 0x01e4c, 0x000d5, 0x00301 }, + { 0x01e4d, 0x000f5, 0x00301 }, + { 0x01e4e, 0x000d5, 0x00308 }, + { 0x01e4f, 0x000f5, 0x00308 }, + { 0x01e50, 0x0014c, 0x00300 }, + { 0x01e51, 0x0014d, 0x00300 }, + { 0x01e52, 0x0014c, 0x00301 }, + { 0x01e53, 0x0014d, 0x00301 }, + { 0x01e54, 0x00050, 0x00301 }, + { 0x01e55, 0x00070, 0x00301 }, + { 0x01e56, 0x00050, 0x00307 }, + { 0x01e57, 0x00070, 0x00307 }, + { 0x01e58, 0x00052, 0x00307 }, + { 0x01e59, 0x00072, 0x00307 }, + { 0x01e5a, 0x00052, 0x00323 }, + { 0x01e5b, 0x00072, 0x00323 }, + { 0x01e5c, 0x01e5a, 0x00304 }, + { 0x01e5d, 0x01e5b, 0x00304 }, + { 0x01e5e, 0x00052, 0x00331 }, + { 0x01e5f, 0x00072, 0x00331 }, + { 0x01e60, 0x00053, 0x00307 }, + { 0x01e61, 0x00073, 0x00307 }, + { 0x01e62, 0x00053, 0x00323 }, + { 0x01e63, 0x00073, 0x00323 }, + { 0x01e64, 0x0015a, 0x00307 }, + { 0x01e65, 0x0015b, 0x00307 }, + { 0x01e66, 0x00160, 0x00307 }, + { 0x01e67, 0x00161, 0x00307 }, + { 0x01e68, 0x01e62, 0x00307 }, + { 0x01e69, 0x01e63, 0x00307 }, + { 0x01e6a, 0x00054, 0x00307 }, + { 0x01e6b, 0x00074, 0x00307 }, + { 0x01e6c, 0x00054, 0x00323 }, + { 0x01e6d, 0x00074, 0x00323 }, + { 0x01e6e, 0x00054, 0x00331 }, + { 0x01e6f, 0x00074, 0x00331 }, + { 0x01e70, 0x00054, 0x0032d }, + { 0x01e71, 0x00074, 0x0032d }, + { 0x01e72, 0x00055, 0x00324 }, + { 0x01e73, 0x00075, 0x00324 }, + { 0x01e74, 0x00055, 0x00330 }, + { 0x01e75, 0x00075, 0x00330 }, + { 0x01e76, 0x00055, 0x0032d }, + { 0x01e77, 0x00075, 0x0032d }, + { 0x01e78, 0x00168, 0x00301 }, + { 0x01e79, 0x00169, 0x00301 }, + { 0x01e7a, 0x0016a, 0x00308 }, + { 0x01e7b, 0x0016b, 0x00308 }, + { 0x01e7c, 0x00056, 0x00303 }, + { 0x01e7d, 0x00076, 0x00303 }, + { 0x01e7e, 0x00056, 0x00323 }, + { 0x01e7f, 0x00076, 0x00323 }, + { 0x01e80, 0x00057, 0x00300 }, + { 0x01e81, 0x00077, 0x00300 }, + { 0x01e82, 0x00057, 0x00301 }, + { 0x01e83, 0x00077, 0x00301 }, + { 0x01e84, 0x00057, 0x00308 }, + { 0x01e85, 0x00077, 0x00308 }, + { 0x01e86, 0x00057, 0x00307 }, + { 0x01e87, 0x00077, 0x00307 }, + { 0x01e88, 0x00057, 0x00323 }, + { 0x01e89, 0x00077, 0x00323 }, + { 0x01e8a, 0x00058, 0x00307 }, + { 0x01e8b, 0x00078, 0x00307 }, + { 0x01e8c, 0x00058, 0x00308 }, + { 0x01e8d, 0x00078, 0x00308 }, + { 0x01e8e, 0x00059, 0x00307 }, + { 0x01e8f, 0x00079, 0x00307 }, + { 0x01e90, 0x0005a, 0x00302 }, + { 0x01e91, 0x0007a, 0x00302 }, + { 0x01e92, 0x0005a, 0x00323 }, + { 0x01e93, 0x0007a, 0x00323 }, + { 0x01e94, 0x0005a, 0x00331 }, + { 0x01e95, 0x0007a, 0x00331 }, + { 0x01e96, 0x00068, 0x00331 }, + { 0x01e97, 0x00074, 0x00308 }, + { 0x01e98, 0x00077, 0x0030a }, + { 0x01e99, 0x00079, 0x0030a }, + { 0x01e9b, 0x0017f, 0x00307 }, + { 0x01ea0, 0x00041, 0x00323 }, + { 0x01ea1, 0x00061, 0x00323 }, + { 0x01ea2, 0x00041, 0x00309 }, + { 0x01ea3, 0x00061, 0x00309 }, + { 0x01ea4, 0x000c2, 0x00301 }, + { 0x01ea5, 0x000e2, 0x00301 }, + { 0x01ea6, 0x000c2, 0x00300 }, + { 0x01ea7, 0x000e2, 0x00300 }, + { 0x01ea8, 0x000c2, 0x00309 }, + { 0x01ea9, 0x000e2, 0x00309 }, + { 0x01eaa, 0x000c2, 0x00303 }, + { 0x01eab, 0x000e2, 0x00303 }, + { 0x01eac, 0x01ea0, 0x00302 }, + { 0x01ead, 0x01ea1, 0x00302 }, + { 0x01eae, 0x00102, 0x00301 }, + { 0x01eaf, 0x00103, 0x00301 }, + { 0x01eb0, 0x00102, 0x00300 }, + { 0x01eb1, 0x00103, 0x00300 }, + { 0x01eb2, 0x00102, 0x00309 }, + { 0x01eb3, 0x00103, 0x00309 }, + { 0x01eb4, 0x00102, 0x00303 }, + { 0x01eb5, 0x00103, 0x00303 }, + { 0x01eb6, 0x01ea0, 0x00306 }, + { 0x01eb7, 0x01ea1, 0x00306 }, + { 0x01eb8, 0x00045, 0x00323 }, + { 0x01eb9, 0x00065, 0x00323 }, + { 0x01eba, 0x00045, 0x00309 }, + { 0x01ebb, 0x00065, 0x00309 }, + { 0x01ebc, 0x00045, 0x00303 }, + { 0x01ebd, 0x00065, 0x00303 }, + { 0x01ebe, 0x000ca, 0x00301 }, + { 0x01ebf, 0x000ea, 0x00301 }, + { 0x01ec0, 0x000ca, 0x00300 }, + { 0x01ec1, 0x000ea, 0x00300 }, + { 0x01ec2, 0x000ca, 0x00309 }, + { 0x01ec3, 0x000ea, 0x00309 }, + { 0x01ec4, 0x000ca, 0x00303 }, + { 0x01ec5, 0x000ea, 0x00303 }, + { 0x01ec6, 0x01eb8, 0x00302 }, + { 0x01ec7, 0x01eb9, 0x00302 }, + { 0x01ec8, 0x00049, 0x00309 }, + { 0x01ec9, 0x00069, 0x00309 }, + { 0x01eca, 0x00049, 0x00323 }, + { 0x01ecb, 0x00069, 0x00323 }, + { 0x01ecc, 0x0004f, 0x00323 }, + { 0x01ecd, 0x0006f, 0x00323 }, + { 0x01ece, 0x0004f, 0x00309 }, + { 0x01ecf, 0x0006f, 0x00309 }, + { 0x01ed0, 0x000d4, 0x00301 }, + { 0x01ed1, 0x000f4, 0x00301 }, + { 0x01ed2, 0x000d4, 0x00300 }, + { 0x01ed3, 0x000f4, 0x00300 }, + { 0x01ed4, 0x000d4, 0x00309 }, + { 0x01ed5, 0x000f4, 0x00309 }, + { 0x01ed6, 0x000d4, 0x00303 }, + { 0x01ed7, 0x000f4, 0x00303 }, + { 0x01ed8, 0x01ecc, 0x00302 }, + { 0x01ed9, 0x01ecd, 0x00302 }, + { 0x01eda, 0x001a0, 0x00301 }, + { 0x01edb, 0x001a1, 0x00301 }, + { 0x01edc, 0x001a0, 0x00300 }, + { 0x01edd, 0x001a1, 0x00300 }, + { 0x01ede, 0x001a0, 0x00309 }, + { 0x01edf, 0x001a1, 0x00309 }, + { 0x01ee0, 0x001a0, 0x00303 }, + { 0x01ee1, 0x001a1, 0x00303 }, + { 0x01ee2, 0x001a0, 0x00323 }, + { 0x01ee3, 0x001a1, 0x00323 }, + { 0x01ee4, 0x00055, 0x00323 }, + { 0x01ee5, 0x00075, 0x00323 }, + { 0x01ee6, 0x00055, 0x00309 }, + { 0x01ee7, 0x00075, 0x00309 }, + { 0x01ee8, 0x001af, 0x00301 }, + { 0x01ee9, 0x001b0, 0x00301 }, + { 0x01eea, 0x001af, 0x00300 }, + { 0x01eeb, 0x001b0, 0x00300 }, + { 0x01eec, 0x001af, 0x00309 }, + { 0x01eed, 0x001b0, 0x00309 }, + { 0x01eee, 0x001af, 0x00303 }, + { 0x01eef, 0x001b0, 0x00303 }, + { 0x01ef0, 0x001af, 0x00323 }, + { 0x01ef1, 0x001b0, 0x00323 }, + { 0x01ef2, 0x00059, 0x00300 }, + { 0x01ef3, 0x00079, 0x00300 }, + { 0x01ef4, 0x00059, 0x00323 }, + { 0x01ef5, 0x00079, 0x00323 }, + { 0x01ef6, 0x00059, 0x00309 }, + { 0x01ef7, 0x00079, 0x00309 }, + { 0x01ef8, 0x00059, 0x00303 }, + { 0x01ef9, 0x00079, 0x00303 }, + { 0x01f00, 0x003b1, 0x00313 }, + { 0x01f01, 0x003b1, 0x00314 }, + { 0x01f02, 0x01f00, 0x00300 }, + { 0x01f03, 0x01f01, 0x00300 }, + { 0x01f04, 0x01f00, 0x00301 }, + { 0x01f05, 0x01f01, 0x00301 }, + { 0x01f06, 0x01f00, 0x00342 }, + { 0x01f07, 0x01f01, 0x00342 }, + { 0x01f08, 0x00391, 0x00313 }, + { 0x01f09, 0x00391, 0x00314 }, + { 0x01f0a, 0x01f08, 0x00300 }, + { 0x01f0b, 0x01f09, 0x00300 }, + { 0x01f0c, 0x01f08, 0x00301 }, + { 0x01f0d, 0x01f09, 0x00301 }, + { 0x01f0e, 0x01f08, 0x00342 }, + { 0x01f0f, 0x01f09, 0x00342 }, + { 0x01f10, 0x003b5, 0x00313 }, + { 0x01f11, 0x003b5, 0x00314 }, + { 0x01f12, 0x01f10, 0x00300 }, + { 0x01f13, 0x01f11, 0x00300 }, + { 0x01f14, 0x01f10, 0x00301 }, + { 0x01f15, 0x01f11, 0x00301 }, + { 0x01f18, 0x00395, 0x00313 }, + { 0x01f19, 0x00395, 0x00314 }, + { 0x01f1a, 0x01f18, 0x00300 }, + { 0x01f1b, 0x01f19, 0x00300 }, + { 0x01f1c, 0x01f18, 0x00301 }, + { 0x01f1d, 0x01f19, 0x00301 }, + { 0x01f20, 0x003b7, 0x00313 }, + { 0x01f21, 0x003b7, 0x00314 }, + { 0x01f22, 0x01f20, 0x00300 }, + { 0x01f23, 0x01f21, 0x00300 }, + { 0x01f24, 0x01f20, 0x00301 }, + { 0x01f25, 0x01f21, 0x00301 }, + { 0x01f26, 0x01f20, 0x00342 }, + { 0x01f27, 0x01f21, 0x00342 }, + { 0x01f28, 0x00397, 0x00313 }, + { 0x01f29, 0x00397, 0x00314 }, + { 0x01f2a, 0x01f28, 0x00300 }, + { 0x01f2b, 0x01f29, 0x00300 }, + { 0x01f2c, 0x01f28, 0x00301 }, + { 0x01f2d, 0x01f29, 0x00301 }, + { 0x01f2e, 0x01f28, 0x00342 }, + { 0x01f2f, 0x01f29, 0x00342 }, + { 0x01f30, 0x003b9, 0x00313 }, + { 0x01f31, 0x003b9, 0x00314 }, + { 0x01f32, 0x01f30, 0x00300 }, + { 0x01f33, 0x01f31, 0x00300 }, + { 0x01f34, 0x01f30, 0x00301 }, + { 0x01f35, 0x01f31, 0x00301 }, + { 0x01f36, 0x01f30, 0x00342 }, + { 0x01f37, 0x01f31, 0x00342 }, + { 0x01f38, 0x00399, 0x00313 }, + { 0x01f39, 0x00399, 0x00314 }, + { 0x01f3a, 0x01f38, 0x00300 }, + { 0x01f3b, 0x01f39, 0x00300 }, + { 0x01f3c, 0x01f38, 0x00301 }, + { 0x01f3d, 0x01f39, 0x00301 }, + { 0x01f3e, 0x01f38, 0x00342 }, + { 0x01f3f, 0x01f39, 0x00342 }, + { 0x01f40, 0x003bf, 0x00313 }, + { 0x01f41, 0x003bf, 0x00314 }, + { 0x01f42, 0x01f40, 0x00300 }, + { 0x01f43, 0x01f41, 0x00300 }, + { 0x01f44, 0x01f40, 0x00301 }, + { 0x01f45, 0x01f41, 0x00301 }, + { 0x01f48, 0x0039f, 0x00313 }, + { 0x01f49, 0x0039f, 0x00314 }, + { 0x01f4a, 0x01f48, 0x00300 }, + { 0x01f4b, 0x01f49, 0x00300 }, + { 0x01f4c, 0x01f48, 0x00301 }, + { 0x01f4d, 0x01f49, 0x00301 }, + { 0x01f50, 0x003c5, 0x00313 }, + { 0x01f51, 0x003c5, 0x00314 }, + { 0x01f52, 0x01f50, 0x00300 }, + { 0x01f53, 0x01f51, 0x00300 }, + { 0x01f54, 0x01f50, 0x00301 }, + { 0x01f55, 0x01f51, 0x00301 }, + { 0x01f56, 0x01f50, 0x00342 }, + { 0x01f57, 0x01f51, 0x00342 }, + { 0x01f59, 0x003a5, 0x00314 }, + { 0x01f5b, 0x01f59, 0x00300 }, + { 0x01f5d, 0x01f59, 0x00301 }, + { 0x01f5f, 0x01f59, 0x00342 }, + { 0x01f60, 0x003c9, 0x00313 }, + { 0x01f61, 0x003c9, 0x00314 }, + { 0x01f62, 0x01f60, 0x00300 }, + { 0x01f63, 0x01f61, 0x00300 }, + { 0x01f64, 0x01f60, 0x00301 }, + { 0x01f65, 0x01f61, 0x00301 }, + { 0x01f66, 0x01f60, 0x00342 }, + { 0x01f67, 0x01f61, 0x00342 }, + { 0x01f68, 0x003a9, 0x00313 }, + { 0x01f69, 0x003a9, 0x00314 }, + { 0x01f6a, 0x01f68, 0x00300 }, + { 0x01f6b, 0x01f69, 0x00300 }, + { 0x01f6c, 0x01f68, 0x00301 }, + { 0x01f6d, 0x01f69, 0x00301 }, + { 0x01f6e, 0x01f68, 0x00342 }, + { 0x01f6f, 0x01f69, 0x00342 }, + { 0x01f70, 0x003b1, 0x00300 }, + { 0x01f71, 0x003ac, 0x00000 }, + { 0x01f72, 0x003b5, 0x00300 }, + { 0x01f73, 0x003ad, 0x00000 }, + { 0x01f74, 0x003b7, 0x00300 }, + { 0x01f75, 0x003ae, 0x00000 }, + { 0x01f76, 0x003b9, 0x00300 }, + { 0x01f77, 0x003af, 0x00000 }, + { 0x01f78, 0x003bf, 0x00300 }, + { 0x01f79, 0x003cc, 0x00000 }, + { 0x01f7a, 0x003c5, 0x00300 }, + { 0x01f7b, 0x003cd, 0x00000 }, + { 0x01f7c, 0x003c9, 0x00300 }, + { 0x01f7d, 0x003ce, 0x00000 }, + { 0x01f80, 0x01f00, 0x00345 }, + { 0x01f81, 0x01f01, 0x00345 }, + { 0x01f82, 0x01f02, 0x00345 }, + { 0x01f83, 0x01f03, 0x00345 }, + { 0x01f84, 0x01f04, 0x00345 }, + { 0x01f85, 0x01f05, 0x00345 }, + { 0x01f86, 0x01f06, 0x00345 }, + { 0x01f87, 0x01f07, 0x00345 }, + { 0x01f88, 0x01f08, 0x00345 }, + { 0x01f89, 0x01f09, 0x00345 }, + { 0x01f8a, 0x01f0a, 0x00345 }, + { 0x01f8b, 0x01f0b, 0x00345 }, + { 0x01f8c, 0x01f0c, 0x00345 }, + { 0x01f8d, 0x01f0d, 0x00345 }, + { 0x01f8e, 0x01f0e, 0x00345 }, + { 0x01f8f, 0x01f0f, 0x00345 }, + { 0x01f90, 0x01f20, 0x00345 }, + { 0x01f91, 0x01f21, 0x00345 }, + { 0x01f92, 0x01f22, 0x00345 }, + { 0x01f93, 0x01f23, 0x00345 }, + { 0x01f94, 0x01f24, 0x00345 }, + { 0x01f95, 0x01f25, 0x00345 }, + { 0x01f96, 0x01f26, 0x00345 }, + { 0x01f97, 0x01f27, 0x00345 }, + { 0x01f98, 0x01f28, 0x00345 }, + { 0x01f99, 0x01f29, 0x00345 }, + { 0x01f9a, 0x01f2a, 0x00345 }, + { 0x01f9b, 0x01f2b, 0x00345 }, + { 0x01f9c, 0x01f2c, 0x00345 }, + { 0x01f9d, 0x01f2d, 0x00345 }, + { 0x01f9e, 0x01f2e, 0x00345 }, + { 0x01f9f, 0x01f2f, 0x00345 }, + { 0x01fa0, 0x01f60, 0x00345 }, + { 0x01fa1, 0x01f61, 0x00345 }, + { 0x01fa2, 0x01f62, 0x00345 }, + { 0x01fa3, 0x01f63, 0x00345 }, + { 0x01fa4, 0x01f64, 0x00345 }, + { 0x01fa5, 0x01f65, 0x00345 }, + { 0x01fa6, 0x01f66, 0x00345 }, + { 0x01fa7, 0x01f67, 0x00345 }, + { 0x01fa8, 0x01f68, 0x00345 }, + { 0x01fa9, 0x01f69, 0x00345 }, + { 0x01faa, 0x01f6a, 0x00345 }, + { 0x01fab, 0x01f6b, 0x00345 }, + { 0x01fac, 0x01f6c, 0x00345 }, + { 0x01fad, 0x01f6d, 0x00345 }, + { 0x01fae, 0x01f6e, 0x00345 }, + { 0x01faf, 0x01f6f, 0x00345 }, + { 0x01fb0, 0x003b1, 0x00306 }, + { 0x01fb1, 0x003b1, 0x00304 }, + { 0x01fb2, 0x01f70, 0x00345 }, + { 0x01fb3, 0x003b1, 0x00345 }, + { 0x01fb4, 0x003ac, 0x00345 }, + { 0x01fb6, 0x003b1, 0x00342 }, + { 0x01fb7, 0x01fb6, 0x00345 }, + { 0x01fb8, 0x00391, 0x00306 }, + { 0x01fb9, 0x00391, 0x00304 }, + { 0x01fba, 0x00391, 0x00300 }, + { 0x01fbb, 0x00386, 0x00000 }, + { 0x01fbc, 0x00391, 0x00345 }, + { 0x01fbe, 0x003b9, 0x00000 }, + { 0x01fc1, 0x000a8, 0x00342 }, + { 0x01fc2, 0x01f74, 0x00345 }, + { 0x01fc3, 0x003b7, 0x00345 }, + { 0x01fc4, 0x003ae, 0x00345 }, + { 0x01fc6, 0x003b7, 0x00342 }, + { 0x01fc7, 0x01fc6, 0x00345 }, + { 0x01fc8, 0x00395, 0x00300 }, + { 0x01fc9, 0x00388, 0x00000 }, + { 0x01fca, 0x00397, 0x00300 }, + { 0x01fcb, 0x00389, 0x00000 }, + { 0x01fcc, 0x00397, 0x00345 }, + { 0x01fcd, 0x01fbf, 0x00300 }, + { 0x01fce, 0x01fbf, 0x00301 }, + { 0x01fcf, 0x01fbf, 0x00342 }, + { 0x01fd0, 0x003b9, 0x00306 }, + { 0x01fd1, 0x003b9, 0x00304 }, + { 0x01fd2, 0x003ca, 0x00300 }, + { 0x01fd3, 0x00390, 0x00000 }, + { 0x01fd6, 0x003b9, 0x00342 }, + { 0x01fd7, 0x003ca, 0x00342 }, + { 0x01fd8, 0x00399, 0x00306 }, + { 0x01fd9, 0x00399, 0x00304 }, + { 0x01fda, 0x00399, 0x00300 }, + { 0x01fdb, 0x0038a, 0x00000 }, + { 0x01fdd, 0x01ffe, 0x00300 }, + { 0x01fde, 0x01ffe, 0x00301 }, + { 0x01fdf, 0x01ffe, 0x00342 }, + { 0x01fe0, 0x003c5, 0x00306 }, + { 0x01fe1, 0x003c5, 0x00304 }, + { 0x01fe2, 0x003cb, 0x00300 }, + { 0x01fe3, 0x003b0, 0x00000 }, + { 0x01fe4, 0x003c1, 0x00313 }, + { 0x01fe5, 0x003c1, 0x00314 }, + { 0x01fe6, 0x003c5, 0x00342 }, + { 0x01fe7, 0x003cb, 0x00342 }, + { 0x01fe8, 0x003a5, 0x00306 }, + { 0x01fe9, 0x003a5, 0x00304 }, + { 0x01fea, 0x003a5, 0x00300 }, + { 0x01feb, 0x0038e, 0x00000 }, + { 0x01fec, 0x003a1, 0x00314 }, + { 0x01fed, 0x000a8, 0x00300 }, + { 0x01fee, 0x00385, 0x00000 }, + { 0x01fef, 0x00060, 0x00000 }, + { 0x01ff2, 0x01f7c, 0x00345 }, + { 0x01ff3, 0x003c9, 0x00345 }, + { 0x01ff4, 0x003ce, 0x00345 }, + { 0x01ff6, 0x003c9, 0x00342 }, + { 0x01ff7, 0x01ff6, 0x00345 }, + { 0x01ff8, 0x0039f, 0x00300 }, + { 0x01ff9, 0x0038c, 0x00000 }, + { 0x01ffa, 0x003a9, 0x00300 }, + { 0x01ffb, 0x0038f, 0x00000 }, + { 0x01ffc, 0x003a9, 0x00345 }, + { 0x01ffd, 0x000b4, 0x00000 }, + { 0x02000, 0x02002, 0x00000 }, + { 0x02001, 0x02003, 0x00000 }, + { 0x02126, 0x003a9, 0x00000 }, + { 0x0212a, 0x0004b, 0x00000 }, + { 0x0212b, 0x000c5, 0x00000 }, + { 0x0219a, 0x02190, 0x00338 }, + { 0x0219b, 0x02192, 0x00338 }, + { 0x021ae, 0x02194, 0x00338 }, + { 0x021cd, 0x021d0, 0x00338 }, + { 0x021ce, 0x021d4, 0x00338 }, + { 0x021cf, 0x021d2, 0x00338 }, + { 0x02204, 0x02203, 0x00338 }, + { 0x02209, 0x02208, 0x00338 }, + { 0x0220c, 0x0220b, 0x00338 }, + { 0x02224, 0x02223, 0x00338 }, + { 0x02226, 0x02225, 0x00338 }, + { 0x02241, 0x0223c, 0x00338 }, + { 0x02244, 0x02243, 0x00338 }, + { 0x02247, 0x02245, 0x00338 }, + { 0x02249, 0x02248, 0x00338 }, + { 0x02260, 0x0003d, 0x00338 }, + { 0x02262, 0x02261, 0x00338 }, + { 0x0226d, 0x0224d, 0x00338 }, + { 0x0226e, 0x0003c, 0x00338 }, + { 0x0226f, 0x0003e, 0x00338 }, + { 0x02270, 0x02264, 0x00338 }, + { 0x02271, 0x02265, 0x00338 }, + { 0x02274, 0x02272, 0x00338 }, + { 0x02275, 0x02273, 0x00338 }, + { 0x02278, 0x02276, 0x00338 }, + { 0x02279, 0x02277, 0x00338 }, + { 0x02280, 0x0227a, 0x00338 }, + { 0x02281, 0x0227b, 0x00338 }, + { 0x02284, 0x02282, 0x00338 }, + { 0x02285, 0x02283, 0x00338 }, + { 0x02288, 0x02286, 0x00338 }, + { 0x02289, 0x02287, 0x00338 }, + { 0x022ac, 0x022a2, 0x00338 }, + { 0x022ad, 0x022a8, 0x00338 }, + { 0x022ae, 0x022a9, 0x00338 }, + { 0x022af, 0x022ab, 0x00338 }, + { 0x022e0, 0x0227c, 0x00338 }, + { 0x022e1, 0x0227d, 0x00338 }, + { 0x022e2, 0x02291, 0x00338 }, + { 0x022e3, 0x02292, 0x00338 }, + { 0x022ea, 0x022b2, 0x00338 }, + { 0x022eb, 0x022b3, 0x00338 }, + { 0x022ec, 0x022b4, 0x00338 }, + { 0x022ed, 0x022b5, 0x00338 }, + { 0x02329, 0x03008, 0x00000 }, + { 0x0232a, 0x03009, 0x00000 }, + { 0x02adc, 0x02add, 0x00338 }, + { 0x0304c, 0x0304b, 0x03099 }, + { 0x0304e, 0x0304d, 0x03099 }, + { 0x03050, 0x0304f, 0x03099 }, + { 0x03052, 0x03051, 0x03099 }, + { 0x03054, 0x03053, 0x03099 }, + { 0x03056, 0x03055, 0x03099 }, + { 0x03058, 0x03057, 0x03099 }, + { 0x0305a, 0x03059, 0x03099 }, + { 0x0305c, 0x0305b, 0x03099 }, + { 0x0305e, 0x0305d, 0x03099 }, + { 0x03060, 0x0305f, 0x03099 }, + { 0x03062, 0x03061, 0x03099 }, + { 0x03065, 0x03064, 0x03099 }, + { 0x03067, 0x03066, 0x03099 }, + { 0x03069, 0x03068, 0x03099 }, + { 0x03070, 0x0306f, 0x03099 }, + { 0x03071, 0x0306f, 0x0309a }, + { 0x03073, 0x03072, 0x03099 }, + { 0x03074, 0x03072, 0x0309a }, + { 0x03076, 0x03075, 0x03099 }, + { 0x03077, 0x03075, 0x0309a }, + { 0x03079, 0x03078, 0x03099 }, + { 0x0307a, 0x03078, 0x0309a }, + { 0x0307c, 0x0307b, 0x03099 }, + { 0x0307d, 0x0307b, 0x0309a }, + { 0x03094, 0x03046, 0x03099 }, + { 0x0309e, 0x0309d, 0x03099 }, + { 0x030ac, 0x030ab, 0x03099 }, + { 0x030ae, 0x030ad, 0x03099 }, + { 0x030b0, 0x030af, 0x03099 }, + { 0x030b2, 0x030b1, 0x03099 }, + { 0x030b4, 0x030b3, 0x03099 }, + { 0x030b6, 0x030b5, 0x03099 }, + { 0x030b8, 0x030b7, 0x03099 }, + { 0x030ba, 0x030b9, 0x03099 }, + { 0x030bc, 0x030bb, 0x03099 }, + { 0x030be, 0x030bd, 0x03099 }, + { 0x030c0, 0x030bf, 0x03099 }, + { 0x030c2, 0x030c1, 0x03099 }, + { 0x030c5, 0x030c4, 0x03099 }, + { 0x030c7, 0x030c6, 0x03099 }, + { 0x030c9, 0x030c8, 0x03099 }, + { 0x030d0, 0x030cf, 0x03099 }, + { 0x030d1, 0x030cf, 0x0309a }, + { 0x030d3, 0x030d2, 0x03099 }, + { 0x030d4, 0x030d2, 0x0309a }, + { 0x030d6, 0x030d5, 0x03099 }, + { 0x030d7, 0x030d5, 0x0309a }, + { 0x030d9, 0x030d8, 0x03099 }, + { 0x030da, 0x030d8, 0x0309a }, + { 0x030dc, 0x030db, 0x03099 }, + { 0x030dd, 0x030db, 0x0309a }, + { 0x030f4, 0x030a6, 0x03099 }, + { 0x030f7, 0x030ef, 0x03099 }, + { 0x030f8, 0x030f0, 0x03099 }, + { 0x030f9, 0x030f1, 0x03099 }, + { 0x030fa, 0x030f2, 0x03099 }, + { 0x030fe, 0x030fd, 0x03099 }, + { 0x0f900, 0x08c48, 0x00000 }, + { 0x0f901, 0x066f4, 0x00000 }, + { 0x0f902, 0x08eca, 0x00000 }, + { 0x0f903, 0x08cc8, 0x00000 }, + { 0x0f904, 0x06ed1, 0x00000 }, + { 0x0f905, 0x04e32, 0x00000 }, + { 0x0f906, 0x053e5, 0x00000 }, + { 0x0f907, 0x09f9c, 0x00000 }, + { 0x0f908, 0x09f9c, 0x00000 }, + { 0x0f909, 0x05951, 0x00000 }, + { 0x0f90a, 0x091d1, 0x00000 }, + { 0x0f90b, 0x05587, 0x00000 }, + { 0x0f90c, 0x05948, 0x00000 }, + { 0x0f90d, 0x061f6, 0x00000 }, + { 0x0f90e, 0x07669, 0x00000 }, + { 0x0f90f, 0x07f85, 0x00000 }, + { 0x0f910, 0x0863f, 0x00000 }, + { 0x0f911, 0x087ba, 0x00000 }, + { 0x0f912, 0x088f8, 0x00000 }, + { 0x0f913, 0x0908f, 0x00000 }, + { 0x0f914, 0x06a02, 0x00000 }, + { 0x0f915, 0x06d1b, 0x00000 }, + { 0x0f916, 0x070d9, 0x00000 }, + { 0x0f917, 0x073de, 0x00000 }, + { 0x0f918, 0x0843d, 0x00000 }, + { 0x0f919, 0x0916a, 0x00000 }, + { 0x0f91a, 0x099f1, 0x00000 }, + { 0x0f91b, 0x04e82, 0x00000 }, + { 0x0f91c, 0x05375, 0x00000 }, + { 0x0f91d, 0x06b04, 0x00000 }, + { 0x0f91e, 0x0721b, 0x00000 }, + { 0x0f91f, 0x0862d, 0x00000 }, + { 0x0f920, 0x09e1e, 0x00000 }, + { 0x0f921, 0x05d50, 0x00000 }, + { 0x0f922, 0x06feb, 0x00000 }, + { 0x0f923, 0x085cd, 0x00000 }, + { 0x0f924, 0x08964, 0x00000 }, + { 0x0f925, 0x062c9, 0x00000 }, + { 0x0f926, 0x081d8, 0x00000 }, + { 0x0f927, 0x0881f, 0x00000 }, + { 0x0f928, 0x05eca, 0x00000 }, + { 0x0f929, 0x06717, 0x00000 }, + { 0x0f92a, 0x06d6a, 0x00000 }, + { 0x0f92b, 0x072fc, 0x00000 }, + { 0x0f92c, 0x090ce, 0x00000 }, + { 0x0f92d, 0x04f86, 0x00000 }, + { 0x0f92e, 0x051b7, 0x00000 }, + { 0x0f92f, 0x052de, 0x00000 }, + { 0x0f930, 0x064c4, 0x00000 }, + { 0x0f931, 0x06ad3, 0x00000 }, + { 0x0f932, 0x07210, 0x00000 }, + { 0x0f933, 0x076e7, 0x00000 }, + { 0x0f934, 0x08001, 0x00000 }, + { 0x0f935, 0x08606, 0x00000 }, + { 0x0f936, 0x0865c, 0x00000 }, + { 0x0f937, 0x08def, 0x00000 }, + { 0x0f938, 0x09732, 0x00000 }, + { 0x0f939, 0x09b6f, 0x00000 }, + { 0x0f93a, 0x09dfa, 0x00000 }, + { 0x0f93b, 0x0788c, 0x00000 }, + { 0x0f93c, 0x0797f, 0x00000 }, + { 0x0f93d, 0x07da0, 0x00000 }, + { 0x0f93e, 0x083c9, 0x00000 }, + { 0x0f93f, 0x09304, 0x00000 }, + { 0x0f940, 0x09e7f, 0x00000 }, + { 0x0f941, 0x08ad6, 0x00000 }, + { 0x0f942, 0x058df, 0x00000 }, + { 0x0f943, 0x05f04, 0x00000 }, + { 0x0f944, 0x07c60, 0x00000 }, + { 0x0f945, 0x0807e, 0x00000 }, + { 0x0f946, 0x07262, 0x00000 }, + { 0x0f947, 0x078ca, 0x00000 }, + { 0x0f948, 0x08cc2, 0x00000 }, + { 0x0f949, 0x096f7, 0x00000 }, + { 0x0f94a, 0x058d8, 0x00000 }, + { 0x0f94b, 0x05c62, 0x00000 }, + { 0x0f94c, 0x06a13, 0x00000 }, + { 0x0f94d, 0x06dda, 0x00000 }, + { 0x0f94e, 0x06f0f, 0x00000 }, + { 0x0f94f, 0x07d2f, 0x00000 }, + { 0x0f950, 0x07e37, 0x00000 }, + { 0x0f951, 0x0964b, 0x00000 }, + { 0x0f952, 0x052d2, 0x00000 }, + { 0x0f953, 0x0808b, 0x00000 }, + { 0x0f954, 0x051dc, 0x00000 }, + { 0x0f955, 0x051cc, 0x00000 }, + { 0x0f956, 0x07a1c, 0x00000 }, + { 0x0f957, 0x07dbe, 0x00000 }, + { 0x0f958, 0x083f1, 0x00000 }, + { 0x0f959, 0x09675, 0x00000 }, + { 0x0f95a, 0x08b80, 0x00000 }, + { 0x0f95b, 0x062cf, 0x00000 }, + { 0x0f95c, 0x06a02, 0x00000 }, + { 0x0f95d, 0x08afe, 0x00000 }, + { 0x0f95e, 0x04e39, 0x00000 }, + { 0x0f95f, 0x05be7, 0x00000 }, + { 0x0f960, 0x06012, 0x00000 }, + { 0x0f961, 0x07387, 0x00000 }, + { 0x0f962, 0x07570, 0x00000 }, + { 0x0f963, 0x05317, 0x00000 }, + { 0x0f964, 0x078fb, 0x00000 }, + { 0x0f965, 0x04fbf, 0x00000 }, + { 0x0f966, 0x05fa9, 0x00000 }, + { 0x0f967, 0x04e0d, 0x00000 }, + { 0x0f968, 0x06ccc, 0x00000 }, + { 0x0f969, 0x06578, 0x00000 }, + { 0x0f96a, 0x07d22, 0x00000 }, + { 0x0f96b, 0x053c3, 0x00000 }, + { 0x0f96c, 0x0585e, 0x00000 }, + { 0x0f96d, 0x07701, 0x00000 }, + { 0x0f96e, 0x08449, 0x00000 }, + { 0x0f96f, 0x08aaa, 0x00000 }, + { 0x0f970, 0x06bba, 0x00000 }, + { 0x0f971, 0x08fb0, 0x00000 }, + { 0x0f972, 0x06c88, 0x00000 }, + { 0x0f973, 0x062fe, 0x00000 }, + { 0x0f974, 0x082e5, 0x00000 }, + { 0x0f975, 0x063a0, 0x00000 }, + { 0x0f976, 0x07565, 0x00000 }, + { 0x0f977, 0x04eae, 0x00000 }, + { 0x0f978, 0x05169, 0x00000 }, + { 0x0f979, 0x051c9, 0x00000 }, + { 0x0f97a, 0x06881, 0x00000 }, + { 0x0f97b, 0x07ce7, 0x00000 }, + { 0x0f97c, 0x0826f, 0x00000 }, + { 0x0f97d, 0x08ad2, 0x00000 }, + { 0x0f97e, 0x091cf, 0x00000 }, + { 0x0f97f, 0x052f5, 0x00000 }, + { 0x0f980, 0x05442, 0x00000 }, + { 0x0f981, 0x05973, 0x00000 }, + { 0x0f982, 0x05eec, 0x00000 }, + { 0x0f983, 0x065c5, 0x00000 }, + { 0x0f984, 0x06ffe, 0x00000 }, + { 0x0f985, 0x0792a, 0x00000 }, + { 0x0f986, 0x095ad, 0x00000 }, + { 0x0f987, 0x09a6a, 0x00000 }, + { 0x0f988, 0x09e97, 0x00000 }, + { 0x0f989, 0x09ece, 0x00000 }, + { 0x0f98a, 0x0529b, 0x00000 }, + { 0x0f98b, 0x066c6, 0x00000 }, + { 0x0f98c, 0x06b77, 0x00000 }, + { 0x0f98d, 0x08f62, 0x00000 }, + { 0x0f98e, 0x05e74, 0x00000 }, + { 0x0f98f, 0x06190, 0x00000 }, + { 0x0f990, 0x06200, 0x00000 }, + { 0x0f991, 0x0649a, 0x00000 }, + { 0x0f992, 0x06f23, 0x00000 }, + { 0x0f993, 0x07149, 0x00000 }, + { 0x0f994, 0x07489, 0x00000 }, + { 0x0f995, 0x079ca, 0x00000 }, + { 0x0f996, 0x07df4, 0x00000 }, + { 0x0f997, 0x0806f, 0x00000 }, + { 0x0f998, 0x08f26, 0x00000 }, + { 0x0f999, 0x084ee, 0x00000 }, + { 0x0f99a, 0x09023, 0x00000 }, + { 0x0f99b, 0x0934a, 0x00000 }, + { 0x0f99c, 0x05217, 0x00000 }, + { 0x0f99d, 0x052a3, 0x00000 }, + { 0x0f99e, 0x054bd, 0x00000 }, + { 0x0f99f, 0x070c8, 0x00000 }, + { 0x0f9a0, 0x088c2, 0x00000 }, + { 0x0f9a1, 0x08aaa, 0x00000 }, + { 0x0f9a2, 0x05ec9, 0x00000 }, + { 0x0f9a3, 0x05ff5, 0x00000 }, + { 0x0f9a4, 0x0637b, 0x00000 }, + { 0x0f9a5, 0x06bae, 0x00000 }, + { 0x0f9a6, 0x07c3e, 0x00000 }, + { 0x0f9a7, 0x07375, 0x00000 }, + { 0x0f9a8, 0x04ee4, 0x00000 }, + { 0x0f9a9, 0x056f9, 0x00000 }, + { 0x0f9aa, 0x05be7, 0x00000 }, + { 0x0f9ab, 0x05dba, 0x00000 }, + { 0x0f9ac, 0x0601c, 0x00000 }, + { 0x0f9ad, 0x073b2, 0x00000 }, + { 0x0f9ae, 0x07469, 0x00000 }, + { 0x0f9af, 0x07f9a, 0x00000 }, + { 0x0f9b0, 0x08046, 0x00000 }, + { 0x0f9b1, 0x09234, 0x00000 }, + { 0x0f9b2, 0x096f6, 0x00000 }, + { 0x0f9b3, 0x09748, 0x00000 }, + { 0x0f9b4, 0x09818, 0x00000 }, + { 0x0f9b5, 0x04f8b, 0x00000 }, + { 0x0f9b6, 0x079ae, 0x00000 }, + { 0x0f9b7, 0x091b4, 0x00000 }, + { 0x0f9b8, 0x096b8, 0x00000 }, + { 0x0f9b9, 0x060e1, 0x00000 }, + { 0x0f9ba, 0x04e86, 0x00000 }, + { 0x0f9bb, 0x050da, 0x00000 }, + { 0x0f9bc, 0x05bee, 0x00000 }, + { 0x0f9bd, 0x05c3f, 0x00000 }, + { 0x0f9be, 0x06599, 0x00000 }, + { 0x0f9bf, 0x06a02, 0x00000 }, + { 0x0f9c0, 0x071ce, 0x00000 }, + { 0x0f9c1, 0x07642, 0x00000 }, + { 0x0f9c2, 0x084fc, 0x00000 }, + { 0x0f9c3, 0x0907c, 0x00000 }, + { 0x0f9c4, 0x09f8d, 0x00000 }, + { 0x0f9c5, 0x06688, 0x00000 }, + { 0x0f9c6, 0x0962e, 0x00000 }, + { 0x0f9c7, 0x05289, 0x00000 }, + { 0x0f9c8, 0x0677b, 0x00000 }, + { 0x0f9c9, 0x067f3, 0x00000 }, + { 0x0f9ca, 0x06d41, 0x00000 }, + { 0x0f9cb, 0x06e9c, 0x00000 }, + { 0x0f9cc, 0x07409, 0x00000 }, + { 0x0f9cd, 0x07559, 0x00000 }, + { 0x0f9ce, 0x0786b, 0x00000 }, + { 0x0f9cf, 0x07d10, 0x00000 }, + { 0x0f9d0, 0x0985e, 0x00000 }, + { 0x0f9d1, 0x0516d, 0x00000 }, + { 0x0f9d2, 0x0622e, 0x00000 }, + { 0x0f9d3, 0x09678, 0x00000 }, + { 0x0f9d4, 0x0502b, 0x00000 }, + { 0x0f9d5, 0x05d19, 0x00000 }, + { 0x0f9d6, 0x06dea, 0x00000 }, + { 0x0f9d7, 0x08f2a, 0x00000 }, + { 0x0f9d8, 0x05f8b, 0x00000 }, + { 0x0f9d9, 0x06144, 0x00000 }, + { 0x0f9da, 0x06817, 0x00000 }, + { 0x0f9db, 0x07387, 0x00000 }, + { 0x0f9dc, 0x09686, 0x00000 }, + { 0x0f9dd, 0x05229, 0x00000 }, + { 0x0f9de, 0x0540f, 0x00000 }, + { 0x0f9df, 0x05c65, 0x00000 }, + { 0x0f9e0, 0x06613, 0x00000 }, + { 0x0f9e1, 0x0674e, 0x00000 }, + { 0x0f9e2, 0x068a8, 0x00000 }, + { 0x0f9e3, 0x06ce5, 0x00000 }, + { 0x0f9e4, 0x07406, 0x00000 }, + { 0x0f9e5, 0x075e2, 0x00000 }, + { 0x0f9e6, 0x07f79, 0x00000 }, + { 0x0f9e7, 0x088cf, 0x00000 }, + { 0x0f9e8, 0x088e1, 0x00000 }, + { 0x0f9e9, 0x091cc, 0x00000 }, + { 0x0f9ea, 0x096e2, 0x00000 }, + { 0x0f9eb, 0x0533f, 0x00000 }, + { 0x0f9ec, 0x06eba, 0x00000 }, + { 0x0f9ed, 0x0541d, 0x00000 }, + { 0x0f9ee, 0x071d0, 0x00000 }, + { 0x0f9ef, 0x07498, 0x00000 }, + { 0x0f9f0, 0x085fa, 0x00000 }, + { 0x0f9f1, 0x096a3, 0x00000 }, + { 0x0f9f2, 0x09c57, 0x00000 }, + { 0x0f9f3, 0x09e9f, 0x00000 }, + { 0x0f9f4, 0x06797, 0x00000 }, + { 0x0f9f5, 0x06dcb, 0x00000 }, + { 0x0f9f6, 0x081e8, 0x00000 }, + { 0x0f9f7, 0x07acb, 0x00000 }, + { 0x0f9f8, 0x07b20, 0x00000 }, + { 0x0f9f9, 0x07c92, 0x00000 }, + { 0x0f9fa, 0x072c0, 0x00000 }, + { 0x0f9fb, 0x07099, 0x00000 }, + { 0x0f9fc, 0x08b58, 0x00000 }, + { 0x0f9fd, 0x04ec0, 0x00000 }, + { 0x0f9fe, 0x08336, 0x00000 }, + { 0x0f9ff, 0x0523a, 0x00000 }, + { 0x0fa00, 0x05207, 0x00000 }, + { 0x0fa01, 0x05ea6, 0x00000 }, + { 0x0fa02, 0x062d3, 0x00000 }, + { 0x0fa03, 0x07cd6, 0x00000 }, + { 0x0fa04, 0x05b85, 0x00000 }, + { 0x0fa05, 0x06d1e, 0x00000 }, + { 0x0fa06, 0x066b4, 0x00000 }, + { 0x0fa07, 0x08f3b, 0x00000 }, + { 0x0fa08, 0x0884c, 0x00000 }, + { 0x0fa09, 0x0964d, 0x00000 }, + { 0x0fa0a, 0x0898b, 0x00000 }, + { 0x0fa0b, 0x05ed3, 0x00000 }, + { 0x0fa0c, 0x05140, 0x00000 }, + { 0x0fa0d, 0x055c0, 0x00000 }, + { 0x0fa10, 0x0585a, 0x00000 }, + { 0x0fa12, 0x06674, 0x00000 }, + { 0x0fa15, 0x051de, 0x00000 }, + { 0x0fa16, 0x0732a, 0x00000 }, + { 0x0fa17, 0x076ca, 0x00000 }, + { 0x0fa18, 0x0793c, 0x00000 }, + { 0x0fa19, 0x0795e, 0x00000 }, + { 0x0fa1a, 0x07965, 0x00000 }, + { 0x0fa1b, 0x0798f, 0x00000 }, + { 0x0fa1c, 0x09756, 0x00000 }, + { 0x0fa1d, 0x07cbe, 0x00000 }, + { 0x0fa1e, 0x07fbd, 0x00000 }, + { 0x0fa20, 0x08612, 0x00000 }, + { 0x0fa22, 0x08af8, 0x00000 }, + { 0x0fa25, 0x09038, 0x00000 }, + { 0x0fa26, 0x090fd, 0x00000 }, + { 0x0fa2a, 0x098ef, 0x00000 }, + { 0x0fa2b, 0x098fc, 0x00000 }, + { 0x0fa2c, 0x09928, 0x00000 }, + { 0x0fa2d, 0x09db4, 0x00000 }, + { 0x0fa30, 0x04fae, 0x00000 }, + { 0x0fa31, 0x050e7, 0x00000 }, + { 0x0fa32, 0x0514d, 0x00000 }, + { 0x0fa33, 0x052c9, 0x00000 }, + { 0x0fa34, 0x052e4, 0x00000 }, + { 0x0fa35, 0x05351, 0x00000 }, + { 0x0fa36, 0x0559d, 0x00000 }, + { 0x0fa37, 0x05606, 0x00000 }, + { 0x0fa38, 0x05668, 0x00000 }, + { 0x0fa39, 0x05840, 0x00000 }, + { 0x0fa3a, 0x058a8, 0x00000 }, + { 0x0fa3b, 0x05c64, 0x00000 }, + { 0x0fa3c, 0x05c6e, 0x00000 }, + { 0x0fa3d, 0x06094, 0x00000 }, + { 0x0fa3e, 0x06168, 0x00000 }, + { 0x0fa3f, 0x0618e, 0x00000 }, + { 0x0fa40, 0x061f2, 0x00000 }, + { 0x0fa41, 0x0654f, 0x00000 }, + { 0x0fa42, 0x065e2, 0x00000 }, + { 0x0fa43, 0x06691, 0x00000 }, + { 0x0fa44, 0x06885, 0x00000 }, + { 0x0fa45, 0x06d77, 0x00000 }, + { 0x0fa46, 0x06e1a, 0x00000 }, + { 0x0fa47, 0x06f22, 0x00000 }, + { 0x0fa48, 0x0716e, 0x00000 }, + { 0x0fa49, 0x0722b, 0x00000 }, + { 0x0fa4a, 0x07422, 0x00000 }, + { 0x0fa4b, 0x07891, 0x00000 }, + { 0x0fa4c, 0x0793e, 0x00000 }, + { 0x0fa4d, 0x07949, 0x00000 }, + { 0x0fa4e, 0x07948, 0x00000 }, + { 0x0fa4f, 0x07950, 0x00000 }, + { 0x0fa50, 0x07956, 0x00000 }, + { 0x0fa51, 0x0795d, 0x00000 }, + { 0x0fa52, 0x0798d, 0x00000 }, + { 0x0fa53, 0x0798e, 0x00000 }, + { 0x0fa54, 0x07a40, 0x00000 }, + { 0x0fa55, 0x07a81, 0x00000 }, + { 0x0fa56, 0x07bc0, 0x00000 }, + { 0x0fa57, 0x07df4, 0x00000 }, + { 0x0fa58, 0x07e09, 0x00000 }, + { 0x0fa59, 0x07e41, 0x00000 }, + { 0x0fa5a, 0x07f72, 0x00000 }, + { 0x0fa5b, 0x08005, 0x00000 }, + { 0x0fa5c, 0x081ed, 0x00000 }, + { 0x0fa5d, 0x08279, 0x00000 }, + { 0x0fa5e, 0x08279, 0x00000 }, + { 0x0fa5f, 0x08457, 0x00000 }, + { 0x0fa60, 0x08910, 0x00000 }, + { 0x0fa61, 0x08996, 0x00000 }, + { 0x0fa62, 0x08b01, 0x00000 }, + { 0x0fa63, 0x08b39, 0x00000 }, + { 0x0fa64, 0x08cd3, 0x00000 }, + { 0x0fa65, 0x08d08, 0x00000 }, + { 0x0fa66, 0x08fb6, 0x00000 }, + { 0x0fa67, 0x09038, 0x00000 }, + { 0x0fa68, 0x096e3, 0x00000 }, + { 0x0fa69, 0x097ff, 0x00000 }, + { 0x0fa6a, 0x0983b, 0x00000 }, + { 0x0fa6b, 0x06075, 0x00000 }, + { 0x0fa6c, 0x242ee, 0x00000 }, + { 0x0fa6d, 0x08218, 0x00000 }, + { 0x0fa70, 0x04e26, 0x00000 }, + { 0x0fa71, 0x051b5, 0x00000 }, + { 0x0fa72, 0x05168, 0x00000 }, + { 0x0fa73, 0x04f80, 0x00000 }, + { 0x0fa74, 0x05145, 0x00000 }, + { 0x0fa75, 0x05180, 0x00000 }, + { 0x0fa76, 0x052c7, 0x00000 }, + { 0x0fa77, 0x052fa, 0x00000 }, + { 0x0fa78, 0x0559d, 0x00000 }, + { 0x0fa79, 0x05555, 0x00000 }, + { 0x0fa7a, 0x05599, 0x00000 }, + { 0x0fa7b, 0x055e2, 0x00000 }, + { 0x0fa7c, 0x0585a, 0x00000 }, + { 0x0fa7d, 0x058b3, 0x00000 }, + { 0x0fa7e, 0x05944, 0x00000 }, + { 0x0fa7f, 0x05954, 0x00000 }, + { 0x0fa80, 0x05a62, 0x00000 }, + { 0x0fa81, 0x05b28, 0x00000 }, + { 0x0fa82, 0x05ed2, 0x00000 }, + { 0x0fa83, 0x05ed9, 0x00000 }, + { 0x0fa84, 0x05f69, 0x00000 }, + { 0x0fa85, 0x05fad, 0x00000 }, + { 0x0fa86, 0x060d8, 0x00000 }, + { 0x0fa87, 0x0614e, 0x00000 }, + { 0x0fa88, 0x06108, 0x00000 }, + { 0x0fa89, 0x0618e, 0x00000 }, + { 0x0fa8a, 0x06160, 0x00000 }, + { 0x0fa8b, 0x061f2, 0x00000 }, + { 0x0fa8c, 0x06234, 0x00000 }, + { 0x0fa8d, 0x063c4, 0x00000 }, + { 0x0fa8e, 0x0641c, 0x00000 }, + { 0x0fa8f, 0x06452, 0x00000 }, + { 0x0fa90, 0x06556, 0x00000 }, + { 0x0fa91, 0x06674, 0x00000 }, + { 0x0fa92, 0x06717, 0x00000 }, + { 0x0fa93, 0x0671b, 0x00000 }, + { 0x0fa94, 0x06756, 0x00000 }, + { 0x0fa95, 0x06b79, 0x00000 }, + { 0x0fa96, 0x06bba, 0x00000 }, + { 0x0fa97, 0x06d41, 0x00000 }, + { 0x0fa98, 0x06edb, 0x00000 }, + { 0x0fa99, 0x06ecb, 0x00000 }, + { 0x0fa9a, 0x06f22, 0x00000 }, + { 0x0fa9b, 0x0701e, 0x00000 }, + { 0x0fa9c, 0x0716e, 0x00000 }, + { 0x0fa9d, 0x077a7, 0x00000 }, + { 0x0fa9e, 0x07235, 0x00000 }, + { 0x0fa9f, 0x072af, 0x00000 }, + { 0x0faa0, 0x0732a, 0x00000 }, + { 0x0faa1, 0x07471, 0x00000 }, + { 0x0faa2, 0x07506, 0x00000 }, + { 0x0faa3, 0x0753b, 0x00000 }, + { 0x0faa4, 0x0761d, 0x00000 }, + { 0x0faa5, 0x0761f, 0x00000 }, + { 0x0faa6, 0x076ca, 0x00000 }, + { 0x0faa7, 0x076db, 0x00000 }, + { 0x0faa8, 0x076f4, 0x00000 }, + { 0x0faa9, 0x0774a, 0x00000 }, + { 0x0faaa, 0x07740, 0x00000 }, + { 0x0faab, 0x078cc, 0x00000 }, + { 0x0faac, 0x07ab1, 0x00000 }, + { 0x0faad, 0x07bc0, 0x00000 }, + { 0x0faae, 0x07c7b, 0x00000 }, + { 0x0faaf, 0x07d5b, 0x00000 }, + { 0x0fab0, 0x07df4, 0x00000 }, + { 0x0fab1, 0x07f3e, 0x00000 }, + { 0x0fab2, 0x08005, 0x00000 }, + { 0x0fab3, 0x08352, 0x00000 }, + { 0x0fab4, 0x083ef, 0x00000 }, + { 0x0fab5, 0x08779, 0x00000 }, + { 0x0fab6, 0x08941, 0x00000 }, + { 0x0fab7, 0x08986, 0x00000 }, + { 0x0fab8, 0x08996, 0x00000 }, + { 0x0fab9, 0x08abf, 0x00000 }, + { 0x0faba, 0x08af8, 0x00000 }, + { 0x0fabb, 0x08acb, 0x00000 }, + { 0x0fabc, 0x08b01, 0x00000 }, + { 0x0fabd, 0x08afe, 0x00000 }, + { 0x0fabe, 0x08aed, 0x00000 }, + { 0x0fabf, 0x08b39, 0x00000 }, + { 0x0fac0, 0x08b8a, 0x00000 }, + { 0x0fac1, 0x08d08, 0x00000 }, + { 0x0fac2, 0x08f38, 0x00000 }, + { 0x0fac3, 0x09072, 0x00000 }, + { 0x0fac4, 0x09199, 0x00000 }, + { 0x0fac5, 0x09276, 0x00000 }, + { 0x0fac6, 0x0967c, 0x00000 }, + { 0x0fac7, 0x096e3, 0x00000 }, + { 0x0fac8, 0x09756, 0x00000 }, + { 0x0fac9, 0x097db, 0x00000 }, + { 0x0faca, 0x097ff, 0x00000 }, + { 0x0facb, 0x0980b, 0x00000 }, + { 0x0facc, 0x0983b, 0x00000 }, + { 0x0facd, 0x09b12, 0x00000 }, + { 0x0face, 0x09f9c, 0x00000 }, + { 0x0facf, 0x2284a, 0x00000 }, + { 0x0fad0, 0x22844, 0x00000 }, + { 0x0fad1, 0x233d5, 0x00000 }, + { 0x0fad2, 0x03b9d, 0x00000 }, + { 0x0fad3, 0x04018, 0x00000 }, + { 0x0fad4, 0x04039, 0x00000 }, + { 0x0fad5, 0x25249, 0x00000 }, + { 0x0fad6, 0x25cd0, 0x00000 }, + { 0x0fad7, 0x27ed3, 0x00000 }, + { 0x0fad8, 0x09f43, 0x00000 }, + { 0x0fad9, 0x09f8e, 0x00000 }, + { 0x0fb1d, 0x005d9, 0x005b4 }, + { 0x0fb1f, 0x005f2, 0x005b7 }, + { 0x0fb2a, 0x005e9, 0x005c1 }, + { 0x0fb2b, 0x005e9, 0x005c2 }, + { 0x0fb2c, 0x0fb49, 0x005c1 }, + { 0x0fb2d, 0x0fb49, 0x005c2 }, + { 0x0fb2e, 0x005d0, 0x005b7 }, + { 0x0fb2f, 0x005d0, 0x005b8 }, + { 0x0fb30, 0x005d0, 0x005bc }, + { 0x0fb31, 0x005d1, 0x005bc }, + { 0x0fb32, 0x005d2, 0x005bc }, + { 0x0fb33, 0x005d3, 0x005bc }, + { 0x0fb34, 0x005d4, 0x005bc }, + { 0x0fb35, 0x005d5, 0x005bc }, + { 0x0fb36, 0x005d6, 0x005bc }, + { 0x0fb38, 0x005d8, 0x005bc }, + { 0x0fb39, 0x005d9, 0x005bc }, + { 0x0fb3a, 0x005da, 0x005bc }, + { 0x0fb3b, 0x005db, 0x005bc }, + { 0x0fb3c, 0x005dc, 0x005bc }, + { 0x0fb3e, 0x005de, 0x005bc }, + { 0x0fb40, 0x005e0, 0x005bc }, + { 0x0fb41, 0x005e1, 0x005bc }, + { 0x0fb43, 0x005e3, 0x005bc }, + { 0x0fb44, 0x005e4, 0x005bc }, + { 0x0fb46, 0x005e6, 0x005bc }, + { 0x0fb47, 0x005e7, 0x005bc }, + { 0x0fb48, 0x005e8, 0x005bc }, + { 0x0fb49, 0x005e9, 0x005bc }, + { 0x0fb4a, 0x005ea, 0x005bc }, + { 0x0fb4b, 0x005d5, 0x005b9 }, + { 0x0fb4c, 0x005d1, 0x005bf }, + { 0x0fb4d, 0x005db, 0x005bf }, + { 0x0fb4e, 0x005e4, 0x005bf }, + { 0x1109a, 0x11099, 0x110ba }, + { 0x1109c, 0x1109b, 0x110ba }, + { 0x110ab, 0x110a5, 0x110ba }, + { 0x1d15e, 0x1d157, 0x1d165 }, + { 0x1d15f, 0x1d158, 0x1d165 }, + { 0x1d160, 0x1d15f, 0x1d16e }, + { 0x1d161, 0x1d15f, 0x1d16f }, + { 0x1d162, 0x1d15f, 0x1d170 }, + { 0x1d163, 0x1d15f, 0x1d171 }, + { 0x1d164, 0x1d15f, 0x1d172 }, + { 0x1d1bb, 0x1d1b9, 0x1d165 }, + { 0x1d1bc, 0x1d1ba, 0x1d165 }, + { 0x1d1bd, 0x1d1bb, 0x1d16e }, + { 0x1d1be, 0x1d1bc, 0x1d16e }, + { 0x1d1bf, 0x1d1bb, 0x1d16f }, + { 0x1d1c0, 0x1d1bc, 0x1d16f }, + { 0x2f800, 0x04e3d, 0x00000 }, + { 0x2f801, 0x04e38, 0x00000 }, + { 0x2f802, 0x04e41, 0x00000 }, + { 0x2f803, 0x20122, 0x00000 }, + { 0x2f804, 0x04f60, 0x00000 }, + { 0x2f805, 0x04fae, 0x00000 }, + { 0x2f806, 0x04fbb, 0x00000 }, + { 0x2f807, 0x05002, 0x00000 }, + { 0x2f808, 0x0507a, 0x00000 }, + { 0x2f809, 0x05099, 0x00000 }, + { 0x2f80a, 0x050e7, 0x00000 }, + { 0x2f80b, 0x050cf, 0x00000 }, + { 0x2f80c, 0x0349e, 0x00000 }, + { 0x2f80d, 0x2063a, 0x00000 }, + { 0x2f80e, 0x0514d, 0x00000 }, + { 0x2f80f, 0x05154, 0x00000 }, + { 0x2f810, 0x05164, 0x00000 }, + { 0x2f811, 0x05177, 0x00000 }, + { 0x2f812, 0x2051c, 0x00000 }, + { 0x2f813, 0x034b9, 0x00000 }, + { 0x2f814, 0x05167, 0x00000 }, + { 0x2f815, 0x0518d, 0x00000 }, + { 0x2f816, 0x2054b, 0x00000 }, + { 0x2f817, 0x05197, 0x00000 }, + { 0x2f818, 0x051a4, 0x00000 }, + { 0x2f819, 0x04ecc, 0x00000 }, + { 0x2f81a, 0x051ac, 0x00000 }, + { 0x2f81b, 0x051b5, 0x00000 }, + { 0x2f81c, 0x291df, 0x00000 }, + { 0x2f81d, 0x051f5, 0x00000 }, + { 0x2f81e, 0x05203, 0x00000 }, + { 0x2f81f, 0x034df, 0x00000 }, + { 0x2f820, 0x0523b, 0x00000 }, + { 0x2f821, 0x05246, 0x00000 }, + { 0x2f822, 0x05272, 0x00000 }, + { 0x2f823, 0x05277, 0x00000 }, + { 0x2f824, 0x03515, 0x00000 }, + { 0x2f825, 0x052c7, 0x00000 }, + { 0x2f826, 0x052c9, 0x00000 }, + { 0x2f827, 0x052e4, 0x00000 }, + { 0x2f828, 0x052fa, 0x00000 }, + { 0x2f829, 0x05305, 0x00000 }, + { 0x2f82a, 0x05306, 0x00000 }, + { 0x2f82b, 0x05317, 0x00000 }, + { 0x2f82c, 0x05349, 0x00000 }, + { 0x2f82d, 0x05351, 0x00000 }, + { 0x2f82e, 0x0535a, 0x00000 }, + { 0x2f82f, 0x05373, 0x00000 }, + { 0x2f830, 0x0537d, 0x00000 }, + { 0x2f831, 0x0537f, 0x00000 }, + { 0x2f832, 0x0537f, 0x00000 }, + { 0x2f833, 0x0537f, 0x00000 }, + { 0x2f834, 0x20a2c, 0x00000 }, + { 0x2f835, 0x07070, 0x00000 }, + { 0x2f836, 0x053ca, 0x00000 }, + { 0x2f837, 0x053df, 0x00000 }, + { 0x2f838, 0x20b63, 0x00000 }, + { 0x2f839, 0x053eb, 0x00000 }, + { 0x2f83a, 0x053f1, 0x00000 }, + { 0x2f83b, 0x05406, 0x00000 }, + { 0x2f83c, 0x0549e, 0x00000 }, + { 0x2f83d, 0x05438, 0x00000 }, + { 0x2f83e, 0x05448, 0x00000 }, + { 0x2f83f, 0x05468, 0x00000 }, + { 0x2f840, 0x054a2, 0x00000 }, + { 0x2f841, 0x054f6, 0x00000 }, + { 0x2f842, 0x05510, 0x00000 }, + { 0x2f843, 0x05553, 0x00000 }, + { 0x2f844, 0x05563, 0x00000 }, + { 0x2f845, 0x05584, 0x00000 }, + { 0x2f846, 0x05584, 0x00000 }, + { 0x2f847, 0x05599, 0x00000 }, + { 0x2f848, 0x055ab, 0x00000 }, + { 0x2f849, 0x055b3, 0x00000 }, + { 0x2f84a, 0x055c2, 0x00000 }, + { 0x2f84b, 0x05716, 0x00000 }, + { 0x2f84c, 0x05606, 0x00000 }, + { 0x2f84d, 0x05717, 0x00000 }, + { 0x2f84e, 0x05651, 0x00000 }, + { 0x2f84f, 0x05674, 0x00000 }, + { 0x2f850, 0x05207, 0x00000 }, + { 0x2f851, 0x058ee, 0x00000 }, + { 0x2f852, 0x057ce, 0x00000 }, + { 0x2f853, 0x057f4, 0x00000 }, + { 0x2f854, 0x0580d, 0x00000 }, + { 0x2f855, 0x0578b, 0x00000 }, + { 0x2f856, 0x05832, 0x00000 }, + { 0x2f857, 0x05831, 0x00000 }, + { 0x2f858, 0x058ac, 0x00000 }, + { 0x2f859, 0x214e4, 0x00000 }, + { 0x2f85a, 0x058f2, 0x00000 }, + { 0x2f85b, 0x058f7, 0x00000 }, + { 0x2f85c, 0x05906, 0x00000 }, + { 0x2f85d, 0x0591a, 0x00000 }, + { 0x2f85e, 0x05922, 0x00000 }, + { 0x2f85f, 0x05962, 0x00000 }, + { 0x2f860, 0x216a8, 0x00000 }, + { 0x2f861, 0x216ea, 0x00000 }, + { 0x2f862, 0x059ec, 0x00000 }, + { 0x2f863, 0x05a1b, 0x00000 }, + { 0x2f864, 0x05a27, 0x00000 }, + { 0x2f865, 0x059d8, 0x00000 }, + { 0x2f866, 0x05a66, 0x00000 }, + { 0x2f867, 0x036ee, 0x00000 }, + { 0x2f868, 0x036fc, 0x00000 }, + { 0x2f869, 0x05b08, 0x00000 }, + { 0x2f86a, 0x05b3e, 0x00000 }, + { 0x2f86b, 0x05b3e, 0x00000 }, + { 0x2f86c, 0x219c8, 0x00000 }, + { 0x2f86d, 0x05bc3, 0x00000 }, + { 0x2f86e, 0x05bd8, 0x00000 }, + { 0x2f86f, 0x05be7, 0x00000 }, + { 0x2f870, 0x05bf3, 0x00000 }, + { 0x2f871, 0x21b18, 0x00000 }, + { 0x2f872, 0x05bff, 0x00000 }, + { 0x2f873, 0x05c06, 0x00000 }, + { 0x2f874, 0x05f53, 0x00000 }, + { 0x2f875, 0x05c22, 0x00000 }, + { 0x2f876, 0x03781, 0x00000 }, + { 0x2f877, 0x05c60, 0x00000 }, + { 0x2f878, 0x05c6e, 0x00000 }, + { 0x2f879, 0x05cc0, 0x00000 }, + { 0x2f87a, 0x05c8d, 0x00000 }, + { 0x2f87b, 0x21de4, 0x00000 }, + { 0x2f87c, 0x05d43, 0x00000 }, + { 0x2f87d, 0x21de6, 0x00000 }, + { 0x2f87e, 0x05d6e, 0x00000 }, + { 0x2f87f, 0x05d6b, 0x00000 }, + { 0x2f880, 0x05d7c, 0x00000 }, + { 0x2f881, 0x05de1, 0x00000 }, + { 0x2f882, 0x05de2, 0x00000 }, + { 0x2f883, 0x0382f, 0x00000 }, + { 0x2f884, 0x05dfd, 0x00000 }, + { 0x2f885, 0x05e28, 0x00000 }, + { 0x2f886, 0x05e3d, 0x00000 }, + { 0x2f887, 0x05e69, 0x00000 }, + { 0x2f888, 0x03862, 0x00000 }, + { 0x2f889, 0x22183, 0x00000 }, + { 0x2f88a, 0x0387c, 0x00000 }, + { 0x2f88b, 0x05eb0, 0x00000 }, + { 0x2f88c, 0x05eb3, 0x00000 }, + { 0x2f88d, 0x05eb6, 0x00000 }, + { 0x2f88e, 0x05eca, 0x00000 }, + { 0x2f88f, 0x2a392, 0x00000 }, + { 0x2f890, 0x05efe, 0x00000 }, + { 0x2f891, 0x22331, 0x00000 }, + { 0x2f892, 0x22331, 0x00000 }, + { 0x2f893, 0x08201, 0x00000 }, + { 0x2f894, 0x05f22, 0x00000 }, + { 0x2f895, 0x05f22, 0x00000 }, + { 0x2f896, 0x038c7, 0x00000 }, + { 0x2f897, 0x232b8, 0x00000 }, + { 0x2f898, 0x261da, 0x00000 }, + { 0x2f899, 0x05f62, 0x00000 }, + { 0x2f89a, 0x05f6b, 0x00000 }, + { 0x2f89b, 0x038e3, 0x00000 }, + { 0x2f89c, 0x05f9a, 0x00000 }, + { 0x2f89d, 0x05fcd, 0x00000 }, + { 0x2f89e, 0x05fd7, 0x00000 }, + { 0x2f89f, 0x05ff9, 0x00000 }, + { 0x2f8a0, 0x06081, 0x00000 }, + { 0x2f8a1, 0x0393a, 0x00000 }, + { 0x2f8a2, 0x0391c, 0x00000 }, + { 0x2f8a3, 0x06094, 0x00000 }, + { 0x2f8a4, 0x226d4, 0x00000 }, + { 0x2f8a5, 0x060c7, 0x00000 }, + { 0x2f8a6, 0x06148, 0x00000 }, + { 0x2f8a7, 0x0614c, 0x00000 }, + { 0x2f8a8, 0x0614e, 0x00000 }, + { 0x2f8a9, 0x0614c, 0x00000 }, + { 0x2f8aa, 0x0617a, 0x00000 }, + { 0x2f8ab, 0x0618e, 0x00000 }, + { 0x2f8ac, 0x061b2, 0x00000 }, + { 0x2f8ad, 0x061a4, 0x00000 }, + { 0x2f8ae, 0x061af, 0x00000 }, + { 0x2f8af, 0x061de, 0x00000 }, + { 0x2f8b0, 0x061f2, 0x00000 }, + { 0x2f8b1, 0x061f6, 0x00000 }, + { 0x2f8b2, 0x06210, 0x00000 }, + { 0x2f8b3, 0x0621b, 0x00000 }, + { 0x2f8b4, 0x0625d, 0x00000 }, + { 0x2f8b5, 0x062b1, 0x00000 }, + { 0x2f8b6, 0x062d4, 0x00000 }, + { 0x2f8b7, 0x06350, 0x00000 }, + { 0x2f8b8, 0x22b0c, 0x00000 }, + { 0x2f8b9, 0x0633d, 0x00000 }, + { 0x2f8ba, 0x062fc, 0x00000 }, + { 0x2f8bb, 0x06368, 0x00000 }, + { 0x2f8bc, 0x06383, 0x00000 }, + { 0x2f8bd, 0x063e4, 0x00000 }, + { 0x2f8be, 0x22bf1, 0x00000 }, + { 0x2f8bf, 0x06422, 0x00000 }, + { 0x2f8c0, 0x063c5, 0x00000 }, + { 0x2f8c1, 0x063a9, 0x00000 }, + { 0x2f8c2, 0x03a2e, 0x00000 }, + { 0x2f8c3, 0x06469, 0x00000 }, + { 0x2f8c4, 0x0647e, 0x00000 }, + { 0x2f8c5, 0x0649d, 0x00000 }, + { 0x2f8c6, 0x06477, 0x00000 }, + { 0x2f8c7, 0x03a6c, 0x00000 }, + { 0x2f8c8, 0x0654f, 0x00000 }, + { 0x2f8c9, 0x0656c, 0x00000 }, + { 0x2f8ca, 0x2300a, 0x00000 }, + { 0x2f8cb, 0x065e3, 0x00000 }, + { 0x2f8cc, 0x066f8, 0x00000 }, + { 0x2f8cd, 0x06649, 0x00000 }, + { 0x2f8ce, 0x03b19, 0x00000 }, + { 0x2f8cf, 0x06691, 0x00000 }, + { 0x2f8d0, 0x03b08, 0x00000 }, + { 0x2f8d1, 0x03ae4, 0x00000 }, + { 0x2f8d2, 0x05192, 0x00000 }, + { 0x2f8d3, 0x05195, 0x00000 }, + { 0x2f8d4, 0x06700, 0x00000 }, + { 0x2f8d5, 0x0669c, 0x00000 }, + { 0x2f8d6, 0x080ad, 0x00000 }, + { 0x2f8d7, 0x043d9, 0x00000 }, + { 0x2f8d8, 0x06717, 0x00000 }, + { 0x2f8d9, 0x0671b, 0x00000 }, + { 0x2f8da, 0x06721, 0x00000 }, + { 0x2f8db, 0x0675e, 0x00000 }, + { 0x2f8dc, 0x06753, 0x00000 }, + { 0x2f8dd, 0x233c3, 0x00000 }, + { 0x2f8de, 0x03b49, 0x00000 }, + { 0x2f8df, 0x067fa, 0x00000 }, + { 0x2f8e0, 0x06785, 0x00000 }, + { 0x2f8e1, 0x06852, 0x00000 }, + { 0x2f8e2, 0x06885, 0x00000 }, + { 0x2f8e3, 0x2346d, 0x00000 }, + { 0x2f8e4, 0x0688e, 0x00000 }, + { 0x2f8e5, 0x0681f, 0x00000 }, + { 0x2f8e6, 0x06914, 0x00000 }, + { 0x2f8e7, 0x03b9d, 0x00000 }, + { 0x2f8e8, 0x06942, 0x00000 }, + { 0x2f8e9, 0x069a3, 0x00000 }, + { 0x2f8ea, 0x069ea, 0x00000 }, + { 0x2f8eb, 0x06aa8, 0x00000 }, + { 0x2f8ec, 0x236a3, 0x00000 }, + { 0x2f8ed, 0x06adb, 0x00000 }, + { 0x2f8ee, 0x03c18, 0x00000 }, + { 0x2f8ef, 0x06b21, 0x00000 }, + { 0x2f8f0, 0x238a7, 0x00000 }, + { 0x2f8f1, 0x06b54, 0x00000 }, + { 0x2f8f2, 0x03c4e, 0x00000 }, + { 0x2f8f3, 0x06b72, 0x00000 }, + { 0x2f8f4, 0x06b9f, 0x00000 }, + { 0x2f8f5, 0x06bba, 0x00000 }, + { 0x2f8f6, 0x06bbb, 0x00000 }, + { 0x2f8f7, 0x23a8d, 0x00000 }, + { 0x2f8f8, 0x21d0b, 0x00000 }, + { 0x2f8f9, 0x23afa, 0x00000 }, + { 0x2f8fa, 0x06c4e, 0x00000 }, + { 0x2f8fb, 0x23cbc, 0x00000 }, + { 0x2f8fc, 0x06cbf, 0x00000 }, + { 0x2f8fd, 0x06ccd, 0x00000 }, + { 0x2f8fe, 0x06c67, 0x00000 }, + { 0x2f8ff, 0x06d16, 0x00000 }, + { 0x2f900, 0x06d3e, 0x00000 }, + { 0x2f901, 0x06d77, 0x00000 }, + { 0x2f902, 0x06d41, 0x00000 }, + { 0x2f903, 0x06d69, 0x00000 }, + { 0x2f904, 0x06d78, 0x00000 }, + { 0x2f905, 0x06d85, 0x00000 }, + { 0x2f906, 0x23d1e, 0x00000 }, + { 0x2f907, 0x06d34, 0x00000 }, + { 0x2f908, 0x06e2f, 0x00000 }, + { 0x2f909, 0x06e6e, 0x00000 }, + { 0x2f90a, 0x03d33, 0x00000 }, + { 0x2f90b, 0x06ecb, 0x00000 }, + { 0x2f90c, 0x06ec7, 0x00000 }, + { 0x2f90d, 0x23ed1, 0x00000 }, + { 0x2f90e, 0x06df9, 0x00000 }, + { 0x2f90f, 0x06f6e, 0x00000 }, + { 0x2f910, 0x23f5e, 0x00000 }, + { 0x2f911, 0x23f8e, 0x00000 }, + { 0x2f912, 0x06fc6, 0x00000 }, + { 0x2f913, 0x07039, 0x00000 }, + { 0x2f914, 0x0701e, 0x00000 }, + { 0x2f915, 0x0701b, 0x00000 }, + { 0x2f916, 0x03d96, 0x00000 }, + { 0x2f917, 0x0704a, 0x00000 }, + { 0x2f918, 0x0707d, 0x00000 }, + { 0x2f919, 0x07077, 0x00000 }, + { 0x2f91a, 0x070ad, 0x00000 }, + { 0x2f91b, 0x20525, 0x00000 }, + { 0x2f91c, 0x07145, 0x00000 }, + { 0x2f91d, 0x24263, 0x00000 }, + { 0x2f91e, 0x0719c, 0x00000 }, + { 0x2f91f, 0x243ab, 0x00000 }, + { 0x2f920, 0x07228, 0x00000 }, + { 0x2f921, 0x07235, 0x00000 }, + { 0x2f922, 0x07250, 0x00000 }, + { 0x2f923, 0x24608, 0x00000 }, + { 0x2f924, 0x07280, 0x00000 }, + { 0x2f925, 0x07295, 0x00000 }, + { 0x2f926, 0x24735, 0x00000 }, + { 0x2f927, 0x24814, 0x00000 }, + { 0x2f928, 0x0737a, 0x00000 }, + { 0x2f929, 0x0738b, 0x00000 }, + { 0x2f92a, 0x03eac, 0x00000 }, + { 0x2f92b, 0x073a5, 0x00000 }, + { 0x2f92c, 0x03eb8, 0x00000 }, + { 0x2f92d, 0x03eb8, 0x00000 }, + { 0x2f92e, 0x07447, 0x00000 }, + { 0x2f92f, 0x0745c, 0x00000 }, + { 0x2f930, 0x07471, 0x00000 }, + { 0x2f931, 0x07485, 0x00000 }, + { 0x2f932, 0x074ca, 0x00000 }, + { 0x2f933, 0x03f1b, 0x00000 }, + { 0x2f934, 0x07524, 0x00000 }, + { 0x2f935, 0x24c36, 0x00000 }, + { 0x2f936, 0x0753e, 0x00000 }, + { 0x2f937, 0x24c92, 0x00000 }, + { 0x2f938, 0x07570, 0x00000 }, + { 0x2f939, 0x2219f, 0x00000 }, + { 0x2f93a, 0x07610, 0x00000 }, + { 0x2f93b, 0x24fa1, 0x00000 }, + { 0x2f93c, 0x24fb8, 0x00000 }, + { 0x2f93d, 0x25044, 0x00000 }, + { 0x2f93e, 0x03ffc, 0x00000 }, + { 0x2f93f, 0x04008, 0x00000 }, + { 0x2f940, 0x076f4, 0x00000 }, + { 0x2f941, 0x250f3, 0x00000 }, + { 0x2f942, 0x250f2, 0x00000 }, + { 0x2f943, 0x25119, 0x00000 }, + { 0x2f944, 0x25133, 0x00000 }, + { 0x2f945, 0x0771e, 0x00000 }, + { 0x2f946, 0x0771f, 0x00000 }, + { 0x2f947, 0x0771f, 0x00000 }, + { 0x2f948, 0x0774a, 0x00000 }, + { 0x2f949, 0x04039, 0x00000 }, + { 0x2f94a, 0x0778b, 0x00000 }, + { 0x2f94b, 0x04046, 0x00000 }, + { 0x2f94c, 0x04096, 0x00000 }, + { 0x2f94d, 0x2541d, 0x00000 }, + { 0x2f94e, 0x0784e, 0x00000 }, + { 0x2f94f, 0x0788c, 0x00000 }, + { 0x2f950, 0x078cc, 0x00000 }, + { 0x2f951, 0x040e3, 0x00000 }, + { 0x2f952, 0x25626, 0x00000 }, + { 0x2f953, 0x07956, 0x00000 }, + { 0x2f954, 0x2569a, 0x00000 }, + { 0x2f955, 0x256c5, 0x00000 }, + { 0x2f956, 0x0798f, 0x00000 }, + { 0x2f957, 0x079eb, 0x00000 }, + { 0x2f958, 0x0412f, 0x00000 }, + { 0x2f959, 0x07a40, 0x00000 }, + { 0x2f95a, 0x07a4a, 0x00000 }, + { 0x2f95b, 0x07a4f, 0x00000 }, + { 0x2f95c, 0x2597c, 0x00000 }, + { 0x2f95d, 0x25aa7, 0x00000 }, + { 0x2f95e, 0x25aa7, 0x00000 }, + { 0x2f95f, 0x07aee, 0x00000 }, + { 0x2f960, 0x04202, 0x00000 }, + { 0x2f961, 0x25bab, 0x00000 }, + { 0x2f962, 0x07bc6, 0x00000 }, + { 0x2f963, 0x07bc9, 0x00000 }, + { 0x2f964, 0x04227, 0x00000 }, + { 0x2f965, 0x25c80, 0x00000 }, + { 0x2f966, 0x07cd2, 0x00000 }, + { 0x2f967, 0x042a0, 0x00000 }, + { 0x2f968, 0x07ce8, 0x00000 }, + { 0x2f969, 0x07ce3, 0x00000 }, + { 0x2f96a, 0x07d00, 0x00000 }, + { 0x2f96b, 0x25f86, 0x00000 }, + { 0x2f96c, 0x07d63, 0x00000 }, + { 0x2f96d, 0x04301, 0x00000 }, + { 0x2f96e, 0x07dc7, 0x00000 }, + { 0x2f96f, 0x07e02, 0x00000 }, + { 0x2f970, 0x07e45, 0x00000 }, + { 0x2f971, 0x04334, 0x00000 }, + { 0x2f972, 0x26228, 0x00000 }, + { 0x2f973, 0x26247, 0x00000 }, + { 0x2f974, 0x04359, 0x00000 }, + { 0x2f975, 0x262d9, 0x00000 }, + { 0x2f976, 0x07f7a, 0x00000 }, + { 0x2f977, 0x2633e, 0x00000 }, + { 0x2f978, 0x07f95, 0x00000 }, + { 0x2f979, 0x07ffa, 0x00000 }, + { 0x2f97a, 0x08005, 0x00000 }, + { 0x2f97b, 0x264da, 0x00000 }, + { 0x2f97c, 0x26523, 0x00000 }, + { 0x2f97d, 0x08060, 0x00000 }, + { 0x2f97e, 0x265a8, 0x00000 }, + { 0x2f97f, 0x08070, 0x00000 }, + { 0x2f980, 0x2335f, 0x00000 }, + { 0x2f981, 0x043d5, 0x00000 }, + { 0x2f982, 0x080b2, 0x00000 }, + { 0x2f983, 0x08103, 0x00000 }, + { 0x2f984, 0x0440b, 0x00000 }, + { 0x2f985, 0x0813e, 0x00000 }, + { 0x2f986, 0x05ab5, 0x00000 }, + { 0x2f987, 0x267a7, 0x00000 }, + { 0x2f988, 0x267b5, 0x00000 }, + { 0x2f989, 0x23393, 0x00000 }, + { 0x2f98a, 0x2339c, 0x00000 }, + { 0x2f98b, 0x08201, 0x00000 }, + { 0x2f98c, 0x08204, 0x00000 }, + { 0x2f98d, 0x08f9e, 0x00000 }, + { 0x2f98e, 0x0446b, 0x00000 }, + { 0x2f98f, 0x08291, 0x00000 }, + { 0x2f990, 0x0828b, 0x00000 }, + { 0x2f991, 0x0829d, 0x00000 }, + { 0x2f992, 0x052b3, 0x00000 }, + { 0x2f993, 0x082b1, 0x00000 }, + { 0x2f994, 0x082b3, 0x00000 }, + { 0x2f995, 0x082bd, 0x00000 }, + { 0x2f996, 0x082e6, 0x00000 }, + { 0x2f997, 0x26b3c, 0x00000 }, + { 0x2f998, 0x082e5, 0x00000 }, + { 0x2f999, 0x0831d, 0x00000 }, + { 0x2f99a, 0x08363, 0x00000 }, + { 0x2f99b, 0x083ad, 0x00000 }, + { 0x2f99c, 0x08323, 0x00000 }, + { 0x2f99d, 0x083bd, 0x00000 }, + { 0x2f99e, 0x083e7, 0x00000 }, + { 0x2f99f, 0x08457, 0x00000 }, + { 0x2f9a0, 0x08353, 0x00000 }, + { 0x2f9a1, 0x083ca, 0x00000 }, + { 0x2f9a2, 0x083cc, 0x00000 }, + { 0x2f9a3, 0x083dc, 0x00000 }, + { 0x2f9a4, 0x26c36, 0x00000 }, + { 0x2f9a5, 0x26d6b, 0x00000 }, + { 0x2f9a6, 0x26cd5, 0x00000 }, + { 0x2f9a7, 0x0452b, 0x00000 }, + { 0x2f9a8, 0x084f1, 0x00000 }, + { 0x2f9a9, 0x084f3, 0x00000 }, + { 0x2f9aa, 0x08516, 0x00000 }, + { 0x2f9ab, 0x273ca, 0x00000 }, + { 0x2f9ac, 0x08564, 0x00000 }, + { 0x2f9ad, 0x26f2c, 0x00000 }, + { 0x2f9ae, 0x0455d, 0x00000 }, + { 0x2f9af, 0x04561, 0x00000 }, + { 0x2f9b0, 0x26fb1, 0x00000 }, + { 0x2f9b1, 0x270d2, 0x00000 }, + { 0x2f9b2, 0x0456b, 0x00000 }, + { 0x2f9b3, 0x08650, 0x00000 }, + { 0x2f9b4, 0x0865c, 0x00000 }, + { 0x2f9b5, 0x08667, 0x00000 }, + { 0x2f9b6, 0x08669, 0x00000 }, + { 0x2f9b7, 0x086a9, 0x00000 }, + { 0x2f9b8, 0x08688, 0x00000 }, + { 0x2f9b9, 0x0870e, 0x00000 }, + { 0x2f9ba, 0x086e2, 0x00000 }, + { 0x2f9bb, 0x08779, 0x00000 }, + { 0x2f9bc, 0x08728, 0x00000 }, + { 0x2f9bd, 0x0876b, 0x00000 }, + { 0x2f9be, 0x08786, 0x00000 }, + { 0x2f9bf, 0x045d7, 0x00000 }, + { 0x2f9c0, 0x087e1, 0x00000 }, + { 0x2f9c1, 0x08801, 0x00000 }, + { 0x2f9c2, 0x045f9, 0x00000 }, + { 0x2f9c3, 0x08860, 0x00000 }, + { 0x2f9c4, 0x08863, 0x00000 }, + { 0x2f9c5, 0x27667, 0x00000 }, + { 0x2f9c6, 0x088d7, 0x00000 }, + { 0x2f9c7, 0x088de, 0x00000 }, + { 0x2f9c8, 0x04635, 0x00000 }, + { 0x2f9c9, 0x088fa, 0x00000 }, + { 0x2f9ca, 0x034bb, 0x00000 }, + { 0x2f9cb, 0x278ae, 0x00000 }, + { 0x2f9cc, 0x27966, 0x00000 }, + { 0x2f9cd, 0x046be, 0x00000 }, + { 0x2f9ce, 0x046c7, 0x00000 }, + { 0x2f9cf, 0x08aa0, 0x00000 }, + { 0x2f9d0, 0x08aed, 0x00000 }, + { 0x2f9d1, 0x08b8a, 0x00000 }, + { 0x2f9d2, 0x08c55, 0x00000 }, + { 0x2f9d3, 0x27ca8, 0x00000 }, + { 0x2f9d4, 0x08cab, 0x00000 }, + { 0x2f9d5, 0x08cc1, 0x00000 }, + { 0x2f9d6, 0x08d1b, 0x00000 }, + { 0x2f9d7, 0x08d77, 0x00000 }, + { 0x2f9d8, 0x27f2f, 0x00000 }, + { 0x2f9d9, 0x20804, 0x00000 }, + { 0x2f9da, 0x08dcb, 0x00000 }, + { 0x2f9db, 0x08dbc, 0x00000 }, + { 0x2f9dc, 0x08df0, 0x00000 }, + { 0x2f9dd, 0x208de, 0x00000 }, + { 0x2f9de, 0x08ed4, 0x00000 }, + { 0x2f9df, 0x08f38, 0x00000 }, + { 0x2f9e0, 0x285d2, 0x00000 }, + { 0x2f9e1, 0x285ed, 0x00000 }, + { 0x2f9e2, 0x09094, 0x00000 }, + { 0x2f9e3, 0x090f1, 0x00000 }, + { 0x2f9e4, 0x09111, 0x00000 }, + { 0x2f9e5, 0x2872e, 0x00000 }, + { 0x2f9e6, 0x0911b, 0x00000 }, + { 0x2f9e7, 0x09238, 0x00000 }, + { 0x2f9e8, 0x092d7, 0x00000 }, + { 0x2f9e9, 0x092d8, 0x00000 }, + { 0x2f9ea, 0x0927c, 0x00000 }, + { 0x2f9eb, 0x093f9, 0x00000 }, + { 0x2f9ec, 0x09415, 0x00000 }, + { 0x2f9ed, 0x28bfa, 0x00000 }, + { 0x2f9ee, 0x0958b, 0x00000 }, + { 0x2f9ef, 0x04995, 0x00000 }, + { 0x2f9f0, 0x095b7, 0x00000 }, + { 0x2f9f1, 0x28d77, 0x00000 }, + { 0x2f9f2, 0x049e6, 0x00000 }, + { 0x2f9f3, 0x096c3, 0x00000 }, + { 0x2f9f4, 0x05db2, 0x00000 }, + { 0x2f9f5, 0x09723, 0x00000 }, + { 0x2f9f6, 0x29145, 0x00000 }, + { 0x2f9f7, 0x2921a, 0x00000 }, + { 0x2f9f8, 0x04a6e, 0x00000 }, + { 0x2f9f9, 0x04a76, 0x00000 }, + { 0x2f9fa, 0x097e0, 0x00000 }, + { 0x2f9fb, 0x2940a, 0x00000 }, + { 0x2f9fc, 0x04ab2, 0x00000 }, + { 0x2f9fd, 0x29496, 0x00000 }, + { 0x2f9fe, 0x0980b, 0x00000 }, + { 0x2f9ff, 0x0980b, 0x00000 }, + { 0x2fa00, 0x09829, 0x00000 }, + { 0x2fa01, 0x295b6, 0x00000 }, + { 0x2fa02, 0x098e2, 0x00000 }, + { 0x2fa03, 0x04b33, 0x00000 }, + { 0x2fa04, 0x09929, 0x00000 }, + { 0x2fa05, 0x099a7, 0x00000 }, + { 0x2fa06, 0x099c2, 0x00000 }, + { 0x2fa07, 0x099fe, 0x00000 }, + { 0x2fa08, 0x04bce, 0x00000 }, + { 0x2fa09, 0x29b30, 0x00000 }, + { 0x2fa0a, 0x09b12, 0x00000 }, + { 0x2fa0b, 0x09c40, 0x00000 }, + { 0x2fa0c, 0x09cfd, 0x00000 }, + { 0x2fa0d, 0x04cce, 0x00000 }, + { 0x2fa0e, 0x04ced, 0x00000 }, + { 0x2fa0f, 0x09d67, 0x00000 }, + { 0x2fa10, 0x2a0ce, 0x00000 }, + { 0x2fa11, 0x04cf8, 0x00000 }, + { 0x2fa12, 0x2a105, 0x00000 }, + { 0x2fa13, 0x2a20e, 0x00000 }, + { 0x2fa14, 0x2a291, 0x00000 }, + { 0x2fa15, 0x09ebb, 0x00000 }, + { 0x2fa16, 0x04d56, 0x00000 }, + { 0x2fa17, 0x09ef9, 0x00000 }, + { 0x2fa18, 0x09efe, 0x00000 }, + { 0x2fa19, 0x09f05, 0x00000 }, + { 0x2fa1a, 0x09f0f, 0x00000 }, + { 0x2fa1b, 0x09f16, 0x00000 }, + { 0x2fa1c, 0x09f3b, 0x00000 }, + { 0x2fa1d, 0x2a600, 0x00000 } +}; + +#endif /* DECOMP_H */ diff --git a/glib/glib/guniprop.c b/glib/glib/guniprop.c new file mode 100644 index 0000000..420d58a --- /dev/null +++ b/glib/glib/guniprop.c @@ -0,0 +1,1510 @@ +/* guniprop.c - Unicode character properties. + * + * Copyright (C) 1999 Tom Tromey + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#include +#include +#include + +#include "gmem.h" +#include "gstring.h" +#include "gtestutils.h" +#include "gtypes.h" +#include "gunicode.h" +#include "gunichartables.h" +#include "gmirroringtable.h" +#include "gscripttable.h" +#include "gunicodeprivate.h" +#ifdef G_OS_WIN32 +#include "gwin32.h" +#endif + +#define ATTR_TABLE(Page) (((Page) <= G_UNICODE_LAST_PAGE_PART1) \ + ? attr_table_part1[Page] \ + : attr_table_part2[(Page) - 0xe00]) + +#define ATTTABLE(Page, Char) \ + ((ATTR_TABLE(Page) == G_UNICODE_MAX_TABLE_INDEX) ? 0 : (attr_data[ATTR_TABLE(Page)][Char])) + +#define TTYPE_PART1(Page, Char) \ + ((type_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (type_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (type_data[type_table_part1[Page]][Char])) + +#define TTYPE_PART2(Page, Char) \ + ((type_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \ + ? (type_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \ + : (type_data[type_table_part2[Page]][Char])) + +#define TYPE(Char) \ + (((Char) <= G_UNICODE_LAST_CHAR_PART1) \ + ? TTYPE_PART1 ((Char) >> 8, (Char) & 0xff) \ + : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \ + ? TTYPE_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \ + : G_UNICODE_UNASSIGNED)) + + +#define IS(Type, Class) (((guint)1 << (Type)) & (Class)) +#define OR(Type, Rest) (((guint)1 << (Type)) | (Rest)) + + + +#define ISALPHA(Type) IS ((Type), \ + OR (G_UNICODE_LOWERCASE_LETTER, \ + OR (G_UNICODE_UPPERCASE_LETTER, \ + OR (G_UNICODE_TITLECASE_LETTER, \ + OR (G_UNICODE_MODIFIER_LETTER, \ + OR (G_UNICODE_OTHER_LETTER, 0)))))) + +#define ISALDIGIT(Type) IS ((Type), \ + OR (G_UNICODE_DECIMAL_NUMBER, \ + OR (G_UNICODE_LETTER_NUMBER, \ + OR (G_UNICODE_OTHER_NUMBER, \ + OR (G_UNICODE_LOWERCASE_LETTER, \ + OR (G_UNICODE_UPPERCASE_LETTER, \ + OR (G_UNICODE_TITLECASE_LETTER, \ + OR (G_UNICODE_MODIFIER_LETTER, \ + OR (G_UNICODE_OTHER_LETTER, 0))))))))) + +#define ISMARK(Type) IS ((Type), \ + OR (G_UNICODE_NON_SPACING_MARK, \ + OR (G_UNICODE_SPACING_MARK, \ + OR (G_UNICODE_ENCLOSING_MARK, 0)))) + +#define ISZEROWIDTHTYPE(Type) IS ((Type), \ + OR (G_UNICODE_NON_SPACING_MARK, \ + OR (G_UNICODE_ENCLOSING_MARK, \ + OR (G_UNICODE_FORMAT, 0)))) + +/** + * g_unichar_isalnum: + * @c: a Unicode character + * + * Determines whether a character is alphanumeric. + * Given some UTF-8 text, obtain a character value + * with g_utf8_get_char(). + * + * Return value: %TRUE if @c is an alphanumeric character + **/ +gboolean +g_unichar_isalnum (gunichar c) +{ + return ISALDIGIT (TYPE (c)) ? TRUE : FALSE; +} + +/** + * g_unichar_isalpha: + * @c: a Unicode character + * + * Determines whether a character is alphabetic (i.e. a letter). + * Given some UTF-8 text, obtain a character value with + * g_utf8_get_char(). + * + * Return value: %TRUE if @c is an alphabetic character + **/ +gboolean +g_unichar_isalpha (gunichar c) +{ + return ISALPHA (TYPE (c)) ? TRUE : FALSE; +} + + +/** + * g_unichar_iscntrl: + * @c: a Unicode character + * + * Determines whether a character is a control character. + * Given some UTF-8 text, obtain a character value with + * g_utf8_get_char(). + * + * Return value: %TRUE if @c is a control character + **/ +gboolean +g_unichar_iscntrl (gunichar c) +{ + return TYPE (c) == G_UNICODE_CONTROL; +} + +/** + * g_unichar_isdigit: + * @c: a Unicode character + * + * Determines whether a character is numeric (i.e. a digit). This + * covers ASCII 0-9 and also digits in other languages/scripts. Given + * some UTF-8 text, obtain a character value with g_utf8_get_char(). + * + * Return value: %TRUE if @c is a digit + **/ +gboolean +g_unichar_isdigit (gunichar c) +{ + return TYPE (c) == G_UNICODE_DECIMAL_NUMBER; +} + + +/** + * g_unichar_isgraph: + * @c: a Unicode character + * + * Determines whether a character is printable and not a space + * (returns %FALSE for control characters, format characters, and + * spaces). g_unichar_isprint() is similar, but returns %TRUE for + * spaces. Given some UTF-8 text, obtain a character value with + * g_utf8_get_char(). + * + * Return value: %TRUE if @c is printable unless it's a space + **/ +gboolean +g_unichar_isgraph (gunichar c) +{ + return !IS (TYPE(c), + OR (G_UNICODE_CONTROL, + OR (G_UNICODE_FORMAT, + OR (G_UNICODE_UNASSIGNED, + OR (G_UNICODE_SURROGATE, + OR (G_UNICODE_SPACE_SEPARATOR, + 0)))))); +} + +/** + * g_unichar_islower: + * @c: a Unicode character + * + * Determines whether a character is a lowercase letter. + * Given some UTF-8 text, obtain a character value with + * g_utf8_get_char(). + * + * Return value: %TRUE if @c is a lowercase letter + **/ +gboolean +g_unichar_islower (gunichar c) +{ + return TYPE (c) == G_UNICODE_LOWERCASE_LETTER; +} + + +/** + * g_unichar_isprint: + * @c: a Unicode character + * + * Determines whether a character is printable. + * Unlike g_unichar_isgraph(), returns %TRUE for spaces. + * Given some UTF-8 text, obtain a character value with + * g_utf8_get_char(). + * + * Return value: %TRUE if @c is printable + **/ +gboolean +g_unichar_isprint (gunichar c) +{ + return !IS (TYPE(c), + OR (G_UNICODE_CONTROL, + OR (G_UNICODE_FORMAT, + OR (G_UNICODE_UNASSIGNED, + OR (G_UNICODE_SURROGATE, + 0))))); +} + +/** + * g_unichar_ispunct: + * @c: a Unicode character + * + * Determines whether a character is punctuation or a symbol. + * Given some UTF-8 text, obtain a character value with + * g_utf8_get_char(). + * + * Return value: %TRUE if @c is a punctuation or symbol character + **/ +gboolean +g_unichar_ispunct (gunichar c) +{ + return IS (TYPE(c), + OR (G_UNICODE_CONNECT_PUNCTUATION, + OR (G_UNICODE_DASH_PUNCTUATION, + OR (G_UNICODE_CLOSE_PUNCTUATION, + OR (G_UNICODE_FINAL_PUNCTUATION, + OR (G_UNICODE_INITIAL_PUNCTUATION, + OR (G_UNICODE_OTHER_PUNCTUATION, + OR (G_UNICODE_OPEN_PUNCTUATION, + OR (G_UNICODE_CURRENCY_SYMBOL, + OR (G_UNICODE_MODIFIER_SYMBOL, + OR (G_UNICODE_MATH_SYMBOL, + OR (G_UNICODE_OTHER_SYMBOL, + 0)))))))))))) ? TRUE : FALSE; +} + +/** + * g_unichar_isspace: + * @c: a Unicode character + * + * Determines whether a character is a space, tab, or line separator + * (newline, carriage return, etc.). Given some UTF-8 text, obtain a + * character value with g_utf8_get_char(). + * + * (Note: don't use this to do word breaking; you have to use + * Pango or equivalent to get word breaking right, the algorithm + * is fairly complex.) + * + * Return value: %TRUE if @c is a space character + **/ +gboolean +g_unichar_isspace (gunichar c) +{ + switch (c) + { + /* special-case these since Unicode thinks they are not spaces */ + case '\t': + case '\n': + case '\r': + case '\f': + return TRUE; + break; + + default: + { + return IS (TYPE(c), + OR (G_UNICODE_SPACE_SEPARATOR, + OR (G_UNICODE_LINE_SEPARATOR, + OR (G_UNICODE_PARAGRAPH_SEPARATOR, + 0)))) ? TRUE : FALSE; + } + break; + } +} + +/** + * g_unichar_ismark: + * @c: a Unicode character + * + * Determines whether a character is a mark (non-spacing mark, + * combining mark, or enclosing mark in Unicode speak). + * Given some UTF-8 text, obtain a character value + * with g_utf8_get_char(). + * + * Note: in most cases where isalpha characters are allowed, + * ismark characters should be allowed to as they are essential + * for writing most European languages as well as many non-Latin + * scripts. + * + * Return value: %TRUE if @c is a mark character + * + * Since: 2.14 + **/ +gboolean +g_unichar_ismark (gunichar c) +{ + return ISMARK (TYPE (c)); +} + +/** + * g_unichar_isupper: + * @c: a Unicode character + * + * Determines if a character is uppercase. + * + * Return value: %TRUE if @c is an uppercase character + **/ +gboolean +g_unichar_isupper (gunichar c) +{ + return TYPE (c) == G_UNICODE_UPPERCASE_LETTER; +} + +/** + * g_unichar_istitle: + * @c: a Unicode character + * + * Determines if a character is titlecase. Some characters in + * Unicode which are composites, such as the DZ digraph + * have three case variants instead of just two. The titlecase + * form is used at the beginning of a word where only the + * first letter is capitalized. The titlecase form of the DZ + * digraph is U+01F2 LATIN CAPITAL LETTTER D WITH SMALL LETTER Z. + * + * Return value: %TRUE if the character is titlecase + **/ +gboolean +g_unichar_istitle (gunichar c) +{ + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + if (title_table[i][0] == c) + return TRUE; + return FALSE; +} + +/** + * g_unichar_isxdigit: + * @c: a Unicode character. + * + * Determines if a character is a hexidecimal digit. + * + * Return value: %TRUE if the character is a hexadecimal digit + **/ +gboolean +g_unichar_isxdigit (gunichar c) +{ + return ((c >= 'a' && c <= 'f') + || (c >= 'A' && c <= 'F') + || (TYPE (c) == G_UNICODE_DECIMAL_NUMBER)); +} + +/** + * g_unichar_isdefined: + * @c: a Unicode character + * + * Determines if a given character is assigned in the Unicode + * standard. + * + * Return value: %TRUE if the character has an assigned value + **/ +gboolean +g_unichar_isdefined (gunichar c) +{ + return !IS (TYPE(c), + OR (G_UNICODE_UNASSIGNED, + OR (G_UNICODE_SURROGATE, + 0))); +} + +/** + * g_unichar_iszerowidth: + * @c: a Unicode character + * + * Determines if a given character typically takes zero width when rendered. + * The return value is %TRUE for all non-spacing and enclosing marks + * (e.g., combining accents), format characters, zero-width + * space, but not U+00AD SOFT HYPHEN. + * + * A typical use of this function is with one of g_unichar_iswide() or + * g_unichar_iswide_cjk() to determine the number of cells a string occupies + * when displayed on a grid display (terminals). However, note that not all + * terminals support zero-width rendering of zero-width marks. + * + * Return value: %TRUE if the character has zero width + * + * Since: 2.14 + **/ +gboolean +g_unichar_iszerowidth (gunichar c) +{ + if (G_UNLIKELY (c == 0x00AD)) + return FALSE; + + if (G_UNLIKELY (ISZEROWIDTHTYPE (TYPE (c)))) + return TRUE; + + if (G_UNLIKELY ((c >= 0x1160 && c < 0x1200) || + c == 0x200B)) + return TRUE; + + return FALSE; +} + +struct Interval +{ + gunichar start, end; +}; + +static int +interval_compare (const void *key, const void *elt) +{ + gunichar c = GPOINTER_TO_UINT (key); + struct Interval *interval = (struct Interval *)elt; + + if (c < interval->start) + return -1; + if (c > interval->end) + return +1; + + return 0; +} + + +/* + * NOTE: + * + * The tables for g_unichar_iswide() and g_unichar_iswide_cjk() are + * generated from the Unicode Character Database's file + * extracted/DerivedEastAsianWidth.txt using the gen-iswide-table.py + * in this way: + * + * ./gen-iswide-table.py < path/to/ucd/extracted/DerivedEastAsianWidth.txt | fmt + * + * Last update for Unicode 6.0. + */ + +/** + * g_unichar_iswide: + * @c: a Unicode character + * + * Determines if a character is typically rendered in a double-width + * cell. + * + * Return value: %TRUE if the character is wide + **/ +gboolean +g_unichar_iswide (gunichar c) +{ + /* See NOTE earlier for how to update this table. */ + static const struct Interval wide[] = { + {0x1100, 0x115F}, {0x11A3, 0x11A7}, {0x11FA, 0x11FF}, {0x2329, 0x232A}, + {0x2E80, 0x2E99}, {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, + {0x3000, 0x303E}, {0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312D}, + {0x3131, 0x318E}, {0x3190, 0x31BA}, {0x31C0, 0x31E3}, {0x31F0, 0x321E}, + {0x3220, 0x3247}, {0x3250, 0x32FE}, {0x3300, 0x4DBF}, {0x4E00, 0xA48C}, + {0xA490, 0xA4C6}, {0xA960, 0xA97C}, {0xAC00, 0xD7A3}, {0xD7B0, 0xD7C6}, + {0xD7CB, 0xD7FB}, {0xF900, 0xFAFF}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, + {0xFE54, 0xFE66}, {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, + {0x1B000, 0x1B001}, {0x1F200, 0x1F202}, {0x1F210, 0x1F23A}, {0x1F240, + 0x1F248}, {0x1F250, 0x1F251}, {0x20000, 0x2FFFD}, {0x30000, 0x3FFFD} + }; + + if (bsearch (GUINT_TO_POINTER (c), wide, G_N_ELEMENTS (wide), sizeof wide[0], + interval_compare)) + return TRUE; + + return FALSE; +} + + +/** + * g_unichar_iswide_cjk: + * @c: a Unicode character + * + * Determines if a character is typically rendered in a double-width + * cell under legacy East Asian locales. If a character is wide according to + * g_unichar_iswide(), then it is also reported wide with this function, but + * the converse is not necessarily true. See the + * Unicode Standard + * Annex #11 for details. + * + * If a character passes the g_unichar_iswide() test then it will also pass + * this test, but not the other way around. Note that some characters may + * pas both this test and g_unichar_iszerowidth(). + * + * Return value: %TRUE if the character is wide in legacy East Asian locales + * + * Since: 2.12 + */ +gboolean +g_unichar_iswide_cjk (gunichar c) +{ + /* See NOTE earlier for how to update this table. */ + static const struct Interval ambiguous[] = { + {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, {0x00AA, 0x00AA}, + {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, {0x00B6, 0x00BA}, {0x00BC, 0x00BF}, + {0x00C6, 0x00C6}, {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1}, + {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, {0x00F0, 0x00F0}, + {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, {0x00FC, 0x00FC}, {0x00FE, 0x00FE}, + {0x0101, 0x0101}, {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B}, + {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, {0x0138, 0x0138}, + {0x013F, 0x0142}, {0x0144, 0x0144}, {0x0148, 0x014B}, {0x014D, 0x014D}, + {0x0152, 0x0153}, {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE}, + {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, {0x01D6, 0x01D6}, + {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, {0x01DC, 0x01DC}, {0x0251, 0x0251}, + {0x0261, 0x0261}, {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB}, + {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, {0x02DD, 0x02DD}, + {0x02DF, 0x02DF}, {0x0300, 0x036F}, {0x0391, 0x03A1}, {0x03A3, 0x03A9}, + {0x03B1, 0x03C1}, {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F}, + {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019}, + {0x201C, 0x201D}, {0x2020, 0x2022}, {0x2024, 0x2027}, {0x2030, 0x2030}, + {0x2032, 0x2033}, {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E}, + {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC}, + {0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109}, {0x2113, 0x2113}, + {0x2116, 0x2116}, {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B}, + {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, {0x2170, 0x2179}, + {0x2189, 0x2189}, {0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, + {0x21D4, 0x21D4}, {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, + {0x2207, 0x2208}, {0x220B, 0x220B}, {0x220F, 0x220F}, {0x2211, 0x2211}, + {0x2215, 0x2215}, {0x221A, 0x221A}, {0x221D, 0x2220}, {0x2223, 0x2223}, + {0x2225, 0x2225}, {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, + {0x223C, 0x223D}, {0x2248, 0x2248}, {0x224C, 0x224C}, {0x2252, 0x2252}, + {0x2260, 0x2261}, {0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F}, + {0x2282, 0x2283}, {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, + {0x22A5, 0x22A5}, {0x22BF, 0x22BF}, {0x2312, 0x2312}, {0x2460, 0x24E9}, + {0x24EB, 0x254B}, {0x2550, 0x2573}, {0x2580, 0x258F}, {0x2592, 0x2595}, + {0x25A0, 0x25A1}, {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, + {0x25BC, 0x25BD}, {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, {0x25CB, 0x25CB}, + {0x25CE, 0x25D1}, {0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606}, + {0x2609, 0x2609}, {0x260E, 0x260F}, {0x2614, 0x2615}, {0x261C, 0x261C}, + {0x261E, 0x261E}, {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, + {0x2663, 0x2665}, {0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F}, + {0x269E, 0x269F}, {0x26BE, 0x26BF}, {0x26C4, 0x26CD}, {0x26CF, 0x26E1}, + {0x26E3, 0x26E3}, {0x26E8, 0x26FF}, {0x273D, 0x273D}, {0x2757, 0x2757}, + {0x2776, 0x277F}, {0x2B55, 0x2B59}, {0x3248, 0x324F}, {0xE000, 0xF8FF}, + {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD}, {0x1F100, 0x1F10A}, {0x1F110, + 0x1F12D}, {0x1F130, 0x1F169}, {0x1F170, 0x1F19A}, {0xE0100, 0xE01EF}, + {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD} + }; + + if (g_unichar_iswide (c)) + return TRUE; + + if (bsearch (GUINT_TO_POINTER (c), ambiguous, G_N_ELEMENTS (ambiguous), sizeof ambiguous[0], + interval_compare)) + return TRUE; + + return FALSE; +} + + +/** + * g_unichar_toupper: + * @c: a Unicode character + * + * Converts a character to uppercase. + * + * Return value: the result of converting @c to uppercase. + * If @c is not an lowercase or titlecase character, + * or has no upper case equivalent @c is returned unchanged. + **/ +gunichar +g_unichar_toupper (gunichar c) +{ + int t = TYPE (c); + if (t == G_UNICODE_LOWERCASE_LETTER) + { + gunichar val = ATTTABLE (c >> 8, c & 0xff); + if (val >= 0x1000000) + { + const gchar *p = special_case_table + val - 0x1000000; + val = g_utf8_get_char (p); + } + /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR, + * do not have an uppercase equivalent, in which case val will be + * zero. + */ + return val ? val : c; + } + else if (t == G_UNICODE_TITLECASE_LETTER) + { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + { + if (title_table[i][0] == c) + return title_table[i][1] ? title_table[i][1] : c; + } + } + return c; +} + +/** + * g_unichar_tolower: + * @c: a Unicode character. + * + * Converts a character to lower case. + * + * Return value: the result of converting @c to lower case. + * If @c is not an upperlower or titlecase character, + * or has no lowercase equivalent @c is returned unchanged. + **/ +gunichar +g_unichar_tolower (gunichar c) +{ + int t = TYPE (c); + if (t == G_UNICODE_UPPERCASE_LETTER) + { + gunichar val = ATTTABLE (c >> 8, c & 0xff); + if (val >= 0x1000000) + { + const gchar *p = special_case_table + val - 0x1000000; + return g_utf8_get_char (p); + } + else + { + /* Not all uppercase letters are guaranteed to have a lowercase + * equivalent. If this is the case, val will be zero. */ + return val ? val : c; + } + } + else if (t == G_UNICODE_TITLECASE_LETTER) + { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + { + if (title_table[i][0] == c) + return title_table[i][2]; + } + } + return c; +} + +/** + * g_unichar_totitle: + * @c: a Unicode character + * + * Converts a character to the titlecase. + * + * Return value: the result of converting @c to titlecase. + * If @c is not an uppercase or lowercase character, + * @c is returned unchanged. + **/ +gunichar +g_unichar_totitle (gunichar c) +{ + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + { + if (title_table[i][0] == c || title_table[i][1] == c + || title_table[i][2] == c) + return title_table[i][0]; + } + + if (TYPE (c) == G_UNICODE_LOWERCASE_LETTER) + return g_unichar_toupper (c); + + return c; +} + +/** + * g_unichar_digit_value: + * @c: a Unicode character + * + * Determines the numeric value of a character as a decimal + * digit. + * + * Return value: If @c is a decimal digit (according to + * g_unichar_isdigit()), its numeric value. Otherwise, -1. + **/ +int +g_unichar_digit_value (gunichar c) +{ + if (TYPE (c) == G_UNICODE_DECIMAL_NUMBER) + return ATTTABLE (c >> 8, c & 0xff); + return -1; +} + +/** + * g_unichar_xdigit_value: + * @c: a Unicode character + * + * Determines the numeric value of a character as a hexidecimal + * digit. + * + * Return value: If @c is a hex digit (according to + * g_unichar_isxdigit()), its numeric value. Otherwise, -1. + **/ +int +g_unichar_xdigit_value (gunichar c) +{ + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (TYPE (c) == G_UNICODE_DECIMAL_NUMBER) + return ATTTABLE (c >> 8, c & 0xff); + return -1; +} + +/** + * g_unichar_type: + * @c: a Unicode character + * + * Classifies a Unicode character by type. + * + * Return value: the type of the character. + **/ +GUnicodeType +g_unichar_type (gunichar c) +{ + return TYPE (c); +} + +/* + * Case mapping functions + */ + +typedef enum { + LOCALE_NORMAL, + LOCALE_TURKIC, + LOCALE_LITHUANIAN +} LocaleType; + +static LocaleType +get_locale_type (void) +{ +#ifdef G_OS_WIN32 + char *tem = g_win32_getlocale (); + char locale[2]; + + locale[0] = tem[0]; + locale[1] = tem[1]; + g_free (tem); +#else + const char *locale = setlocale (LC_CTYPE, NULL); +#endif + + switch (locale[0]) + { + case 'a': + if (locale[1] == 'z') + return LOCALE_TURKIC; + break; + case 'l': + if (locale[1] == 't') + return LOCALE_LITHUANIAN; + break; + case 't': + if (locale[1] == 'r') + return LOCALE_TURKIC; + break; + } + + return LOCALE_NORMAL; +} + +static gint +output_marks (const char **p_inout, + char *out_buffer, + gboolean remove_dot) +{ + const char *p = *p_inout; + gint len = 0; + + while (*p) + { + gunichar c = g_utf8_get_char (p); + + if (ISMARK (TYPE (c))) + { + if (!remove_dot || c != 0x307 /* COMBINING DOT ABOVE */) + len += g_unichar_to_utf8 (c, out_buffer ? out_buffer + len : NULL); + p = g_utf8_next_char (p); + } + else + break; + } + + *p_inout = p; + return len; +} + +static gint +output_special_case (gchar *out_buffer, + int offset, + int type, + int which) +{ + const gchar *p = special_case_table + offset; + gint len; + + if (type != G_UNICODE_TITLECASE_LETTER) + p = g_utf8_next_char (p); + + if (which == 1) + p += strlen (p) + 1; + + len = strlen (p); + if (out_buffer) + memcpy (out_buffer, p, len); + + return len; +} + +static gsize +real_toupper (const gchar *str, + gssize max_len, + gchar *out_buffer, + LocaleType locale_type) +{ + const gchar *p = str; + const char *last = NULL; + gsize len = 0; + gboolean last_was_i = FALSE; + + while ((max_len < 0 || p < str + max_len) && *p) + { + gunichar c = g_utf8_get_char (p); + int t = TYPE (c); + gunichar val; + + last = p; + p = g_utf8_next_char (p); + + if (locale_type == LOCALE_LITHUANIAN) + { + if (c == 'i') + last_was_i = TRUE; + else + { + if (last_was_i) + { + /* Nasty, need to remove any dot above. Though + * I think only E WITH DOT ABOVE occurs in practice + * which could simplify this considerably. + */ + gsize decomp_len, i; + gunichar decomp[G_UNICHAR_MAX_DECOMPOSITION_LENGTH]; + + decomp_len = g_unichar_fully_decompose (c, FALSE, decomp, G_N_ELEMENTS (decomp)); + for (i=0; i < decomp_len; i++) + { + if (decomp[i] != 0x307 /* COMBINING DOT ABOVE */) + len += g_unichar_to_utf8 (g_unichar_toupper (decomp[i]), out_buffer ? out_buffer + len : NULL); + } + + len += output_marks (&p, out_buffer ? out_buffer + len : NULL, TRUE); + + continue; + } + + if (!ISMARK (t)) + last_was_i = FALSE; + } + } + + if (locale_type == LOCALE_TURKIC && c == 'i') + { + /* i => LATIN CAPITAL LETTER I WITH DOT ABOVE */ + len += g_unichar_to_utf8 (0x130, out_buffer ? out_buffer + len : NULL); + } + else if (c == 0x0345) /* COMBINING GREEK YPOGEGRAMMENI */ + { + /* Nasty, need to move it after other combining marks .. this would go away if + * we normalized first. + */ + len += output_marks (&p, out_buffer ? out_buffer + len : NULL, FALSE); + + /* And output as GREEK CAPITAL LETTER IOTA */ + len += g_unichar_to_utf8 (0x399, out_buffer ? out_buffer + len : NULL); + } + else if (IS (t, + OR (G_UNICODE_LOWERCASE_LETTER, + OR (G_UNICODE_TITLECASE_LETTER, + 0)))) + { + val = ATTTABLE (c >> 8, c & 0xff); + + if (val >= 0x1000000) + { + len += output_special_case (out_buffer ? out_buffer + len : NULL, val - 0x1000000, t, + t == G_UNICODE_LOWERCASE_LETTER ? 0 : 1); + } + else + { + if (t == G_UNICODE_TITLECASE_LETTER) + { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + { + if (title_table[i][0] == c) + { + val = title_table[i][1]; + break; + } + } + } + + /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR, + * do not have an uppercase equivalent, in which case val will be + * zero. */ + len += g_unichar_to_utf8 (val ? val : c, out_buffer ? out_buffer + len : NULL); + } + } + else + { + gsize char_len = g_utf8_skip[*(guchar *)last]; + + if (out_buffer) + memcpy (out_buffer + len, last, char_len); + + len += char_len; + } + + } + + return len; +} + +/** + * g_utf8_strup: + * @str: a UTF-8 encoded string + * @len: length of @str, in bytes, or -1 if @str is nul-terminated. + * + * Converts all Unicode characters in the string that have a case + * to uppercase. The exact manner that this is done depends + * on the current locale, and may result in the number of + * characters in the string increasing. (For instance, the + * German ess-zet will be changed to SS.) + * + * Return value: a newly allocated string, with all characters + * converted to uppercase. + **/ +gchar * +g_utf8_strup (const gchar *str, + gssize len) +{ + gsize result_len; + LocaleType locale_type; + gchar *result; + + g_return_val_if_fail (str != NULL, NULL); + + locale_type = get_locale_type (); + + /* + * We use a two pass approach to keep memory management simple + */ + result_len = real_toupper (str, len, NULL, locale_type); + result = g_malloc (result_len + 1); + real_toupper (str, len, result, locale_type); + result[result_len] = '\0'; + + return result; +} + +/* traverses the string checking for characters with combining class == 230 + * until a base character is found */ +static gboolean +has_more_above (const gchar *str) +{ + const gchar *p = str; + gint combining_class; + + while (*p) + { + combining_class = g_unichar_combining_class (g_utf8_get_char (p)); + if (combining_class == 230) + return TRUE; + else if (combining_class == 0) + break; + + p = g_utf8_next_char (p); + } + + return FALSE; +} + +static gsize +real_tolower (const gchar *str, + gssize max_len, + gchar *out_buffer, + LocaleType locale_type) +{ + const gchar *p = str; + const char *last = NULL; + gsize len = 0; + + while ((max_len < 0 || p < str + max_len) && *p) + { + gunichar c = g_utf8_get_char (p); + int t = TYPE (c); + gunichar val; + + last = p; + p = g_utf8_next_char (p); + + if (locale_type == LOCALE_TURKIC && c == 'I') + { + if (g_utf8_get_char (p) == 0x0307) + { + /* I + COMBINING DOT ABOVE => i (U+0069) */ + len += g_unichar_to_utf8 (0x0069, out_buffer ? out_buffer + len : NULL); + p = g_utf8_next_char (p); + } + else + { + /* I => LATIN SMALL LETTER DOTLESS I */ + len += g_unichar_to_utf8 (0x131, out_buffer ? out_buffer + len : NULL); + } + } + /* Introduce an explicit dot above when lowercasing capital I's and J's + * whenever there are more accents above. [SpecialCasing.txt] */ + else if (locale_type == LOCALE_LITHUANIAN && + (c == 0x00cc || c == 0x00cd || c == 0x0128)) + { + len += g_unichar_to_utf8 (0x0069, out_buffer ? out_buffer + len : NULL); + len += g_unichar_to_utf8 (0x0307, out_buffer ? out_buffer + len : NULL); + + switch (c) + { + case 0x00cc: + len += g_unichar_to_utf8 (0x0300, out_buffer ? out_buffer + len : NULL); + break; + case 0x00cd: + len += g_unichar_to_utf8 (0x0301, out_buffer ? out_buffer + len : NULL); + break; + case 0x0128: + len += g_unichar_to_utf8 (0x0303, out_buffer ? out_buffer + len : NULL); + break; + } + } + else if (locale_type == LOCALE_LITHUANIAN && + (c == 'I' || c == 'J' || c == 0x012e) && + has_more_above (p)) + { + len += g_unichar_to_utf8 (g_unichar_tolower (c), out_buffer ? out_buffer + len : NULL); + len += g_unichar_to_utf8 (0x0307, out_buffer ? out_buffer + len : NULL); + } + else if (c == 0x03A3) /* GREEK CAPITAL LETTER SIGMA */ + { + if ((max_len < 0 || p < str + max_len) && *p) + { + gunichar next_c = g_utf8_get_char (p); + int next_type = TYPE(next_c); + + /* SIGMA mapps differently depending on whether it is + * final or not. The following simplified test would + * fail in the case of combining marks following the + * sigma, but I don't think that occurs in real text. + * The test here matches that in ICU. + */ + if (ISALPHA (next_type)) /* Lu,Ll,Lt,Lm,Lo */ + val = 0x3c3; /* GREEK SMALL SIGMA */ + else + val = 0x3c2; /* GREEK SMALL FINAL SIGMA */ + } + else + val = 0x3c2; /* GREEK SMALL FINAL SIGMA */ + + len += g_unichar_to_utf8 (val, out_buffer ? out_buffer + len : NULL); + } + else if (IS (t, + OR (G_UNICODE_UPPERCASE_LETTER, + OR (G_UNICODE_TITLECASE_LETTER, + 0)))) + { + val = ATTTABLE (c >> 8, c & 0xff); + + if (val >= 0x1000000) + { + len += output_special_case (out_buffer ? out_buffer + len : NULL, val - 0x1000000, t, 0); + } + else + { + if (t == G_UNICODE_TITLECASE_LETTER) + { + unsigned int i; + for (i = 0; i < G_N_ELEMENTS (title_table); ++i) + { + if (title_table[i][0] == c) + { + val = title_table[i][2]; + break; + } + } + } + + /* Not all uppercase letters are guaranteed to have a lowercase + * equivalent. If this is the case, val will be zero. */ + len += g_unichar_to_utf8 (val ? val : c, out_buffer ? out_buffer + len : NULL); + } + } + else + { + gsize char_len = g_utf8_skip[*(guchar *)last]; + + if (out_buffer) + memcpy (out_buffer + len, last, char_len); + + len += char_len; + } + + } + + return len; +} + +/** + * g_utf8_strdown: + * @str: a UTF-8 encoded string + * @len: length of @str, in bytes, or -1 if @str is nul-terminated. + * + * Converts all Unicode characters in the string that have a case + * to lowercase. The exact manner that this is done depends + * on the current locale, and may result in the number of + * characters in the string changing. + * + * Return value: a newly allocated string, with all characters + * converted to lowercase. + **/ +gchar * +g_utf8_strdown (const gchar *str, + gssize len) +{ + gsize result_len; + LocaleType locale_type; + gchar *result; + + g_return_val_if_fail (str != NULL, NULL); + + locale_type = get_locale_type (); + + /* + * We use a two pass approach to keep memory management simple + */ + result_len = real_tolower (str, len, NULL, locale_type); + result = g_malloc (result_len + 1); + real_tolower (str, len, result, locale_type); + result[result_len] = '\0'; + + return result; +} + +/** + * g_utf8_casefold: + * @str: a UTF-8 encoded string + * @len: length of @str, in bytes, or -1 if @str is nul-terminated. + * + * Converts a string into a form that is independent of case. The + * result will not correspond to any particular case, but can be + * compared for equality or ordered with the results of calling + * g_utf8_casefold() on other strings. + * + * Note that calling g_utf8_casefold() followed by g_utf8_collate() is + * only an approximation to the correct linguistic case insensitive + * ordering, though it is a fairly good one. Getting this exactly + * right would require a more sophisticated collation function that + * takes case sensitivity into account. GLib does not currently + * provide such a function. + * + * Return value: a newly allocated string, that is a + * case independent form of @str. + **/ +gchar * +g_utf8_casefold (const gchar *str, + gssize len) +{ + GString *result; + const char *p; + + g_return_val_if_fail (str != NULL, NULL); + + result = g_string_new (NULL); + p = str; + while ((len < 0 || p < str + len) && *p) + { + gunichar ch = g_utf8_get_char (p); + + int start = 0; + int end = G_N_ELEMENTS (casefold_table); + + if (ch >= casefold_table[start].ch && + ch <= casefold_table[end - 1].ch) + { + while (TRUE) + { + int half = (start + end) / 2; + if (ch == casefold_table[half].ch) + { + g_string_append (result, casefold_table[half].data); + goto next; + } + else if (half == start) + break; + else if (ch > casefold_table[half].ch) + start = half; + else + end = half; + } + } + + g_string_append_unichar (result, g_unichar_tolower (ch)); + + next: + p = g_utf8_next_char (p); + } + + return g_string_free (result, FALSE); +} + +/** + * g_unichar_get_mirror_char: + * @ch: a Unicode character + * @mirrored_ch: location to store the mirrored character + * + * In Unicode, some characters are mirrored. This + * means that their images are mirrored horizontally in text that is laid + * out from right to left. For instance, "(" would become its mirror image, + * ")", in right-to-left text. + * + * If @ch has the Unicode mirrored property and there is another unicode + * character that typically has a glyph that is the mirror image of @ch's + * glyph and @mirrored_ch is set, it puts that character in the address + * pointed to by @mirrored_ch. Otherwise the original character is put. + * + * Return value: %TRUE if @ch has a mirrored character, %FALSE otherwise + * + * Since: 2.4 + **/ +gboolean +g_unichar_get_mirror_char (gunichar ch, + gunichar *mirrored_ch) +{ + gboolean found; + gunichar mirrored; + + mirrored = GLIB_GET_MIRRORING(ch); + + found = ch != mirrored; + if (mirrored_ch) + *mirrored_ch = mirrored; + + return found; + +} + +#define G_SCRIPT_TABLE_MIDPOINT (G_N_ELEMENTS (g_script_table) / 2) + +static inline GUnicodeScript +g_unichar_get_script_bsearch (gunichar ch) +{ + int lower = 0; + int upper = G_N_ELEMENTS (g_script_table) - 1; + static int saved_mid = G_SCRIPT_TABLE_MIDPOINT; + int mid = saved_mid; + + + do + { + if (ch < g_script_table[mid].start) + upper = mid - 1; + else if (ch >= g_script_table[mid].start + g_script_table[mid].chars) + lower = mid + 1; + else + return g_script_table[saved_mid = mid].script; + + mid = (lower + upper) / 2; + } + while (lower <= upper); + + return G_UNICODE_SCRIPT_UNKNOWN; +} + +/** + * g_unichar_get_script: + * @ch: a Unicode character + * + * Looks up the #GUnicodeScript for a particular character (as defined + * by Unicode Standard Annex \#24). No check is made for @ch being a + * valid Unicode character; if you pass in invalid character, the + * result is undefined. + * + * This function is equivalent to pango_script_for_unichar() and the + * two are interchangeable. + * + * Return value: the #GUnicodeScript for the character. + * + * Since: 2.14 + */ +GUnicodeScript +g_unichar_get_script (gunichar ch) +{ + if (ch < G_EASY_SCRIPTS_RANGE) + return g_script_easy_table[ch]; + else + return g_unichar_get_script_bsearch (ch); +} + + +/* http://unicode.org/iso15924/ */ +static const guint32 iso15924_tags[] = +{ +#define PACK(a,b,c,d) ((guint32)((((guint8)(a))<<24)|(((guint8)(b))<<16)|(((guint8)(c))<<8)|((guint8)(d)))) + + PACK ('Z','y','y','y'), /* G_UNICODE_SCRIPT_COMMON */ + PACK ('Z','i','n','h'), /* G_UNICODE_SCRIPT_INHERITED */ + PACK ('A','r','a','b'), /* G_UNICODE_SCRIPT_ARABIC */ + PACK ('A','r','m','n'), /* G_UNICODE_SCRIPT_ARMENIAN */ + PACK ('B','e','n','g'), /* G_UNICODE_SCRIPT_BENGALI */ + PACK ('B','o','p','o'), /* G_UNICODE_SCRIPT_BOPOMOFO */ + PACK ('C','h','e','r'), /* G_UNICODE_SCRIPT_CHEROKEE */ + PACK ('C','o','p','t'), /* G_UNICODE_SCRIPT_COPTIC */ + PACK ('C','y','r','l'), /* G_UNICODE_SCRIPT_CYRILLIC */ + PACK ('D','s','r','t'), /* G_UNICODE_SCRIPT_DESERET */ + PACK ('D','e','v','a'), /* G_UNICODE_SCRIPT_DEVANAGARI */ + PACK ('E','t','h','i'), /* G_UNICODE_SCRIPT_ETHIOPIC */ + PACK ('G','e','o','r'), /* G_UNICODE_SCRIPT_GEORGIAN */ + PACK ('G','o','t','h'), /* G_UNICODE_SCRIPT_GOTHIC */ + PACK ('G','r','e','k'), /* G_UNICODE_SCRIPT_GREEK */ + PACK ('G','u','j','r'), /* G_UNICODE_SCRIPT_GUJARATI */ + PACK ('G','u','r','u'), /* G_UNICODE_SCRIPT_GURMUKHI */ + PACK ('H','a','n','i'), /* G_UNICODE_SCRIPT_HAN */ + PACK ('H','a','n','g'), /* G_UNICODE_SCRIPT_HANGUL */ + PACK ('H','e','b','r'), /* G_UNICODE_SCRIPT_HEBREW */ + PACK ('H','i','r','a'), /* G_UNICODE_SCRIPT_HIRAGANA */ + PACK ('K','n','d','a'), /* G_UNICODE_SCRIPT_KANNADA */ + PACK ('K','a','n','a'), /* G_UNICODE_SCRIPT_KATAKANA */ + PACK ('K','h','m','r'), /* G_UNICODE_SCRIPT_KHMER */ + PACK ('L','a','o','o'), /* G_UNICODE_SCRIPT_LAO */ + PACK ('L','a','t','n'), /* G_UNICODE_SCRIPT_LATIN */ + PACK ('M','l','y','m'), /* G_UNICODE_SCRIPT_MALAYALAM */ + PACK ('M','o','n','g'), /* G_UNICODE_SCRIPT_MONGOLIAN */ + PACK ('M','y','m','r'), /* G_UNICODE_SCRIPT_MYANMAR */ + PACK ('O','g','a','m'), /* G_UNICODE_SCRIPT_OGHAM */ + PACK ('I','t','a','l'), /* G_UNICODE_SCRIPT_OLD_ITALIC */ + PACK ('O','r','y','a'), /* G_UNICODE_SCRIPT_ORIYA */ + PACK ('R','u','n','r'), /* G_UNICODE_SCRIPT_RUNIC */ + PACK ('S','i','n','h'), /* G_UNICODE_SCRIPT_SINHALA */ + PACK ('S','y','r','c'), /* G_UNICODE_SCRIPT_SYRIAC */ + PACK ('T','a','m','l'), /* G_UNICODE_SCRIPT_TAMIL */ + PACK ('T','e','l','u'), /* G_UNICODE_SCRIPT_TELUGU */ + PACK ('T','h','a','a'), /* G_UNICODE_SCRIPT_THAANA */ + PACK ('T','h','a','i'), /* G_UNICODE_SCRIPT_THAI */ + PACK ('T','i','b','t'), /* G_UNICODE_SCRIPT_TIBETAN */ + PACK ('C','a','n','s'), /* G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL */ + PACK ('Y','i','i','i'), /* G_UNICODE_SCRIPT_YI */ + PACK ('T','g','l','g'), /* G_UNICODE_SCRIPT_TAGALOG */ + PACK ('H','a','n','o'), /* G_UNICODE_SCRIPT_HANUNOO */ + PACK ('B','u','h','d'), /* G_UNICODE_SCRIPT_BUHID */ + PACK ('T','a','g','b'), /* G_UNICODE_SCRIPT_TAGBANWA */ + + /* Unicode-4.0 additions */ + PACK ('B','r','a','i'), /* G_UNICODE_SCRIPT_BRAILLE */ + PACK ('C','p','r','t'), /* G_UNICODE_SCRIPT_CYPRIOT */ + PACK ('L','i','m','b'), /* G_UNICODE_SCRIPT_LIMBU */ + PACK ('O','s','m','a'), /* G_UNICODE_SCRIPT_OSMANYA */ + PACK ('S','h','a','w'), /* G_UNICODE_SCRIPT_SHAVIAN */ + PACK ('L','i','n','b'), /* G_UNICODE_SCRIPT_LINEAR_B */ + PACK ('T','a','l','e'), /* G_UNICODE_SCRIPT_TAI_LE */ + PACK ('U','g','a','r'), /* G_UNICODE_SCRIPT_UGARITIC */ + + /* Unicode-4.1 additions */ + PACK ('T','a','l','u'), /* G_UNICODE_SCRIPT_NEW_TAI_LUE */ + PACK ('B','u','g','i'), /* G_UNICODE_SCRIPT_BUGINESE */ + PACK ('G','l','a','g'), /* G_UNICODE_SCRIPT_GLAGOLITIC */ + PACK ('T','f','n','g'), /* G_UNICODE_SCRIPT_TIFINAGH */ + PACK ('S','y','l','o'), /* G_UNICODE_SCRIPT_SYLOTI_NAGRI */ + PACK ('X','p','e','o'), /* G_UNICODE_SCRIPT_OLD_PERSIAN */ + PACK ('K','h','a','r'), /* G_UNICODE_SCRIPT_KHAROSHTHI */ + + /* Unicode-5.0 additions */ + PACK ('Z','z','z','z'), /* G_UNICODE_SCRIPT_UNKNOWN */ + PACK ('B','a','l','i'), /* G_UNICODE_SCRIPT_BALINESE */ + PACK ('X','s','u','x'), /* G_UNICODE_SCRIPT_CUNEIFORM */ + PACK ('P','h','n','x'), /* G_UNICODE_SCRIPT_PHOENICIAN */ + PACK ('P','h','a','g'), /* G_UNICODE_SCRIPT_PHAGS_PA */ + PACK ('N','k','o','o'), /* G_UNICODE_SCRIPT_NKO */ + + /* Unicode-5.1 additions */ + PACK ('K','a','l','i'), /* G_UNICODE_SCRIPT_KAYAH_LI */ + PACK ('L','e','p','c'), /* G_UNICODE_SCRIPT_LEPCHA */ + PACK ('R','j','n','g'), /* G_UNICODE_SCRIPT_REJANG */ + PACK ('S','u','n','d'), /* G_UNICODE_SCRIPT_SUNDANESE */ + PACK ('S','a','u','r'), /* G_UNICODE_SCRIPT_SAURASHTRA */ + PACK ('C','h','a','m'), /* G_UNICODE_SCRIPT_CHAM */ + PACK ('O','l','c','k'), /* G_UNICODE_SCRIPT_OL_CHIKI */ + PACK ('V','a','i','i'), /* G_UNICODE_SCRIPT_VAI */ + PACK ('C','a','r','i'), /* G_UNICODE_SCRIPT_CARIAN */ + PACK ('L','y','c','i'), /* G_UNICODE_SCRIPT_LYCIAN */ + PACK ('L','y','d','i'), /* G_UNICODE_SCRIPT_LYDIAN */ + + /* Unicode-5.2 additions */ + PACK ('A','v','s','t'), /* G_UNICODE_SCRIPT_AVESTAN */ + PACK ('B','a','m','u'), /* G_UNICODE_SCRIPT_BAMUM */ + PACK ('E','g','y','p'), /* G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS */ + PACK ('A','r','m','i'), /* G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC */ + PACK ('P','h','l','i'), /* G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI */ + PACK ('P','r','t','i'), /* G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN */ + PACK ('J','a','v','a'), /* G_UNICODE_SCRIPT_JAVANESE */ + PACK ('K','t','h','i'), /* G_UNICODE_SCRIPT_KAITHI */ + PACK ('L','i','s','u'), /* G_UNICODE_SCRIPT_LISU */ + PACK ('M','t','e','i'), /* G_UNICODE_SCRIPT_MEETEI_MAYEK */ + PACK ('S','a','r','b'), /* G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN */ + PACK ('O','r','k','h'), /* G_UNICODE_SCRIPT_OLD_TURKIC */ + PACK ('S','a','m','r'), /* G_UNICODE_SCRIPT_SAMARITAN */ + PACK ('L','a','n','a'), /* G_UNICODE_SCRIPT_TAI_THAM */ + PACK ('T','a','v','t'), /* G_UNICODE_SCRIPT_TAI_VIET */ + + /* Unicode-6.0 additions */ + PACK ('B','a','t','k'), /* G_UNICODE_SCRIPT_BATAK */ + PACK ('B','r','a','h'), /* G_UNICODE_SCRIPT_BRAHMI */ + PACK ('M','a','n','d'), /* G_UNICODE_SCRIPT_MANDAIC */ + + /* Unicode-6.1 additions */ + PACK ('C','a','k','m'), /* G_UNICODE_SCRIPT_CHAKMA */ + PACK ('M','e','r','c'), /* G_UNICODE_SCRIPT_MEROITIC_CURSIVE */ + PACK ('M','e','r','o'), /* G_UNICODE_SCRIPT_MEROITIC_HIEROGLYPHS */ + PACK ('P','l','r','d'), /* G_UNICODE_SCRIPT_MIAO */ + PACK ('S','h','r','d'), /* G_UNICODE_SCRIPT_SHARADA */ + PACK ('S','o','r','a'), /* G_UNICODE_SCRIPT_SORA_SOMPENG */ + PACK ('T','a','k','r'), /* G_UNICODE_SCRIPT_TAKRI */ + +#undef PACK +}; + +/** + * g_unicode_script_to_iso15924: + * @script: a Unicode script + * + * Looks up the ISO 15924 code for @script. ISO 15924 assigns four-letter + * codes to scripts. For example, the code for Arabic is 'Arab'. The + * four letter codes are encoded as a @guint32 by this function in a + * big-endian fashion. That is, the code returned for Arabic is + * 0x41726162 (0x41 is ASCII code for 'A', 0x72 is ASCII code for 'r', etc). + * + * See Codes for the + * representation of names of scripts for details. + * + * Return value: the ISO 15924 code for @script, encoded as an integer, + * of zero if @script is %G_UNICODE_SCRIPT_INVALID_CODE or + * ISO 15924 code 'Zzzz' (script code for UNKNOWN) if @script is not understood. + * + * Since: 2.30 + */ +guint32 +g_unicode_script_to_iso15924 (GUnicodeScript script) +{ + if (G_UNLIKELY (script == G_UNICODE_SCRIPT_INVALID_CODE)) + return 0; + + if (G_UNLIKELY (script < 0 || script >= (int) G_N_ELEMENTS (iso15924_tags))) + return 0x5A7A7A7A; + + return iso15924_tags[script]; +} + +/** + * g_unicode_script_from_iso15924: + * @iso15924: a Unicode script + * + * Looks up the Unicode script for @iso15924. ISO 15924 assigns four-letter + * codes to scripts. For example, the code for Arabic is 'Arab'. + * This function accepts four letter codes encoded as a @guint32 in a + * big-endian fashion. That is, the code expected for Arabic is + * 0x41726162 (0x41 is ASCII code for 'A', 0x72 is ASCII code for 'r', etc). + * + * See Codes for the + * representation of names of scripts for details. + * + * Return value: the Unicode script for @iso15924, or + * of %G_UNICODE_SCRIPT_INVALID_CODE if @iso15924 is zero and + * %G_UNICODE_SCRIPT_UNKNOWN if @iso15924 is unknown. + * + * Since: 2.30 + */ +GUnicodeScript +g_unicode_script_from_iso15924 (guint32 iso15924) +{ + unsigned int i; + + if (!iso15924) + return G_UNICODE_SCRIPT_INVALID_CODE; + + for (i = 0; i < G_N_ELEMENTS (iso15924_tags); i++) + if (iso15924_tags[i] == iso15924) + return (GUnicodeScript) i; + + return G_UNICODE_SCRIPT_UNKNOWN; +} diff --git a/glib/glib/gurifuncs.c b/glib/glib/gurifuncs.c new file mode 100644 index 0000000..d438205 --- /dev/null +++ b/glib/glib/gurifuncs.c @@ -0,0 +1,252 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alexander Larsson + */ + +#include "config.h" + +#include "gurifuncs.h" + +#include +#include +#include +#include + +#include + +#include "config.h" + +/** + * SECTION:gurifuncs + * @title: URI Functions + * @short_description: manipulating URIs + * + * Functions for manipulating Universal Resource Identifiers (URIs) as + * defined by + * RFC 3986. It is highly recommended that you have read and + * understand RFC 3986 for understanding this API. + */ + +static int +unescape_character (const char *scanner) +{ + int first_digit; + int second_digit; + + first_digit = g_ascii_xdigit_value (*scanner++); + if (first_digit < 0) + return -1; + + second_digit = g_ascii_xdigit_value (*scanner++); + if (second_digit < 0) + return -1; + + return (first_digit << 4) | second_digit; +} + +/** + * g_uri_unescape_segment: + * @escaped_string: (allow-none): A string, may be %NULL + * @escaped_string_end: (allow-none): Pointer to end of @escaped_string, may be %NULL + * @illegal_characters: (allow-none): An optional string of illegal characters not to be allowed, may be %NULL + * + * Unescapes a segment of an escaped string. + * + * If any of the characters in @illegal_characters or the character zero appears + * as an escaped character in @escaped_string then that is an error and %NULL + * will be returned. This is useful it you want to avoid for instance having a + * slash being expanded in an escaped path element, which might confuse pathname + * handling. + * + * Returns: an unescaped version of @escaped_string or %NULL on error. + * The returned string should be freed when no longer needed. As a + * special case if %NULL is given for @escaped_string, this function + * will return %NULL. + * + * Since: 2.16 + **/ +char * +g_uri_unescape_segment (const char *escaped_string, + const char *escaped_string_end, + const char *illegal_characters) +{ + const char *in; + char *out, *result; + gint character; + + if (escaped_string == NULL) + return NULL; + + if (escaped_string_end == NULL) + escaped_string_end = escaped_string + strlen (escaped_string); + + result = g_malloc (escaped_string_end - escaped_string + 1); + + out = result; + for (in = escaped_string; in < escaped_string_end; in++) + { + character = *in; + + if (*in == '%') + { + in++; + + if (escaped_string_end - in < 2) + { + /* Invalid escaped char (to short) */ + g_free (result); + return NULL; + } + + character = unescape_character (in); + + /* Check for an illegal character. We consider '\0' illegal here. */ + if (character <= 0 || + (illegal_characters != NULL && + strchr (illegal_characters, (char)character) != NULL)) + { + g_free (result); + return NULL; + } + + in++; /* The other char will be eaten in the loop header */ + } + *out++ = (char)character; + } + + *out = '\0'; + + return result; +} + +/** + * g_uri_unescape_string: + * @escaped_string: an escaped string to be unescaped. + * @illegal_characters: an optional string of illegal characters not to be allowed. + * + * Unescapes a whole escaped string. + * + * If any of the characters in @illegal_characters or the character zero appears + * as an escaped character in @escaped_string then that is an error and %NULL + * will be returned. This is useful it you want to avoid for instance having a + * slash being expanded in an escaped path element, which might confuse pathname + * handling. + * + * Returns: an unescaped version of @escaped_string. The returned string + * should be freed when no longer needed. + * + * Since: 2.16 + **/ +char * +g_uri_unescape_string (const char *escaped_string, + const char *illegal_characters) +{ + return g_uri_unescape_segment (escaped_string, NULL, illegal_characters); +} + +/** + * g_uri_parse_scheme: + * @uri: a valid URI. + * + * Gets the scheme portion of a URI string. RFC 3986 decodes the scheme as: + * + * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + * + * Common schemes include "file", "http", "svn+ssh", etc. + * + * Returns: The "Scheme" component of the URI, or %NULL on error. + * The returned string should be freed when no longer needed. + * + * Since: 2.16 + **/ +char * +g_uri_parse_scheme (const char *uri) +{ + const char *p; + char c; + + g_return_val_if_fail (uri != NULL, NULL); + + /* From RFC 3986 Decodes: + * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] + */ + + p = uri; + + /* Decode scheme: + scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) + */ + + if (!g_ascii_isalpha (*p)) + return NULL; + + while (1) + { + c = *p++; + + if (c == ':') + break; + + if (!(g_ascii_isalnum(c) || + c == '+' || + c == '-' || + c == '.')) + return NULL; + } + + return g_strndup (uri, p - uri - 1); +} + +/** + * g_uri_escape_string: + * @unescaped: the unescaped input string. + * @reserved_chars_allowed: a string of reserved characters that are + * allowed to be used, or %NULL. + * @allow_utf8: %TRUE if the result can include UTF-8 characters. + * + * Escapes a string for use in a URI. + * + * Normally all characters that are not "unreserved" (i.e. ASCII alphanumerical + * characters plus dash, dot, underscore and tilde) are escaped. + * But if you specify characters in @reserved_chars_allowed they are not + * escaped. This is useful for the "reserved" characters in the URI + * specification, since those are allowed unescaped in some portions of + * a URI. + * + * Returns: an escaped version of @unescaped. The returned string should be + * freed when no longer needed. + * + * Since: 2.16 + **/ +char * +g_uri_escape_string (const char *unescaped, + const char *reserved_chars_allowed, + gboolean allow_utf8) +{ + GString *s; + + g_return_val_if_fail (unescaped != NULL, NULL); + + s = g_string_sized_new (strlen (unescaped) + 10); + + g_string_append_uri_escaped (s, unescaped, reserved_chars_allowed, allow_utf8); + + return g_string_free (s, FALSE); +} diff --git a/glib/glib/gurifuncs.h b/glib/glib/gurifuncs.h new file mode 100644 index 0000000..8097806 --- /dev/null +++ b/glib/glib/gurifuncs.h @@ -0,0 +1,81 @@ +/* GIO - GLib Input, Output and Streaming Library + * + * Copyright (C) 2006-2007 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General + * Public License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Alexander Larsson + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_URI_FUNCS_H__ +#define __G_URI_FUNCS_H__ + +#include + +G_BEGIN_DECLS + +/** + * G_URI_RESERVED_CHARS_GENERIC_DELIMITERS: + * + * Generic delimiters characters as defined in RFC 3986. Includes ":/?#[]@". + **/ +#define G_URI_RESERVED_CHARS_GENERIC_DELIMITERS ":/?#[]@" + +/** + * G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS + * + * Subcomponent delimiter characters as defined in RFC 3986. Includes "!$&'()*+,;=". + **/ +#define G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS "!$&'()*+,;=" + +/** + * G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT: + * + * Allowed characters in path elements. Includes "!$&'()*+,;=:@". + **/ +#define G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS ":@" + +/** + * G_URI_RESERVED_CHARS_ALLOWED_IN_PATH: + * + * Allowed characters in a path. Includes "!$&'()*+,;=:@/". + **/ +#define G_URI_RESERVED_CHARS_ALLOWED_IN_PATH G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT "/" + +/** + * G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO: + * + * Allowed characters in userinfo as defined in RFC 3986. Includes "!$&'()*+,;=:". + **/ +#define G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS ":" + +char * g_uri_unescape_string (const char *escaped_string, + const char *illegal_characters); +char * g_uri_unescape_segment (const char *escaped_string, + const char *escaped_string_end, + const char *illegal_characters); +char * g_uri_parse_scheme (const char *uri); +char * g_uri_escape_string (const char *unescaped, + const char *reserved_chars_allowed, + gboolean allow_utf8); + +G_END_DECLS + +#endif /* __G_URI_FUNCS_H__ */ diff --git a/glib/glib/gutf8.c b/glib/glib/gutf8.c new file mode 100644 index 0000000..e1e0003 --- /dev/null +++ b/glib/glib/gutf8.c @@ -0,0 +1,1747 @@ +/* gutf8.c - Operations on UTF-8 strings. + * + * Copyright (C) 1999 Tom Tromey + * Copyright (C) 2000 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" + +#include +#ifdef HAVE_CODESET +#include +#endif +#include + +#ifdef G_PLATFORM_WIN32 +#include +#define STRICT +#include +#undef STRICT +#endif + +#include "gconvert.h" +#include "ghash.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gtypes.h" +#include "gthread.h" +#include "glibintl.h" + +#define UTF8_COMPUTE(Char, Mask, Len) \ + if (Char < 128) \ + { \ + Len = 1; \ + Mask = 0x7f; \ + } \ + else if ((Char & 0xe0) == 0xc0) \ + { \ + Len = 2; \ + Mask = 0x1f; \ + } \ + else if ((Char & 0xf0) == 0xe0) \ + { \ + Len = 3; \ + Mask = 0x0f; \ + } \ + else if ((Char & 0xf8) == 0xf0) \ + { \ + Len = 4; \ + Mask = 0x07; \ + } \ + else if ((Char & 0xfc) == 0xf8) \ + { \ + Len = 5; \ + Mask = 0x03; \ + } \ + else if ((Char & 0xfe) == 0xfc) \ + { \ + Len = 6; \ + Mask = 0x01; \ + } \ + else \ + Len = -1; + +#define UTF8_LENGTH(Char) \ + ((Char) < 0x80 ? 1 : \ + ((Char) < 0x800 ? 2 : \ + ((Char) < 0x10000 ? 3 : \ + ((Char) < 0x200000 ? 4 : \ + ((Char) < 0x4000000 ? 5 : 6))))) + + +#define UTF8_GET(Result, Chars, Count, Mask, Len) \ + (Result) = (Chars)[0] & (Mask); \ + for ((Count) = 1; (Count) < (Len); ++(Count)) \ + { \ + if (((Chars)[(Count)] & 0xc0) != 0x80) \ + { \ + (Result) = -1; \ + break; \ + } \ + (Result) <<= 6; \ + (Result) |= ((Chars)[(Count)] & 0x3f); \ + } + +/* + * Check whether a Unicode (5.2) char is in a valid range. + * + * The first check comes from the Unicode guarantee to never encode + * a point above 0x0010ffff, since UTF-16 couldn't represent it. + * + * The second check covers surrogate pairs (category Cs). + * + * The last two checks cover "Noncharacter": defined as: + * "A code point that is permanently reserved for + * internal use, and that should never be interchanged. In + * Unicode 3.1, these consist of the values U+nFFFE and U+nFFFF + * (where n is from 0 to 10_16) and the values U+FDD0..U+FDEF." + * + * @param Char the character + */ +#define UNICODE_VALID(Char) \ + ((Char) < 0x110000 && \ + (((Char) & 0xFFFFF800) != 0xD800) && \ + ((Char) < 0xFDD0 || (Char) > 0xFDEF) && \ + ((Char) & 0xFFFE) != 0xFFFE) + + +static const gchar utf8_skip_data[256] = { + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, + 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1 +}; + +const gchar * const g_utf8_skip = utf8_skip_data; + +/** + * g_utf8_find_prev_char: + * @str: pointer to the beginning of a UTF-8 encoded string + * @p: pointer to some position within @str + * + * Given a position @p with a UTF-8 encoded string @str, find the start + * of the previous UTF-8 character starting before @p. Returns %NULL if no + * UTF-8 characters are present in @str before @p. + * + * @p does not have to be at the beginning of a UTF-8 character. No check + * is made to see if the character found is actually valid other than + * it starts with an appropriate byte. + * + * Return value: a pointer to the found character or %NULL. + **/ +gchar * +g_utf8_find_prev_char (const char *str, + const char *p) +{ + for (--p; p >= str; --p) + { + if ((*p & 0xc0) != 0x80) + return (gchar *)p; + } + return NULL; +} + +/** + * g_utf8_find_next_char: + * @p: a pointer to a position within a UTF-8 encoded string + * @end: a pointer to the byte following the end of the string, + * or %NULL to indicate that the string is nul-terminated. + * + * Finds the start of the next UTF-8 character in the string after @p. + * + * @p does not have to be at the beginning of a UTF-8 character. No check + * is made to see if the character found is actually valid other than + * it starts with an appropriate byte. + * + * Return value: a pointer to the found character or %NULL + **/ +gchar * +g_utf8_find_next_char (const gchar *p, + const gchar *end) +{ + if (*p) + { + if (end) + for (++p; p < end && (*p & 0xc0) == 0x80; ++p) + ; + else + for (++p; (*p & 0xc0) == 0x80; ++p) + ; + } + return (p == end) ? NULL : (gchar *)p; +} + +/** + * g_utf8_prev_char: + * @p: a pointer to a position within a UTF-8 encoded string + * + * Finds the previous UTF-8 character in the string before @p. + * + * @p does not have to be at the beginning of a UTF-8 character. No check + * is made to see if the character found is actually valid other than + * it starts with an appropriate byte. If @p might be the first + * character of the string, you must use g_utf8_find_prev_char() instead. + * + * Return value: a pointer to the found character. + **/ +gchar * +g_utf8_prev_char (const gchar *p) +{ + while (TRUE) + { + p--; + if ((*p & 0xc0) != 0x80) + return (gchar *)p; + } +} + +/** + * g_utf8_strlen: + * @p: pointer to the start of a UTF-8 encoded string + * @max: the maximum number of bytes to examine. If @max + * is less than 0, then the string is assumed to be + * nul-terminated. If @max is 0, @p will not be examined and + * may be %NULL. If @max is greater than 0, up to @max + * bytes are examined + * + * Computes the length of the string in characters, not including + * the terminating nul character. If the @max'th byte falls in the + * middle of a character, the last (partial) character is not counted. + * + * Return value: the length of the string in characters + **/ +glong +g_utf8_strlen (const gchar *p, + gssize max) +{ + glong len = 0; + const gchar *start = p; + g_return_val_if_fail (p != NULL || max == 0, 0); + + if (max < 0) + { + while (*p) + { + p = g_utf8_next_char (p); + ++len; + } + } + else + { + if (max == 0 || !*p) + return 0; + + p = g_utf8_next_char (p); + + while (p - start < max && *p) + { + ++len; + p = g_utf8_next_char (p); + } + + /* only do the last len increment if we got a complete + * char (don't count partial chars) + */ + if (p - start <= max) + ++len; + } + + return len; +} + +/** + * g_utf8_substring: + * @str: a UTF-8 encoded string + * @start_pos: a character offset within @str + * @end_pos: another character offset within @str + * + * Copies a substring out of a UTF-8 encoded string. + * The substring will contain @end_pos - @start_pos + * characters. + * + * Returns: a newly allocated copy of the requested + * substring. Free with g_free() when no longer needed. + * + * Since: 2.30 + */ +gchar * +g_utf8_substring (const gchar *str, + glong start_pos, + glong end_pos) +{ + gchar *start, *end, *out; + + start = g_utf8_offset_to_pointer (str, start_pos); + end = g_utf8_offset_to_pointer (start, end_pos - start_pos); + + out = g_malloc (end - start + 1); + memcpy (out, start, end - start); + out[end - start] = 0; + + return out; +} + +/** + * g_utf8_get_char: + * @p: a pointer to Unicode character encoded as UTF-8 + * + * Converts a sequence of bytes encoded as UTF-8 to a Unicode character. + * If @p does not point to a valid UTF-8 encoded character, results are + * undefined. If you are not sure that the bytes are complete + * valid Unicode characters, you should use g_utf8_get_char_validated() + * instead. + * + * Return value: the resulting character + **/ +gunichar +g_utf8_get_char (const gchar *p) +{ + int i, mask = 0, len; + gunichar result; + unsigned char c = (unsigned char) *p; + + UTF8_COMPUTE (c, mask, len); + if (len == -1) + return (gunichar)-1; + UTF8_GET (result, p, i, mask, len); + + return result; +} + +/** + * g_utf8_offset_to_pointer: + * @str: a UTF-8 encoded string + * @offset: a character offset within @str + * + * Converts from an integer character offset to a pointer to a position + * within the string. + * + * Since 2.10, this function allows to pass a negative @offset to + * step backwards. It is usually worth stepping backwards from the end + * instead of forwards if @offset is in the last fourth of the string, + * since moving forward is about 3 times faster than moving backward. + * + * + * This function doesn't abort when reaching the end of @str. Therefore + * you should be sure that @offset is within string boundaries before + * calling that function. Call g_utf8_strlen() when unsure. + * + * This limitation exists as this function is called frequently during + * text rendering and therefore has to be as fast as possible. + * + * + * Return value: the resulting pointer + **/ +gchar * +g_utf8_offset_to_pointer (const gchar *str, + glong offset) +{ + const gchar *s = str; + + if (offset > 0) + while (offset--) + s = g_utf8_next_char (s); + else + { + const char *s1; + + /* This nice technique for fast backwards stepping + * through a UTF-8 string was dubbed "stutter stepping" + * by its inventor, Larry Ewing. + */ + while (offset) + { + s1 = s; + s += offset; + while ((*s & 0xc0) == 0x80) + s--; + + offset += g_utf8_pointer_to_offset (s, s1); + } + } + + return (gchar *)s; +} + +/** + * g_utf8_pointer_to_offset: + * @str: a UTF-8 encoded string + * @pos: a pointer to a position within @str + * + * Converts from a pointer to position within a string to a integer + * character offset. + * + * Since 2.10, this function allows @pos to be before @str, and returns + * a negative offset in this case. + * + * Return value: the resulting character offset + **/ +glong +g_utf8_pointer_to_offset (const gchar *str, + const gchar *pos) +{ + const gchar *s = str; + glong offset = 0; + + if (pos < str) + offset = - g_utf8_pointer_to_offset (pos, str); + else + while (s < pos) + { + s = g_utf8_next_char (s); + offset++; + } + + return offset; +} + + +/** + * g_utf8_strncpy: + * @dest: buffer to fill with characters from @src + * @src: UTF-8 encoded string + * @n: character count + * + * Like the standard C strncpy() function, but + * copies a given number of characters instead of a given number of + * bytes. The @src string must be valid UTF-8 encoded text. + * (Use g_utf8_validate() on all text before trying to use UTF-8 + * utility functions with it.) + * + * Return value: @dest + **/ +gchar * +g_utf8_strncpy (gchar *dest, + const gchar *src, + gsize n) +{ + const gchar *s = src; + while (n && *s) + { + s = g_utf8_next_char(s); + n--; + } + strncpy(dest, src, s - src); + dest[s - src] = 0; + return dest; +} + +/* unicode_strchr */ + +/** + * g_unichar_to_utf8: + * @c: a Unicode character code + * @outbuf: output buffer, must have at least 6 bytes of space. + * If %NULL, the length will be computed and returned + * and nothing will be written to @outbuf. + * + * Converts a single character to UTF-8. + * + * Return value: number of bytes written + **/ +int +g_unichar_to_utf8 (gunichar c, + gchar *outbuf) +{ + /* If this gets modified, also update the copy in g_string_insert_unichar() */ + guint len = 0; + int first; + int i; + + if (c < 0x80) + { + first = 0; + len = 1; + } + else if (c < 0x800) + { + first = 0xc0; + len = 2; + } + else if (c < 0x10000) + { + first = 0xe0; + len = 3; + } + else if (c < 0x200000) + { + first = 0xf0; + len = 4; + } + else if (c < 0x4000000) + { + first = 0xf8; + len = 5; + } + else + { + first = 0xfc; + len = 6; + } + + if (outbuf) + { + for (i = len - 1; i > 0; --i) + { + outbuf[i] = (c & 0x3f) | 0x80; + c >>= 6; + } + outbuf[0] = c | first; + } + + return len; +} + +/** + * g_utf8_strchr: + * @p: a nul-terminated UTF-8 encoded string + * @len: the maximum length of @p + * @c: a Unicode character + * + * Finds the leftmost occurrence of the given Unicode character + * in a UTF-8 encoded string, while limiting the search to @len bytes. + * If @len is -1, allow unbounded search. + * + * Return value: %NULL if the string does not contain the character, + * otherwise, a pointer to the start of the leftmost occurrence of + * the character in the string. + **/ +gchar * +g_utf8_strchr (const char *p, + gssize len, + gunichar c) +{ + gchar ch[10]; + + gint charlen = g_unichar_to_utf8 (c, ch); + ch[charlen] = '\0'; + + return g_strstr_len (p, len, ch); +} + + +/** + * g_utf8_strrchr: + * @p: a nul-terminated UTF-8 encoded string + * @len: the maximum length of @p + * @c: a Unicode character + * + * Find the rightmost occurrence of the given Unicode character + * in a UTF-8 encoded string, while limiting the search to @len bytes. + * If @len is -1, allow unbounded search. + * + * Return value: %NULL if the string does not contain the character, + * otherwise, a pointer to the start of the rightmost occurrence of the + * character in the string. + **/ +gchar * +g_utf8_strrchr (const char *p, + gssize len, + gunichar c) +{ + gchar ch[10]; + + gint charlen = g_unichar_to_utf8 (c, ch); + ch[charlen] = '\0'; + + return g_strrstr_len (p, len, ch); +} + + +/* Like g_utf8_get_char, but take a maximum length + * and return (gunichar)-2 on incomplete trailing character; + * also check for malformed or overlong sequences + * and return (gunichar)-1 in this case. + */ +static inline gunichar +g_utf8_get_char_extended (const gchar *p, + gssize max_len) +{ + guint i, len; + gunichar min_code; + gunichar wc = (guchar) *p; + + if (wc < 0x80) + { + return wc; + } + else if (G_UNLIKELY (wc < 0xc0)) + { + return (gunichar)-1; + } + else if (wc < 0xe0) + { + len = 2; + wc &= 0x1f; + min_code = 1 << 7; + } + else if (wc < 0xf0) + { + len = 3; + wc &= 0x0f; + min_code = 1 << 11; + } + else if (wc < 0xf8) + { + len = 4; + wc &= 0x07; + min_code = 1 << 16; + } + else if (wc < 0xfc) + { + len = 5; + wc &= 0x03; + min_code = 1 << 21; + } + else if (wc < 0xfe) + { + len = 6; + wc &= 0x01; + min_code = 1 << 26; + } + else + { + return (gunichar)-1; + } + + if (G_UNLIKELY (max_len >= 0 && len > max_len)) + { + for (i = 1; i < max_len; i++) + { + if ((((guchar *)p)[i] & 0xc0) != 0x80) + return (gunichar)-1; + } + return (gunichar)-2; + } + + for (i = 1; i < len; ++i) + { + gunichar ch = ((guchar *)p)[i]; + + if (G_UNLIKELY ((ch & 0xc0) != 0x80)) + { + if (ch) + return (gunichar)-1; + else + return (gunichar)-2; + } + + wc <<= 6; + wc |= (ch & 0x3f); + } + + if (G_UNLIKELY (wc < min_code)) + return (gunichar)-1; + + return wc; +} + +/** + * g_utf8_get_char_validated: + * @p: a pointer to Unicode character encoded as UTF-8 + * @max_len: the maximum number of bytes to read, or -1, for no maximum or + * if @p is nul-terminated + * + * Convert a sequence of bytes encoded as UTF-8 to a Unicode character. + * This function checks for incomplete characters, for invalid characters + * such as characters that are out of the range of Unicode, and for + * overlong encodings of valid characters. + * + * Return value: the resulting character. If @p points to a partial + * sequence at the end of a string that could begin a valid + * character (or if @max_len is zero), returns (gunichar)-2; + * otherwise, if @p does not point to a valid UTF-8 encoded + * Unicode character, returns (gunichar)-1. + **/ +gunichar +g_utf8_get_char_validated (const gchar *p, + gssize max_len) +{ + gunichar result; + + if (max_len == 0) + return (gunichar)-2; + + result = g_utf8_get_char_extended (p, max_len); + + if (result & 0x80000000) + return result; + else if (!UNICODE_VALID (result)) + return (gunichar)-1; + else + return result; +} + +/** + * g_utf8_to_ucs4_fast: + * @str: a UTF-8 encoded string + * @len: the maximum length of @str to use, in bytes. If @len < 0, + * then the string is nul-terminated. + * @items_written: location to store the number of characters in the + * result, or %NULL. + * + * Convert a string from UTF-8 to a 32-bit fixed width + * representation as UCS-4, assuming valid UTF-8 input. + * This function is roughly twice as fast as g_utf8_to_ucs4() + * but does no error checking on the input. A trailing 0 character + * will be added to the string after the converted text. + * + * Return value: a pointer to a newly allocated UCS-4 string. + * This value must be freed with g_free(). + **/ +gunichar * +g_utf8_to_ucs4_fast (const gchar *str, + glong len, + glong *items_written) +{ + gunichar *result; + gint n_chars, i; + const gchar *p; + + g_return_val_if_fail (str != NULL, NULL); + + p = str; + n_chars = 0; + if (len < 0) + { + while (*p) + { + p = g_utf8_next_char (p); + ++n_chars; + } + } + else + { + while (p < str + len && *p) + { + p = g_utf8_next_char (p); + ++n_chars; + } + } + + result = g_new (gunichar, n_chars + 1); + + p = str; + for (i=0; i < n_chars; i++) + { + gunichar wc = (guchar)*p++; + + if (wc < 0x80) + { + result[i] = wc; + } + else + { + gunichar mask = 0x40; + + if (G_UNLIKELY ((wc & mask) == 0)) + { + /* It's an out-of-sequence 10xxxxxxx byte. + * Rather than making an ugly hash of this and the next byte + * and overrunning the buffer, it's more useful to treat it + * with a replacement character */ + result[i] = 0xfffd; + continue; + } + + do + { + wc <<= 6; + wc |= (guchar)(*p++) & 0x3f; + mask <<= 5; + } + while((wc & mask) != 0); + + wc &= mask - 1; + + result[i] = wc; + } + } + result[i] = 0; + + if (items_written) + *items_written = i; + + return result; +} + +/** + * g_utf8_to_ucs4: + * @str: a UTF-8 encoded string + * @len: the maximum length of @str to use, in bytes. If @len < 0, + * then the string is nul-terminated. + * @items_read: location to store number of bytes read, or %NULL. + * If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be + * returned in case @str contains a trailing partial + * character. If an error occurs then the index of the + * invalid input is stored here. + * @items_written: location to store number of characters written or %NULL. + * The value here stored does not include the trailing 0 + * character. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError other than + * %G_CONVERT_ERROR_NO_CONVERSION may occur. + * + * Convert a string from UTF-8 to a 32-bit fixed width + * representation as UCS-4. A trailing 0 character will be added to the + * string after the converted text. + * + * Return value: a pointer to a newly allocated UCS-4 string. + * This value must be freed with g_free(). If an + * error occurs, %NULL will be returned and + * @error set. + **/ +gunichar * +g_utf8_to_ucs4 (const gchar *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) +{ + gunichar *result = NULL; + gint n_chars, i; + const gchar *in; + + in = str; + n_chars = 0; + while ((len < 0 || str + len - in > 0) && *in) + { + gunichar wc = g_utf8_get_char_extended (in, len < 0 ? 6 : str + len - in); + if (wc & 0x80000000) + { + if (wc == (gunichar)-2) + { + if (items_read) + break; + else + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + _("Partial character sequence at end of input")); + } + else + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + + goto err_out; + } + + n_chars++; + + in = g_utf8_next_char (in); + } + + result = g_new (gunichar, n_chars + 1); + + in = str; + for (i=0; i < n_chars; i++) + { + result[i] = g_utf8_get_char (in); + in = g_utf8_next_char (in); + } + result[i] = 0; + + if (items_written) + *items_written = n_chars; + + err_out: + if (items_read) + *items_read = in - str; + + return result; +} + +/** + * g_ucs4_to_utf8: + * @str: a UCS-4 encoded string + * @len: the maximum length (number of characters) of @str to use. + * If @len < 0, then the string is nul-terminated. + * @items_read: location to store number of characters read, or %NULL. + * @items_written: location to store number of bytes written or %NULL. + * The value here stored does not include the trailing 0 + * byte. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError other than + * %G_CONVERT_ERROR_NO_CONVERSION may occur. + * + * Convert a string from a 32-bit fixed width representation as UCS-4. + * to UTF-8. The result will be terminated with a 0 byte. + * + * Return value: a pointer to a newly allocated UTF-8 string. + * This value must be freed with g_free(). If an + * error occurs, %NULL will be returned and + * @error set. In that case, @items_read will be + * set to the position of the first invalid input + * character. + **/ +gchar * +g_ucs4_to_utf8 (const gunichar *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) +{ + gint result_length; + gchar *result = NULL; + gchar *p; + gint i; + + result_length = 0; + for (i = 0; len < 0 || i < len ; i++) + { + if (!str[i]) + break; + + if (str[i] >= 0x80000000) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Character out of range for UTF-8")); + goto err_out; + } + + result_length += UTF8_LENGTH (str[i]); + } + + result = g_malloc (result_length + 1); + p = result; + + i = 0; + while (p < result + result_length) + p += g_unichar_to_utf8 (str[i++], p); + + *p = '\0'; + + if (items_written) + *items_written = p - result; + + err_out: + if (items_read) + *items_read = i; + + return result; +} + +#define SURROGATE_VALUE(h,l) (((h) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000) + +/** + * g_utf16_to_utf8: + * @str: a UTF-16 encoded string + * @len: the maximum length (number of gunichar2) of @str to use. + * If @len < 0, then the string is nul-terminated. + * @items_read: location to store number of words read, or %NULL. + * If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be + * returned in case @str contains a trailing partial + * character. If an error occurs then the index of the + * invalid input is stored here. + * @items_written: location to store number of bytes written, or %NULL. + * The value stored here does not include the trailing + * 0 byte. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError other than + * %G_CONVERT_ERROR_NO_CONVERSION may occur. + * + * Convert a string from UTF-16 to UTF-8. The result will be + * terminated with a 0 byte. + * + * Note that the input is expected to be already in native endianness, + * an initial byte-order-mark character is not handled specially. + * g_convert() can be used to convert a byte buffer of UTF-16 data of + * ambiguous endianess. + * + * Further note that this function does not validate the result + * string; it may e.g. include embedded NUL characters. The only + * validation done by this function is to ensure that the input can + * be correctly interpreted as UTF-16, i.e. it doesn't contain + * things unpaired surrogates. + * + * Return value: a pointer to a newly allocated UTF-8 string. + * This value must be freed with g_free(). If an + * error occurs, %NULL will be returned and + * @error set. + **/ +gchar * +g_utf16_to_utf8 (const gunichar2 *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) +{ + /* This function and g_utf16_to_ucs4 are almost exactly identical - The lines that differ + * are marked. + */ + const gunichar2 *in; + gchar *out; + gchar *result = NULL; + gint n_bytes; + gunichar high_surrogate; + + g_return_val_if_fail (str != NULL, NULL); + + n_bytes = 0; + in = str; + high_surrogate = 0; + while ((len < 0 || in - str < len) && *in) + { + gunichar2 c = *in; + gunichar wc; + + if (c >= 0xdc00 && c < 0xe000) /* low surrogate */ + { + if (high_surrogate) + { + wc = SURROGATE_VALUE (high_surrogate, c); + high_surrogate = 0; + } + else + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid sequence in conversion input")); + goto err_out; + } + } + else + { + if (high_surrogate) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid sequence in conversion input")); + goto err_out; + } + + if (c >= 0xd800 && c < 0xdc00) /* high surrogate */ + { + high_surrogate = c; + goto next1; + } + else + wc = c; + } + + /********** DIFFERENT for UTF8/UCS4 **********/ + n_bytes += UTF8_LENGTH (wc); + + next1: + in++; + } + + if (high_surrogate && !items_read) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + _("Partial character sequence at end of input")); + goto err_out; + } + + /* At this point, everything is valid, and we just need to convert + */ + /********** DIFFERENT for UTF8/UCS4 **********/ + result = g_malloc (n_bytes + 1); + + high_surrogate = 0; + out = result; + in = str; + while (out < result + n_bytes) + { + gunichar2 c = *in; + gunichar wc; + + if (c >= 0xdc00 && c < 0xe000) /* low surrogate */ + { + wc = SURROGATE_VALUE (high_surrogate, c); + high_surrogate = 0; + } + else if (c >= 0xd800 && c < 0xdc00) /* high surrogate */ + { + high_surrogate = c; + goto next2; + } + else + wc = c; + + /********** DIFFERENT for UTF8/UCS4 **********/ + out += g_unichar_to_utf8 (wc, out); + + next2: + in++; + } + + /********** DIFFERENT for UTF8/UCS4 **********/ + *out = '\0'; + + if (items_written) + /********** DIFFERENT for UTF8/UCS4 **********/ + *items_written = out - result; + + err_out: + if (items_read) + *items_read = in - str; + + return result; +} + +/** + * g_utf16_to_ucs4: + * @str: a UTF-16 encoded string + * @len: the maximum length (number of gunichar2) of @str to use. + * If @len < 0, then the string is nul-terminated. + * @items_read: location to store number of words read, or %NULL. + * If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be + * returned in case @str contains a trailing partial + * character. If an error occurs then the index of the + * invalid input is stored here. + * @items_written: location to store number of characters written, or %NULL. + * The value stored here does not include the trailing + * 0 character. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError other than + * %G_CONVERT_ERROR_NO_CONVERSION may occur. + * + * Convert a string from UTF-16 to UCS-4. The result will be + * nul-terminated. + * + * Return value: a pointer to a newly allocated UCS-4 string. + * This value must be freed with g_free(). If an + * error occurs, %NULL will be returned and + * @error set. + **/ +gunichar * +g_utf16_to_ucs4 (const gunichar2 *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) +{ + const gunichar2 *in; + gchar *out; + gchar *result = NULL; + gint n_bytes; + gunichar high_surrogate; + + g_return_val_if_fail (str != NULL, NULL); + + n_bytes = 0; + in = str; + high_surrogate = 0; + while ((len < 0 || in - str < len) && *in) + { + gunichar2 c = *in; + + if (c >= 0xdc00 && c < 0xe000) /* low surrogate */ + { + if (high_surrogate) + { + high_surrogate = 0; + } + else + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid sequence in conversion input")); + goto err_out; + } + } + else + { + if (high_surrogate) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid sequence in conversion input")); + goto err_out; + } + + if (c >= 0xd800 && c < 0xdc00) /* high surrogate */ + { + high_surrogate = c; + goto next1; + } + } + + /********** DIFFERENT for UTF8/UCS4 **********/ + n_bytes += sizeof (gunichar); + + next1: + in++; + } + + if (high_surrogate && !items_read) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + _("Partial character sequence at end of input")); + goto err_out; + } + + /* At this point, everything is valid, and we just need to convert + */ + /********** DIFFERENT for UTF8/UCS4 **********/ + result = g_malloc (n_bytes + 4); + + high_surrogate = 0; + out = result; + in = str; + while (out < result + n_bytes) + { + gunichar2 c = *in; + gunichar wc; + + if (c >= 0xdc00 && c < 0xe000) /* low surrogate */ + { + wc = SURROGATE_VALUE (high_surrogate, c); + high_surrogate = 0; + } + else if (c >= 0xd800 && c < 0xdc00) /* high surrogate */ + { + high_surrogate = c; + goto next2; + } + else + wc = c; + + /********** DIFFERENT for UTF8/UCS4 **********/ + *(gunichar *)out = wc; + out += sizeof (gunichar); + + next2: + in++; + } + + /********** DIFFERENT for UTF8/UCS4 **********/ + *(gunichar *)out = 0; + + if (items_written) + /********** DIFFERENT for UTF8/UCS4 **********/ + *items_written = (out - result) / sizeof (gunichar); + + err_out: + if (items_read) + *items_read = in - str; + + return (gunichar *)result; +} + +/** + * g_utf8_to_utf16: + * @str: a UTF-8 encoded string + * @len: the maximum length (number of bytes) of @str to use. + * If @len < 0, then the string is nul-terminated. + * @items_read: location to store number of bytes read, or %NULL. + * If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be + * returned in case @str contains a trailing partial + * character. If an error occurs then the index of the + * invalid input is stored here. + * @items_written: location to store number of gunichar2 written, + * or %NULL. + * The value stored here does not include the trailing 0. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError other than + * %G_CONVERT_ERROR_NO_CONVERSION may occur. + * + * Convert a string from UTF-8 to UTF-16. A 0 character will be + * added to the result after the converted text. + * + * Return value: a pointer to a newly allocated UTF-16 string. + * This value must be freed with g_free(). If an + * error occurs, %NULL will be returned and + * @error set. + **/ +gunichar2 * +g_utf8_to_utf16 (const gchar *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) +{ + gunichar2 *result = NULL; + gint n16; + const gchar *in; + gint i; + + g_return_val_if_fail (str != NULL, NULL); + + in = str; + n16 = 0; + while ((len < 0 || str + len - in > 0) && *in) + { + gunichar wc = g_utf8_get_char_extended (in, len < 0 ? 6 : str + len - in); + if (wc & 0x80000000) + { + if (wc == (gunichar)-2) + { + if (items_read) + break; + else + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT, + _("Partial character sequence at end of input")); + } + else + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid byte sequence in conversion input")); + + goto err_out; + } + + if (wc < 0xd800) + n16 += 1; + else if (wc < 0xe000) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid sequence in conversion input")); + + goto err_out; + } + else if (wc < 0x10000) + n16 += 1; + else if (wc < 0x110000) + n16 += 2; + else + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Character out of range for UTF-16")); + + goto err_out; + } + + in = g_utf8_next_char (in); + } + + result = g_new (gunichar2, n16 + 1); + + in = str; + for (i = 0; i < n16;) + { + gunichar wc = g_utf8_get_char (in); + + if (wc < 0x10000) + { + result[i++] = wc; + } + else + { + result[i++] = (wc - 0x10000) / 0x400 + 0xd800; + result[i++] = (wc - 0x10000) % 0x400 + 0xdc00; + } + + in = g_utf8_next_char (in); + } + + result[i] = 0; + + if (items_written) + *items_written = n16; + + err_out: + if (items_read) + *items_read = in - str; + + return result; +} + +/** + * g_ucs4_to_utf16: + * @str: a UCS-4 encoded string + * @len: the maximum length (number of characters) of @str to use. + * If @len < 0, then the string is nul-terminated. + * @items_read: location to store number of bytes read, or %NULL. + * If an error occurs then the index of the invalid input + * is stored here. + * @items_written: location to store number of gunichar2 + * written, or %NULL. The value stored here does not + * include the trailing 0. + * @error: location to store the error occurring, or %NULL to ignore + * errors. Any of the errors in #GConvertError other than + * %G_CONVERT_ERROR_NO_CONVERSION may occur. + * + * Convert a string from UCS-4 to UTF-16. A 0 character will be + * added to the result after the converted text. + * + * Return value: a pointer to a newly allocated UTF-16 string. + * This value must be freed with g_free(). If an + * error occurs, %NULL will be returned and + * @error set. + **/ +gunichar2 * +g_ucs4_to_utf16 (const gunichar *str, + glong len, + glong *items_read, + glong *items_written, + GError **error) +{ + gunichar2 *result = NULL; + gint n16; + gint i, j; + + n16 = 0; + i = 0; + while ((len < 0 || i < len) && str[i]) + { + gunichar wc = str[i]; + + if (wc < 0xd800) + n16 += 1; + else if (wc < 0xe000) + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Invalid sequence in conversion input")); + + goto err_out; + } + else if (wc < 0x10000) + n16 += 1; + else if (wc < 0x110000) + n16 += 2; + else + { + g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE, + _("Character out of range for UTF-16")); + + goto err_out; + } + + i++; + } + + result = g_new (gunichar2, n16 + 1); + + for (i = 0, j = 0; j < n16; i++) + { + gunichar wc = str[i]; + + if (wc < 0x10000) + { + result[j++] = wc; + } + else + { + result[j++] = (wc - 0x10000) / 0x400 + 0xd800; + result[j++] = (wc - 0x10000) % 0x400 + 0xdc00; + } + } + result[j] = 0; + + if (items_written) + *items_written = n16; + + err_out: + if (items_read) + *items_read = i; + + return result; +} + +#define CONTINUATION_CHAR \ + G_STMT_START { \ + if ((*(guchar *)p & 0xc0) != 0x80) /* 10xxxxxx */ \ + goto error; \ + val <<= 6; \ + val |= (*(guchar *)p) & 0x3f; \ + } G_STMT_END + +static const gchar * +fast_validate (const char *str) + +{ + gunichar val = 0; + gunichar min = 0; + const gchar *p; + + for (p = str; *p; p++) + { + if (*(guchar *)p < 128) + /* done */; + else + { + const gchar *last; + + last = p; + if ((*(guchar *)p & 0xe0) == 0xc0) /* 110xxxxx */ + { + if (G_UNLIKELY ((*(guchar *)p & 0x1e) == 0)) + goto error; + p++; + if (G_UNLIKELY ((*(guchar *)p & 0xc0) != 0x80)) /* 10xxxxxx */ + goto error; + } + else + { + if ((*(guchar *)p & 0xf0) == 0xe0) /* 1110xxxx */ + { + min = (1 << 11); + val = *(guchar *)p & 0x0f; + goto TWO_REMAINING; + } + else if ((*(guchar *)p & 0xf8) == 0xf0) /* 11110xxx */ + { + min = (1 << 16); + val = *(guchar *)p & 0x07; + } + else + goto error; + + p++; + CONTINUATION_CHAR; + TWO_REMAINING: + p++; + CONTINUATION_CHAR; + p++; + CONTINUATION_CHAR; + + if (G_UNLIKELY (val < min)) + goto error; + + if (G_UNLIKELY (!UNICODE_VALID(val))) + goto error; + } + + continue; + + error: + return last; + } + } + + return p; +} + +static const gchar * +fast_validate_len (const char *str, + gssize max_len) + +{ + gunichar val = 0; + gunichar min = 0; + const gchar *p; + + g_assert (max_len >= 0); + + for (p = str; ((p - str) < max_len) && *p; p++) + { + if (*(guchar *)p < 128) + /* done */; + else + { + const gchar *last; + + last = p; + if ((*(guchar *)p & 0xe0) == 0xc0) /* 110xxxxx */ + { + if (G_UNLIKELY (max_len - (p - str) < 2)) + goto error; + + if (G_UNLIKELY ((*(guchar *)p & 0x1e) == 0)) + goto error; + p++; + if (G_UNLIKELY ((*(guchar *)p & 0xc0) != 0x80)) /* 10xxxxxx */ + goto error; + } + else + { + if ((*(guchar *)p & 0xf0) == 0xe0) /* 1110xxxx */ + { + if (G_UNLIKELY (max_len - (p - str) < 3)) + goto error; + + min = (1 << 11); + val = *(guchar *)p & 0x0f; + goto TWO_REMAINING; + } + else if ((*(guchar *)p & 0xf8) == 0xf0) /* 11110xxx */ + { + if (G_UNLIKELY (max_len - (p - str) < 4)) + goto error; + + min = (1 << 16); + val = *(guchar *)p & 0x07; + } + else + goto error; + + p++; + CONTINUATION_CHAR; + TWO_REMAINING: + p++; + CONTINUATION_CHAR; + p++; + CONTINUATION_CHAR; + + if (G_UNLIKELY (val < min)) + goto error; + if (G_UNLIKELY (!UNICODE_VALID(val))) + goto error; + } + + continue; + + error: + return last; + } + } + + return p; +} + +/** + * g_utf8_validate: + * @str: a pointer to character data + * @max_len: max bytes to validate, or -1 to go until NUL + * @end: (allow-none) (out): return location for end of valid data + * + * Validates UTF-8 encoded text. @str is the text to validate; + * if @str is nul-terminated, then @max_len can be -1, otherwise + * @max_len should be the number of bytes to validate. + * If @end is non-%NULL, then the end of the valid range + * will be stored there (i.e. the start of the first invalid + * character if some bytes were invalid, or the end of the text + * being validated otherwise). + * + * Note that g_utf8_validate() returns %FALSE if @max_len is + * positive and any of the @max_len bytes are NUL. + * + * Returns %TRUE if all of @str was valid. Many GLib and GTK+ + * routines require valid UTF-8 as input; + * so data read from a file or the network should be checked + * with g_utf8_validate() before doing anything else with it. + * + * Return value: %TRUE if the text was valid UTF-8 + **/ +gboolean +g_utf8_validate (const char *str, + gssize max_len, + const gchar **end) + +{ + const gchar *p; + + if (max_len < 0) + p = fast_validate (str); + else + p = fast_validate_len (str, max_len); + + if (end) + *end = p; + + if ((max_len >= 0 && p != str + max_len) || + (max_len < 0 && *p != '\0')) + return FALSE; + else + return TRUE; +} + +/** + * g_unichar_validate: + * @ch: a Unicode character + * + * Checks whether @ch is a valid Unicode character. Some possible + * integer values of @ch will not be valid. 0 is considered a valid + * character, though it's normally a string terminator. + * + * Return value: %TRUE if @ch is a valid Unicode character + **/ +gboolean +g_unichar_validate (gunichar ch) +{ + return UNICODE_VALID (ch); +} + +/** + * g_utf8_strreverse: + * @str: a UTF-8 encoded string + * @len: the maximum length of @str to use, in bytes. If @len < 0, + * then the string is nul-terminated. + * + * Reverses a UTF-8 string. @str must be valid UTF-8 encoded text. + * (Use g_utf8_validate() on all text before trying to use UTF-8 + * utility functions with it.) + * + * This function is intended for programmatic uses of reversed strings. + * It pays no attention to decomposed characters, combining marks, byte + * order marks, directional indicators (LRM, LRO, etc) and similar + * characters which might need special handling when reversing a string + * for display purposes. + * + * Note that unlike g_strreverse(), this function returns + * newly-allocated memory, which should be freed with g_free() when + * no longer needed. + * + * Returns: a newly-allocated string which is the reverse of @str. + * + * Since: 2.2 + */ +gchar * +g_utf8_strreverse (const gchar *str, + gssize len) +{ + gchar *r, *result; + const gchar *p; + + if (len < 0) + len = strlen (str); + + result = g_new (gchar, len + 1); + r = result + len; + p = str; + while (r > result) + { + gchar *m, skip = g_utf8_skip[*(guchar*) p]; + r -= skip; + for (m = r; skip; skip--) + *m++ = *p++; + } + result[len] = 0; + + return result; +} + + +gchar * +_g_utf8_make_valid (const gchar *name) +{ + GString *string; + const gchar *remainder, *invalid; + gint remaining_bytes, valid_bytes; + + g_return_val_if_fail (name != NULL, NULL); + + string = NULL; + remainder = name; + remaining_bytes = strlen (name); + + while (remaining_bytes != 0) + { + if (g_utf8_validate (remainder, remaining_bytes, &invalid)) + break; + valid_bytes = invalid - remainder; + + if (string == NULL) + string = g_string_sized_new (remaining_bytes); + + g_string_append_len (string, remainder, valid_bytes); + /* append U+FFFD REPLACEMENT CHARACTER */ + g_string_append (string, "\357\277\275"); + + remaining_bytes -= valid_bytes + 1; + remainder = invalid + 1; + } + + if (string == NULL) + return g_strdup (name); + + g_string_append (string, remainder); + + g_assert (g_utf8_validate (string->str, -1, NULL)); + + return g_string_free (string, FALSE); +} diff --git a/glib/glib/gutils.c b/glib/glib/gutils.c new file mode 100644 index 0000000..4992ecc --- /dev/null +++ b/glib/glib/gutils.c @@ -0,0 +1,2393 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe for the unix part, FIXME: make the win32 part MT safe as well. + */ + +#include "config.h" + +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#include +#include /* For tolower() */ +#include +#include +#include +#ifdef HAVE_PWD_H +#include +#endif +#include +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#ifdef HAVE_CRT_EXTERNS_H +#include /* for _NSGetEnviron */ +#endif + +/* implement gutils's inline functions + */ +#define G_IMPLEMENT_INLINES 1 +#define __G_UTILS_C__ +#include "gutils.h" + +#include "glib-init.h" +#include "genviron.h" +#include "gfileutils.h" +#include "ggettext.h" +#include "ghash.h" +#include "gthread.h" +#include "gtestutils.h" +#include "gunicode.h" +#include "gstrfuncs.h" +#include "garray.h" +#include "glibintl.h" + +#ifdef G_PLATFORM_WIN32 +#include "gconvert.h" +#include "gwin32.h" +#endif + + +/** + * SECTION:misc_utils + * @title: Miscellaneous Utility Functions + * @short_description: a selection of portable utility functions + * + * These are portable utility functions. + */ + +#ifdef G_PLATFORM_WIN32 +# include +# ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS +# define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2 +# define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4 +# endif +# include /* For UNLEN */ +#endif /* G_PLATFORM_WIN32 */ + +#ifdef G_OS_WIN32 +# include +# include + /* older SDK (e.g. msvc 5.0) does not have these*/ +# ifndef CSIDL_MYMUSIC +# define CSIDL_MYMUSIC 13 +# endif +# ifndef CSIDL_MYVIDEO +# define CSIDL_MYVIDEO 14 +# endif +# ifndef CSIDL_INTERNET_CACHE +# define CSIDL_INTERNET_CACHE 32 +# endif +# ifndef CSIDL_COMMON_APPDATA +# define CSIDL_COMMON_APPDATA 35 +# endif +# ifndef CSIDL_MYPICTURES +# define CSIDL_MYPICTURES 0x27 +# endif +# ifndef CSIDL_COMMON_DOCUMENTS +# define CSIDL_COMMON_DOCUMENTS 46 +# endif +# ifndef CSIDL_PROFILE +# define CSIDL_PROFILE 40 +# endif +# include +#endif + +#ifdef HAVE_CARBON +#include +#endif + +#ifdef HAVE_CODESET +#include +#endif + +#ifdef G_PLATFORM_WIN32 + +gchar * +_glib_get_dll_directory (void) +{ + gchar *retval; + gchar *p; + wchar_t wc_fn[MAX_PATH]; + +#ifdef DLL_EXPORT + if (glib_dll == NULL) + return NULL; +#endif + + /* This code is different from that in + * g_win32_get_package_installation_directory_of_module() in that + * here we return the actual folder where the GLib DLL is. We don't + * do the check for it being in a "bin" or "lib" subfolder and then + * returning the parent of that. + * + * In a statically built GLib, glib_dll will be NULL and we will + * thus look up the application's .exe file's location. + */ + if (!GetModuleFileNameW (glib_dll, wc_fn, MAX_PATH)) + return NULL; + + retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL); + + p = strrchr (retval, G_DIR_SEPARATOR); + if (p == NULL) + { + /* Wtf? */ + return NULL; + } + *p = '\0'; + + return retval; +} + +#endif + +#if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY) +/** + * g_memmove: + * @dest: the destination address to copy the bytes to. + * @src: the source address to copy the bytes from. + * @len: the number of bytes to copy. + * + * Copies a block of memory @len bytes long, from @src to @dest. + * The source and destination areas may overlap. + * + * In order to use this function, you must include + * string.h yourself, because this macro will + * typically simply resolve to memmove() and GLib does not include + * string.h for you. + */ +void +g_memmove (gpointer dest, + gconstpointer src, + gulong len) +{ + gchar* destptr = dest; + const gchar* srcptr = src; + if (src + len < dest || dest + len < src) + { + bcopy (src, dest, len); + return; + } + else if (dest <= src) + { + while (len--) + *(destptr++) = *(srcptr++); + } + else + { + destptr += len; + srcptr += len; + while (len--) + *(--destptr) = *(--srcptr); + } +} +#endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */ + +#ifdef G_OS_WIN32 +#undef g_atexit +#endif + +/** + * g_atexit: + * @func: (scope async): the function to call on normal program termination. + * + * Specifies a function to be called at normal program termination. + * + * Since GLib 2.8.2, on Windows g_atexit() actually is a preprocessor + * macro that maps to a call to the atexit() function in the C + * library. This means that in case the code that calls g_atexit(), + * i.e. atexit(), is in a DLL, the function will be called when the + * DLL is detached from the program. This typically makes more sense + * than that the function is called when the GLib DLL is detached, + * which happened earlier when g_atexit() was a function in the GLib + * DLL. + * + * The behaviour of atexit() in the context of dynamically loaded + * modules is not formally specified and varies wildly. + * + * On POSIX systems, calling g_atexit() (or atexit()) in a dynamically + * loaded module which is unloaded before the program terminates might + * well cause a crash at program exit. + * + * Some POSIX systems implement atexit() like Windows, and have each + * dynamically loaded module maintain an own atexit chain that is + * called when the module is unloaded. + * + * On other POSIX systems, before a dynamically loaded module is + * unloaded, the registered atexit functions (if any) residing in that + * module are called, regardless where the code that registered them + * resided. This is presumably the most robust approach. + * + * As can be seen from the above, for portability it's best to avoid + * calling g_atexit() (or atexit()) except in the main executable of a + * program. + * + * Deprecated:2.32: It is best to avoid g_atexit(). + */ +void +g_atexit (GVoidFunc func) +{ + gint result; + const gchar *error = NULL; + + /* keep this in sync with glib.h */ + +#ifdef G_NATIVE_ATEXIT + result = ATEXIT (func); + if (result) + error = g_strerror (errno); +#elif defined (HAVE_ATEXIT) +# ifdef NeXT /* @#%@! NeXTStep */ + result = !atexit ((void (*)(void)) func); + if (result) + error = g_strerror (errno); +# else + result = atexit ((void (*)(void)) func); + if (result) + error = g_strerror (errno); +# endif /* NeXT */ +#elif defined (HAVE_ON_EXIT) + result = on_exit ((void (*)(int, void *)) func, NULL); + if (result) + error = g_strerror (errno); +#else + result = 0; + error = "no implementation"; +#endif /* G_NATIVE_ATEXIT */ + + if (error) + g_error ("Could not register atexit() function: %s", error); +} + +/* Based on execvp() from GNU Libc. + * Some of this code is cut-and-pasted into gspawn.c + */ + +static gchar* +my_strchrnul (const gchar *str, + gchar c) +{ + gchar *p = (gchar*)str; + while (*p && (*p != c)) + ++p; + + return p; +} + +#ifdef G_OS_WIN32 + +static gchar *inner_find_program_in_path (const gchar *program); + +gchar* +g_find_program_in_path (const gchar *program) +{ + const gchar *last_dot = strrchr (program, '.'); + + if (last_dot == NULL || + strchr (last_dot, '\\') != NULL || + strchr (last_dot, '/') != NULL) + { + const gint program_length = strlen (program); + gchar *pathext = g_build_path (";", + ".exe;.cmd;.bat;.com", + g_getenv ("PATHEXT"), + NULL); + gchar *p; + gchar *decorated_program; + gchar *retval; + + p = pathext; + do + { + gchar *q = my_strchrnul (p, ';'); + + decorated_program = g_malloc (program_length + (q-p) + 1); + memcpy (decorated_program, program, program_length); + memcpy (decorated_program+program_length, p, q-p); + decorated_program [program_length + (q-p)] = '\0'; + + retval = inner_find_program_in_path (decorated_program); + g_free (decorated_program); + + if (retval != NULL) + { + g_free (pathext); + return retval; + } + p = q; + } while (*p++ != '\0'); + g_free (pathext); + return NULL; + } + else + return inner_find_program_in_path (program); +} + +#endif + +/** + * g_find_program_in_path: + * @program: a program name in the GLib file name encoding + * + * Locates the first executable named @program in the user's path, in the + * same way that execvp() would locate it. Returns an allocated string + * with the absolute path name, or %NULL if the program is not found in + * the path. If @program is already an absolute path, returns a copy of + * @program if @program exists and is executable, and %NULL otherwise. + * + * On Windows, if @program does not have a file type suffix, tries + * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in + * the PATHEXT environment variable. + * + * On Windows, it looks for the file in the same way as CreateProcess() + * would. This means first in the directory where the executing + * program was loaded from, then in the current directory, then in the + * Windows 32-bit system directory, then in the Windows directory, and + * finally in the directories in the PATH environment + * variable. If the program is found, the return value contains the + * full name including the type suffix. + * + * Return value: absolute path, or %NULL + **/ +#ifdef G_OS_WIN32 +static gchar * +inner_find_program_in_path (const gchar *program) +#else +gchar* +g_find_program_in_path (const gchar *program) +#endif +{ + const gchar *path, *p; + gchar *name, *freeme; +#ifdef G_OS_WIN32 + const gchar *path_copy; + gchar *filename = NULL, *appdir = NULL; + gchar *sysdir = NULL, *windir = NULL; + int n; + wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN], + wwindir[MAXPATHLEN]; +#endif + gsize len; + gsize pathlen; + + g_return_val_if_fail (program != NULL, NULL); + + /* If it is an absolute path, or a relative path including subdirectories, + * don't look in PATH. + */ + if (g_path_is_absolute (program) + || strchr (program, G_DIR_SEPARATOR) != NULL +#ifdef G_OS_WIN32 + || strchr (program, '/') != NULL +#endif + ) + { + if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) && + !g_file_test (program, G_FILE_TEST_IS_DIR)) + return g_strdup (program); + else + return NULL; + } + + path = g_getenv ("PATH"); +#if defined(G_OS_UNIX) || defined(G_OS_BEOS) + if (path == NULL) + { + /* There is no `PATH' in the environment. The default + * search path in GNU libc is the current directory followed by + * the path `confstr' returns for `_CS_PATH'. + */ + + /* In GLib we put . last, for security, and don't use the + * unportable confstr(); UNIX98 does not actually specify + * what to search if PATH is unset. POSIX may, dunno. + */ + + path = "/bin:/usr/bin:."; + } +#else + n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN); + if (n > 0 && n < MAXPATHLEN) + filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL); + + n = GetSystemDirectoryW (wsysdir, MAXPATHLEN); + if (n > 0 && n < MAXPATHLEN) + sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL); + + n = GetWindowsDirectoryW (wwindir, MAXPATHLEN); + if (n > 0 && n < MAXPATHLEN) + windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL); + + if (filename) + { + appdir = g_path_get_dirname (filename); + g_free (filename); + } + + path = g_strdup (path); + + if (windir) + { + const gchar *tem = path; + path = g_strconcat (windir, ";", path, NULL); + g_free ((gchar *) tem); + g_free (windir); + } + + if (sysdir) + { + const gchar *tem = path; + path = g_strconcat (sysdir, ";", path, NULL); + g_free ((gchar *) tem); + g_free (sysdir); + } + + { + const gchar *tem = path; + path = g_strconcat (".;", path, NULL); + g_free ((gchar *) tem); + } + + if (appdir) + { + const gchar *tem = path; + path = g_strconcat (appdir, ";", path, NULL); + g_free ((gchar *) tem); + g_free (appdir); + } + + path_copy = path; +#endif + + len = strlen (program) + 1; + pathlen = strlen (path); + freeme = name = g_malloc (pathlen + len + 1); + + /* Copy the file name at the top, including '\0' */ + memcpy (name + pathlen + 1, program, len); + name = name + pathlen; + /* And add the slash before the filename */ + *name = G_DIR_SEPARATOR; + + p = path; + do + { + char *startp; + + path = p; + p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR); + + if (p == path) + /* Two adjacent colons, or a colon at the beginning or the end + * of `PATH' means to search the current directory. + */ + startp = name + 1; + else + startp = memcpy (name - (p - path), path, p - path); + + if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) && + !g_file_test (startp, G_FILE_TEST_IS_DIR)) + { + gchar *ret; + ret = g_strdup (startp); + g_free (freeme); +#ifdef G_OS_WIN32 + g_free ((gchar *) path_copy); +#endif + return ret; + } + } + while (*p++ != '\0'); + + g_free (freeme); +#ifdef G_OS_WIN32 + g_free ((gchar *) path_copy); +#endif + + return NULL; +} + +/** + * g_bit_nth_lsf: + * @mask: a #gulong containing flags + * @nth_bit: the index of the bit to start the search from + * + * Find the position of the first bit set in @mask, searching + * from (but not including) @nth_bit upwards. Bits are numbered + * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63, + * usually). To start searching from the 0th bit, set @nth_bit to -1. + * + * Returns: the index of the first bit set which is higher than @nth_bit + */ + +/** + * g_bit_nth_msf: + * @mask: a #gulong containing flags + * @nth_bit: the index of the bit to start the search from + * + * Find the position of the first bit set in @mask, searching + * from (but not including) @nth_bit downwards. Bits are numbered + * from 0 (least significant) to sizeof(#gulong) * 8 - 1 (31 or 63, + * usually). To start searching from the last bit, set @nth_bit to + * -1 or GLIB_SIZEOF_LONG * 8. + * + * Returns: the index of the first bit set which is lower than @nth_bit + */ + +/** + * g_bit_storage: + * @number: a #guint + * + * Gets the number of bits used to hold @number, + * e.g. if @number is 4, 3 bits are needed. + * + * Returns: the number of bits used to hold @number + */ + +G_LOCK_DEFINE_STATIC (g_utils_global); + +static gchar *g_tmp_dir = NULL; +static gchar *g_user_name = NULL; +static gchar *g_real_name = NULL; +static gchar *g_home_dir = NULL; +static gchar *g_host_name = NULL; + +#ifdef G_OS_WIN32 +/* System codepage versions of the above, kept at file level so that they, + * too, are produced only once. + */ +static gchar *g_tmp_dir_cp = NULL; +static gchar *g_user_name_cp = NULL; +static gchar *g_real_name_cp = NULL; +static gchar *g_home_dir_cp = NULL; +#endif + +static gchar *g_user_data_dir = NULL; +static gchar **g_system_data_dirs = NULL; +static gchar *g_user_cache_dir = NULL; +static gchar *g_user_config_dir = NULL; +static gchar **g_system_config_dirs = NULL; + +static gchar **g_user_special_dirs = NULL; + +/* fifteen minutes of fame for everybody */ +#define G_USER_DIRS_EXPIRE 15 * 60 + +#ifdef G_OS_WIN32 + +static gchar * +get_special_folder (int csidl) +{ + wchar_t path[MAX_PATH+1]; + HRESULT hr; + LPITEMIDLIST pidl = NULL; + BOOL b; + gchar *retval = NULL; + + hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl); + if (hr == S_OK) + { + b = SHGetPathFromIDListW (pidl, path); + if (b) + retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL); + CoTaskMemFree (pidl); + } + return retval; +} + +static char * +get_windows_directory_root (void) +{ + wchar_t wwindowsdir[MAX_PATH]; + + if (GetWindowsDirectoryW (wwindowsdir, G_N_ELEMENTS (wwindowsdir))) + { + /* Usually X:\Windows, but in terminal server environments + * might be an UNC path, AFAIK. + */ + char *windowsdir = g_utf16_to_utf8 (wwindowsdir, -1, NULL, NULL, NULL); + char *p; + + if (windowsdir == NULL) + return g_strdup ("C:\\"); + + p = (char *) g_path_skip_root (windowsdir); + if (G_IS_DIR_SEPARATOR (p[-1]) && p[-2] != ':') + p--; + *p = '\0'; + return windowsdir; + } + else + return g_strdup ("C:\\"); +} + +#endif + +/* HOLDS: g_utils_global_lock */ +static void +g_get_any_init_do (void) +{ + gchar hostname[100]; + + g_tmp_dir = g_strdup (g_getenv ("TMPDIR")); + if (g_tmp_dir == NULL || *g_tmp_dir == '\0') + g_tmp_dir = g_strdup (g_getenv ("TMP")); + if (g_tmp_dir == NULL || *g_tmp_dir == '\0') + g_tmp_dir = g_strdup (g_getenv ("TEMP")); + +#ifdef G_OS_WIN32 + if (g_tmp_dir == NULL || *g_tmp_dir == '\0') + g_tmp_dir = get_windows_directory_root (); +#else +#ifdef P_tmpdir + if (g_tmp_dir == NULL || *g_tmp_dir == '\0') + { + gsize k; + g_tmp_dir = g_strdup (P_tmpdir); + k = strlen (g_tmp_dir); + if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1])) + g_tmp_dir[k - 1] = '\0'; + } +#endif + + if (g_tmp_dir == NULL || *g_tmp_dir == '\0') + { + g_tmp_dir = g_strdup ("/tmp"); + } +#endif /* !G_OS_WIN32 */ + +#ifdef G_OS_WIN32 + /* We check $HOME first for Win32, though it is a last resort for Unix + * where we prefer the results of getpwuid(). + */ + g_home_dir = g_strdup (g_getenv ("HOME")); + + /* Only believe HOME if it is an absolute path and exists */ + if (g_home_dir) + { + if (!(g_path_is_absolute (g_home_dir) && + g_file_test (g_home_dir, G_FILE_TEST_IS_DIR))) + { + g_free (g_home_dir); + g_home_dir = NULL; + } + } + + /* In case HOME is Unix-style (it happens), convert it to + * Windows style. + */ + if (g_home_dir) + { + gchar *p; + while ((p = strchr (g_home_dir, '/')) != NULL) + *p = '\\'; + } + + if (!g_home_dir) + { + /* USERPROFILE is probably the closest equivalent to $HOME? */ + if (g_getenv ("USERPROFILE") != NULL) + g_home_dir = g_strdup (g_getenv ("USERPROFILE")); + } + + if (!g_home_dir) + g_home_dir = get_special_folder (CSIDL_PROFILE); + + if (!g_home_dir) + g_home_dir = get_windows_directory_root (); +#endif /* G_OS_WIN32 */ + +#ifdef HAVE_PWD_H + { + struct passwd *pw = NULL; + gpointer buffer = NULL; + gint error; + gchar *logname; + +# if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R) + struct passwd pwd; +# ifdef _SC_GETPW_R_SIZE_MAX + /* This reurns the maximum length */ + glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX); + + if (bufsize < 0) + bufsize = 64; +# else /* _SC_GETPW_R_SIZE_MAX */ + glong bufsize = 64; +# endif /* _SC_GETPW_R_SIZE_MAX */ + + logname = (gchar *) g_getenv ("LOGNAME"); + + do + { + g_free (buffer); + /* we allocate 6 extra bytes to work around a bug in + * Mac OS < 10.3. See #156446 + */ + buffer = g_malloc (bufsize + 6); + errno = 0; + +# ifdef HAVE_POSIX_GETPWUID_R + if (logname) { + error = getpwnam_r (logname, &pwd, buffer, bufsize, &pw); + if (!pw || (pw->pw_uid != getuid ())) { + /* LOGNAME is lying, fall back to looking up the uid */ + error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw); + } + } else { + error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw); + } + error = error < 0 ? errno : error; +# else /* HAVE_NONPOSIX_GETPWUID_R */ + /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */ +# if defined(_AIX) || defined(__hpux) + error = getpwuid_r (getuid (), &pwd, buffer, bufsize); + pw = error == 0 ? &pwd : NULL; +# else /* !_AIX */ + if (logname) { + pw = getpwnam_r (logname, &pwd, buffer, bufsize); + if (!pw || (pw->pw_uid != getuid ())) { + /* LOGNAME is lying, fall back to looking up the uid */ + pw = getpwuid_r (getuid (), &pwd, buffer, bufsize); + } + } else { + pw = getpwuid_r (getuid (), &pwd, buffer, bufsize); + } + error = pw ? 0 : errno; +# endif /* !_AIX */ +# endif /* HAVE_NONPOSIX_GETPWUID_R */ + + if (!pw) + { + /* we bail out prematurely if the user id can't be found + * (should be pretty rare case actually), or if the buffer + * should be sufficiently big and lookups are still not + * successful. + */ + if (error == 0 || error == ENOENT) + { + g_warning ("getpwuid_r(): failed due to unknown user id (%lu)", + (gulong) getuid ()); + break; + } + if (bufsize > 32 * 1024) + { + g_warning ("getpwuid_r(): failed due to: %s.", + g_strerror (error)); + break; + } + + bufsize *= 2; + } + } + while (!pw); +# endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */ + + if (!pw) + { + setpwent (); + pw = getpwuid (getuid ()); + endpwent (); + } + if (pw) + { + g_user_name = g_strdup (pw->pw_name); + + if (pw->pw_gecos && *pw->pw_gecos != '\0') + { + gchar **gecos_fields; + gchar **name_parts; + + /* split the gecos field and substitute '&' */ + gecos_fields = g_strsplit (pw->pw_gecos, ",", 0); + name_parts = g_strsplit (gecos_fields[0], "&", 0); + pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]); + g_real_name = g_strjoinv (pw->pw_name, name_parts); + g_strfreev (gecos_fields); + g_strfreev (name_parts); + } + + if (!g_home_dir) + g_home_dir = g_strdup (pw->pw_dir); + } + g_free (buffer); + } + +#else /* !HAVE_PWD_H */ + +#ifdef G_OS_WIN32 + { + guint len = UNLEN+1; + wchar_t buffer[UNLEN+1]; + + if (GetUserNameW (buffer, (LPDWORD) &len)) + { + g_user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL); + g_real_name = g_strdup (g_user_name); + } + } +#endif /* G_OS_WIN32 */ + +#endif /* !HAVE_PWD_H */ + +#ifndef G_OS_WIN32 + if (!g_home_dir) + g_home_dir = g_strdup (g_getenv ("HOME")); +#endif + +#ifdef __EMX__ + /* change '\\' in %HOME% to '/' */ + g_strdelimit (g_home_dir, "\\",'/'); +#endif + if (!g_user_name) + g_user_name = g_strdup ("somebody"); + if (!g_real_name) + g_real_name = g_strdup ("Unknown"); + + { +#ifndef G_OS_WIN32 + gboolean hostname_fail = (gethostname (hostname, sizeof (hostname)) == -1); +#else + DWORD size = sizeof (hostname); + gboolean hostname_fail = (!GetComputerName (hostname, &size)); +#endif + g_host_name = g_strdup (hostname_fail ? "localhost" : hostname); + } + +#ifdef G_OS_WIN32 + g_tmp_dir_cp = g_locale_from_utf8 (g_tmp_dir, -1, NULL, NULL, NULL); + g_user_name_cp = g_locale_from_utf8 (g_user_name, -1, NULL, NULL, NULL); + g_real_name_cp = g_locale_from_utf8 (g_real_name, -1, NULL, NULL, NULL); + + if (!g_tmp_dir_cp) + g_tmp_dir_cp = g_strdup ("\\"); + if (!g_user_name_cp) + g_user_name_cp = g_strdup ("somebody"); + if (!g_real_name_cp) + g_real_name_cp = g_strdup ("Unknown"); + + /* home_dir might be NULL, unlike tmp_dir, user_name and + * real_name. + */ + if (g_home_dir) + g_home_dir_cp = g_locale_from_utf8 (g_home_dir, -1, NULL, NULL, NULL); + else + g_home_dir_cp = NULL; +#endif /* G_OS_WIN32 */ +} + +static inline void +g_get_any_init (void) +{ + if (!g_tmp_dir) + g_get_any_init_do (); +} + +static inline void +g_get_any_init_locked (void) +{ + G_LOCK (g_utils_global); + g_get_any_init (); + G_UNLOCK (g_utils_global); +} + + +/** + * g_get_user_name: + * + * Gets the user name of the current user. The encoding of the returned + * string is system-defined. On UNIX, it might be the preferred file name + * encoding, or something else, and there is no guarantee that it is even + * consistent on a machine. On Windows, it is always UTF-8. + * + * Returns: the user name of the current user. + */ +const gchar * +g_get_user_name (void) +{ + g_get_any_init_locked (); + return g_user_name; +} + +/** + * g_get_real_name: + * + * Gets the real name of the user. This usually comes from the user's entry + * in the passwd file. The encoding of the returned + * string is system-defined. (On Windows, it is, however, always UTF-8.) + * If the real user name cannot be determined, the string "Unknown" is + * returned. + * + * Returns: the user's real name. + */ +const gchar * +g_get_real_name (void) +{ + g_get_any_init_locked (); + return g_real_name; +} + +/** + * g_get_home_dir: + * + * Gets the current user's home directory as defined in the + * password database. + * + * Note that in contrast to traditional UNIX tools, this function + * prefers passwd entries over the HOME + * environment variable. + * + * One of the reasons for this decision is that applications in many + * cases need special handling to deal with the case where + * HOME is + * + * Not owned by the user + * Not writeable + * Not even readable + * + * Since applications are in general not written + * to deal with these situations it was considered better to make + * g_get_home_dir() not pay attention to HOME and to + * return the real home directory for the user. If applications + * want to pay attention to HOME, they can do: + * |[ + * const char *homedir = g_getenv ("HOME"); + * if (!homedir) + * homedir = g_get_home_dir (); + * ]| + * + * Returns: the current user's home directory + */ +const gchar * +g_get_home_dir (void) +{ + g_get_any_init_locked (); + return g_home_dir; +} + +/** + * g_get_tmp_dir: + * + * Gets the directory to use for temporary files. This is found from + * inspecting the environment variables TMPDIR, + * TMP, and TEMP in that order. If none + * of those are defined "/tmp" is returned on UNIX and "C:\" on Windows. + * The encoding of the returned string is system-defined. On Windows, + * it is always UTF-8. The return value is never %NULL or the empty string. + * + * Returns: the directory to use for temporary files. + */ +const gchar * +g_get_tmp_dir (void) +{ + g_get_any_init_locked (); + return g_tmp_dir; +} + +/** + * g_get_host_name: + * + * Return a name for the machine. + * + * The returned name is not necessarily a fully-qualified domain name, + * or even present in DNS or some other name service at all. It need + * not even be unique on your local network or site, but usually it + * is. Callers should not rely on the return value having any specific + * properties like uniqueness for security purposes. Even if the name + * of the machine is changed while an application is running, the + * return value from this function does not change. The returned + * string is owned by GLib and should not be modified or freed. If no + * name can be determined, a default fixed string "localhost" is + * returned. + * + * Returns: the host name of the machine. + * + * Since: 2.8 + */ +const gchar * +g_get_host_name (void) +{ + g_get_any_init_locked (); + return g_host_name; +} + +G_LOCK_DEFINE_STATIC (g_prgname); +static gchar *g_prgname = NULL; + +/** + * g_get_prgname: + * + * Gets the name of the program. This name should not + * be localized, contrast with g_get_application_name(). + * (If you are using GDK or GTK+ the program name is set in gdk_init(), + * which is called by gtk_init(). The program name is found by taking + * the last component of argv[0].) + * + * Returns: the name of the program. The returned string belongs + * to GLib and must not be modified or freed. + */ +gchar* +g_get_prgname (void) +{ + gchar* retval; + + G_LOCK (g_prgname); +#ifdef G_OS_WIN32 + if (g_prgname == NULL) + { + static gboolean beenhere = FALSE; + + if (!beenhere) + { + gchar *utf8_buf = NULL; + wchar_t buf[MAX_PATH+1]; + + beenhere = TRUE; + if (GetModuleFileNameW (GetModuleHandle (NULL), + buf, G_N_ELEMENTS (buf)) > 0) + utf8_buf = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL); + + if (utf8_buf) + { + g_prgname = g_path_get_basename (utf8_buf); + g_free (utf8_buf); + } + } + } +#endif + retval = g_prgname; + G_UNLOCK (g_prgname); + + return retval; +} + +/** + * g_set_prgname: + * @prgname: the name of the program. + * + * Sets the name of the program. This name should not + * be localized, contrast with g_set_application_name(). Note that for + * thread-safety reasons this function can only be called once. + */ +void +g_set_prgname (const gchar *prgname) +{ + G_LOCK (g_prgname); + g_free (g_prgname); + g_prgname = g_strdup (prgname); + G_UNLOCK (g_prgname); +} + +G_LOCK_DEFINE_STATIC (g_application_name); +static gchar *g_application_name = NULL; + +/** + * g_get_application_name: + * + * Gets a human-readable name for the application, as set by + * g_set_application_name(). This name should be localized if + * possible, and is intended for display to the user. Contrast with + * g_get_prgname(), which gets a non-localized name. If + * g_set_application_name() has not been called, returns the result of + * g_get_prgname() (which may be %NULL if g_set_prgname() has also not + * been called). + * + * Return value: human-readable application name. may return %NULL + * + * Since: 2.2 + **/ +const gchar * +g_get_application_name (void) +{ + gchar* retval; + + G_LOCK (g_application_name); + retval = g_application_name; + G_UNLOCK (g_application_name); + + if (retval == NULL) + return g_get_prgname (); + + return retval; +} + +/** + * g_set_application_name: + * @application_name: localized name of the application + * + * Sets a human-readable name for the application. This name should be + * localized if possible, and is intended for display to the user. + * Contrast with g_set_prgname(), which sets a non-localized name. + * g_set_prgname() will be called automatically by gtk_init(), + * but g_set_application_name() will not. + * + * Note that for thread safety reasons, this function can only + * be called once. + * + * The application name will be used in contexts such as error messages, + * or when displaying an application's name in the task list. + * + * Since: 2.2 + **/ +void +g_set_application_name (const gchar *application_name) +{ + gboolean already_set = FALSE; + + G_LOCK (g_application_name); + if (g_application_name) + already_set = TRUE; + else + g_application_name = g_strdup (application_name); + G_UNLOCK (g_application_name); + + if (already_set) + g_warning ("g_set_application_name() called multiple times"); +} + +/** + * g_get_user_data_dir: + * + * Returns a base directory in which to access application data such + * as icons that is customized for a particular user. + * + * On UNIX platforms this is determined using the mechanisms described in + * the + * XDG Base Directory Specification. + * In this case the directory retrieved will be XDG_DATA_HOME. + * + * On Windows this is the folder to use for local (as opposed to + * roaming) application data. See documentation for + * CSIDL_LOCAL_APPDATA. Note that on Windows it thus is the same as + * what g_get_user_config_dir() returns. + * + * Return value: a string owned by GLib that must not be modified + * or freed. + * Since: 2.6 + **/ +const gchar * +g_get_user_data_dir (void) +{ + gchar *data_dir; + + G_LOCK (g_utils_global); + + if (!g_user_data_dir) + { +#ifdef G_OS_WIN32 + data_dir = get_special_folder (CSIDL_LOCAL_APPDATA); +#else + data_dir = (gchar *) g_getenv ("XDG_DATA_HOME"); + + if (data_dir && data_dir[0]) + data_dir = g_strdup (data_dir); +#endif + if (!data_dir || !data_dir[0]) + { + g_get_any_init (); + + if (g_home_dir) + data_dir = g_build_filename (g_home_dir, ".local", + "share", NULL); + else + data_dir = g_build_filename (g_tmp_dir, g_user_name, ".local", + "share", NULL); + } + + g_user_data_dir = data_dir; + } + else + data_dir = g_user_data_dir; + + G_UNLOCK (g_utils_global); + + return data_dir; +} + +static void +g_init_user_config_dir (void) +{ + gchar *config_dir; + + if (!g_user_config_dir) + { +#ifdef G_OS_WIN32 + config_dir = get_special_folder (CSIDL_LOCAL_APPDATA); +#else + config_dir = (gchar *) g_getenv ("XDG_CONFIG_HOME"); + + if (config_dir && config_dir[0]) + config_dir = g_strdup (config_dir); +#endif + if (!config_dir || !config_dir[0]) + { + g_get_any_init (); + + if (g_home_dir) + config_dir = g_build_filename (g_home_dir, ".config", NULL); + else + config_dir = g_build_filename (g_tmp_dir, g_user_name, ".config", NULL); + } + + g_user_config_dir = config_dir; + } +} + +/** + * g_get_user_config_dir: + * + * Returns a base directory in which to store user-specific application + * configuration information such as user preferences and settings. + * + * On UNIX platforms this is determined using the mechanisms described in + * the + * XDG Base Directory Specification. + * In this case the directory retrieved will be XDG_CONFIG_HOME. + * + * On Windows this is the folder to use for local (as opposed to + * roaming) application data. See documentation for + * CSIDL_LOCAL_APPDATA. Note that on Windows it thus is the same as + * what g_get_user_data_dir() returns. + * + * Return value: a string owned by GLib that must not be modified + * or freed. + * Since: 2.6 + **/ +const gchar * +g_get_user_config_dir (void) +{ + G_LOCK (g_utils_global); + + g_init_user_config_dir (); + + G_UNLOCK (g_utils_global); + + return g_user_config_dir; +} + +/** + * g_get_user_cache_dir: + * + * Returns a base directory in which to store non-essential, cached + * data specific to particular user. + * + * On UNIX platforms this is determined using the mechanisms described in + * the + * XDG Base Directory Specification. + * In this case the directory retrieved will be XDG_CACHE_HOME. + * + * On Windows is the directory that serves as a common repository for + * temporary Internet files. A typical path is + * C:\Documents and Settings\username\Local Settings\Temporary Internet Files. + * See documentation for CSIDL_INTERNET_CACHE. + * + * Return value: a string owned by GLib that must not be modified + * or freed. + * Since: 2.6 + **/ +const gchar * +g_get_user_cache_dir (void) +{ + gchar *cache_dir; + + G_LOCK (g_utils_global); + + if (!g_user_cache_dir) + { +#ifdef G_OS_WIN32 + cache_dir = get_special_folder (CSIDL_INTERNET_CACHE); /* XXX correct? */ +#else + cache_dir = (gchar *) g_getenv ("XDG_CACHE_HOME"); + + if (cache_dir && cache_dir[0]) + cache_dir = g_strdup (cache_dir); +#endif + if (!cache_dir || !cache_dir[0]) + { + g_get_any_init (); + + if (g_home_dir) + cache_dir = g_build_filename (g_home_dir, ".cache", NULL); + else + cache_dir = g_build_filename (g_tmp_dir, g_user_name, ".cache", NULL); + } + g_user_cache_dir = cache_dir; + } + else + cache_dir = g_user_cache_dir; + + G_UNLOCK (g_utils_global); + + return cache_dir; +} + +/** + * g_get_user_runtime_dir: + * + * Returns a directory that is unique to the current user on the local + * system. + * + * On UNIX platforms this is determined using the mechanisms described in + * the + * XDG Base Directory Specification. This is the directory + * specified in the XDG_RUNTIME_DIR environment variable. + * In the case that this variable is not set, GLib will issue a warning + * message to stderr and return the value of g_get_user_cache_dir(). + * + * On Windows this is the folder to use for local (as opposed to + * roaming) application data. See documentation for + * CSIDL_LOCAL_APPDATA. Note that on Windows it thus is the same as + * what g_get_user_config_dir() returns. + * + * Returns: a string owned by GLib that must not be modified or freed. + * + * Since: 2.28 + **/ +const gchar * +g_get_user_runtime_dir (void) +{ +#ifndef G_OS_WIN32 + static const gchar *runtime_dir; + static gsize initialised; + + if (g_once_init_enter (&initialised)) + { + runtime_dir = g_strdup (getenv ("XDG_RUNTIME_DIR")); + + g_once_init_leave (&initialised, 1); + } + + if (runtime_dir) + return runtime_dir; + + /* Both fallback for UNIX and the default + * in Windows: use the user cache directory. + */ +#endif + + return g_get_user_cache_dir (); +} + +#ifdef HAVE_CARBON + +static gchar * +find_folder (OSType type) +{ + gchar *filename = NULL; + FSRef found; + + if (FSFindFolder (kUserDomain, type, kDontCreateFolder, &found) == noErr) + { + CFURLRef url = CFURLCreateFromFSRef (kCFAllocatorSystemDefault, &found); + + if (url) + { + CFStringRef path = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle); + + if (path) + { + filename = g_strdup (CFStringGetCStringPtr (path, kCFStringEncodingUTF8)); + + if (! filename) + { + filename = g_new0 (gchar, CFStringGetLength (path) * 3 + 1); + + CFStringGetCString (path, filename, + CFStringGetLength (path) * 3 + 1, + kCFStringEncodingUTF8); + } + + CFRelease (path); + } + + CFRelease (url); + } + } + + return filename; +} + +static void +load_user_special_dirs (void) +{ + g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = find_folder (kDesktopFolderType); + g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = find_folder (kDocumentsFolderType); + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = find_folder (kDesktopFolderType); /* XXX correct ? */ + g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = find_folder (kMusicDocumentsFolderType); + g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = find_folder (kPictureDocumentsFolderType); + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = NULL; + g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = NULL; + g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = find_folder (kMovieDocumentsFolderType); +} + +#endif /* HAVE_CARBON */ + +#if defined(G_OS_WIN32) +static void +load_user_special_dirs (void) +{ + typedef HRESULT (WINAPI *t_SHGetKnownFolderPath) (const GUID *rfid, + DWORD dwFlags, + HANDLE hToken, + PWSTR *ppszPath); + t_SHGetKnownFolderPath p_SHGetKnownFolderPath; + + static const GUID FOLDERID_Downloads = + { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } }; + static const GUID FOLDERID_Public = + { 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } }; + + wchar_t *wcp; + + p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandle ("shell32.dll"), + "SHGetKnownFolderPath"); + + g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY); + g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (CSIDL_PERSONAL); + + if (p_SHGetKnownFolderPath == NULL) + { + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); + } + else + { + wcp = NULL; + (*p_SHGetKnownFolderPath) (&FOLDERID_Downloads, 0, NULL, &wcp); + if (wcp) + { + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL); + if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL) + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); + CoTaskMemFree (wcp); + } + else + g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY); + } + + g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (CSIDL_MYMUSIC); + g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (CSIDL_MYPICTURES); + + if (p_SHGetKnownFolderPath == NULL) + { + /* XXX */ + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); + } + else + { + wcp = NULL; + (*p_SHGetKnownFolderPath) (&FOLDERID_Public, 0, NULL, &wcp); + if (wcp) + { + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL); + if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL) + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); + CoTaskMemFree (wcp); + } + else + g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS); + } + + g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (CSIDL_TEMPLATES); + g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (CSIDL_MYVIDEO); +} +#endif /* G_OS_WIN32 */ + +static void g_init_user_config_dir (void); + +#if defined(G_OS_UNIX) && !defined(HAVE_CARBON) + +/* adapted from xdg-user-dir-lookup.c + * + * Copyright (C) 2007 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation files + * (the "Software"), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +static void +load_user_special_dirs (void) +{ + gchar *config_file; + gchar *data; + gchar **lines; + gint n_lines, i; + + g_init_user_config_dir (); + config_file = g_build_filename (g_user_config_dir, + "user-dirs.dirs", + NULL); + + if (!g_file_get_contents (config_file, &data, NULL, NULL)) + { + g_free (config_file); + return; + } + + lines = g_strsplit (data, "\n", -1); + n_lines = g_strv_length (lines); + g_free (data); + + for (i = 0; i < n_lines; i++) + { + gchar *buffer = lines[i]; + gchar *d, *p; + gint len; + gboolean is_relative = FALSE; + GUserDirectory directory; + + /* Remove newline at end */ + len = strlen (buffer); + if (len > 0 && buffer[len - 1] == '\n') + buffer[len - 1] = 0; + + p = buffer; + while (*p == ' ' || *p == '\t') + p++; + + if (strncmp (p, "XDG_DESKTOP_DIR", strlen ("XDG_DESKTOP_DIR")) == 0) + { + directory = G_USER_DIRECTORY_DESKTOP; + p += strlen ("XDG_DESKTOP_DIR"); + } + else if (strncmp (p, "XDG_DOCUMENTS_DIR", strlen ("XDG_DOCUMENTS_DIR")) == 0) + { + directory = G_USER_DIRECTORY_DOCUMENTS; + p += strlen ("XDG_DOCUMENTS_DIR"); + } + else if (strncmp (p, "XDG_DOWNLOAD_DIR", strlen ("XDG_DOWNLOAD_DIR")) == 0) + { + directory = G_USER_DIRECTORY_DOWNLOAD; + p += strlen ("XDG_DOWNLOAD_DIR"); + } + else if (strncmp (p, "XDG_MUSIC_DIR", strlen ("XDG_MUSIC_DIR")) == 0) + { + directory = G_USER_DIRECTORY_MUSIC; + p += strlen ("XDG_MUSIC_DIR"); + } + else if (strncmp (p, "XDG_PICTURES_DIR", strlen ("XDG_PICTURES_DIR")) == 0) + { + directory = G_USER_DIRECTORY_PICTURES; + p += strlen ("XDG_PICTURES_DIR"); + } + else if (strncmp (p, "XDG_PUBLICSHARE_DIR", strlen ("XDG_PUBLICSHARE_DIR")) == 0) + { + directory = G_USER_DIRECTORY_PUBLIC_SHARE; + p += strlen ("XDG_PUBLICSHARE_DIR"); + } + else if (strncmp (p, "XDG_TEMPLATES_DIR", strlen ("XDG_TEMPLATES_DIR")) == 0) + { + directory = G_USER_DIRECTORY_TEMPLATES; + p += strlen ("XDG_TEMPLATES_DIR"); + } + else if (strncmp (p, "XDG_VIDEOS_DIR", strlen ("XDG_VIDEOS_DIR")) == 0) + { + directory = G_USER_DIRECTORY_VIDEOS; + p += strlen ("XDG_VIDEOS_DIR"); + } + else + continue; + + while (*p == ' ' || *p == '\t') + p++; + + if (*p != '=') + continue; + p++; + + while (*p == ' ' || *p == '\t') + p++; + + if (*p != '"') + continue; + p++; + + if (strncmp (p, "$HOME", 5) == 0) + { + p += 5; + is_relative = TRUE; + } + else if (*p != '/') + continue; + + d = strrchr (p, '"'); + if (!d) + continue; + *d = 0; + + d = p; + + /* remove trailing slashes */ + len = strlen (d); + if (d[len - 1] == '/') + d[len - 1] = 0; + + if (is_relative) + { + g_get_any_init (); + g_user_special_dirs[directory] = g_build_filename (g_home_dir, d, NULL); + } + else + g_user_special_dirs[directory] = g_strdup (d); + } + + g_strfreev (lines); + g_free (config_file); +} + +#endif /* G_OS_UNIX && !HAVE_CARBON */ + + +/** + * g_reload_user_special_dirs_cache: + * + * Resets the cache used for g_get_user_special_dir(), so + * that the latest on-disk version is used. Call this only + * if you just changed the data on disk yourself. + * + * Due to threadsafety issues this may cause leaking of strings + * that were previously returned from g_get_user_special_dir() + * that can't be freed. We ensure to only leak the data for + * the directories that actually changed value though. + * + * Since: 2.22 + */ +void +g_reload_user_special_dirs_cache (void) +{ + int i; + + G_LOCK (g_utils_global); + + if (g_user_special_dirs != NULL) + { + /* save a copy of the pointer, to check if some memory can be preserved */ + char **old_g_user_special_dirs = g_user_special_dirs; + char *old_val; + + /* recreate and reload our cache */ + g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES); + load_user_special_dirs (); + + /* only leak changed directories */ + for (i = 0; i < G_USER_N_DIRECTORIES; i++) + { + old_val = old_g_user_special_dirs[i]; + if (g_strcmp0 (old_val, g_user_special_dirs[i]) == 0) + { + /* don't leak */ + g_free (g_user_special_dirs[i]); + g_user_special_dirs[i] = old_val; + } + else + g_free (old_val); + } + + /* free the old array */ + g_free (old_g_user_special_dirs); + } + + G_UNLOCK (g_utils_global); +} + +/** + * g_get_user_special_dir: + * @directory: the logical id of special directory + * + * Returns the full path of a special directory using its logical id. + * + * On Unix this is done using the XDG special user directories. + * For compatibility with existing practise, %G_USER_DIRECTORY_DESKTOP + * falls back to $HOME/Desktop when XDG special + * user directories have not been set up. + * + * Depending on the platform, the user might be able to change the path + * of the special directory without requiring the session to restart; GLib + * will not reflect any change once the special directories are loaded. + * + * Return value: the path to the specified special directory, or %NULL + * if the logical id was not found. The returned string is owned by + * GLib and should not be modified or freed. + * + * Since: 2.14 + */ +const gchar * +g_get_user_special_dir (GUserDirectory directory) +{ + g_return_val_if_fail (directory >= G_USER_DIRECTORY_DESKTOP && + directory < G_USER_N_DIRECTORIES, NULL); + + G_LOCK (g_utils_global); + + if (G_UNLIKELY (g_user_special_dirs == NULL)) + { + g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES); + + load_user_special_dirs (); + + /* Special-case desktop for historical compatibility */ + if (g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] == NULL) + { + g_get_any_init (); + + g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = + g_build_filename (g_home_dir, "Desktop", NULL); + } + } + + G_UNLOCK (g_utils_global); + + return g_user_special_dirs[directory]; +} + +#ifdef G_OS_WIN32 + +#undef g_get_system_data_dirs + +static HMODULE +get_module_for_address (gconstpointer address) +{ + /* Holds the g_utils_global lock */ + + static gboolean beenhere = FALSE; + typedef BOOL (WINAPI *t_GetModuleHandleExA) (DWORD, LPCTSTR, HMODULE *); + static t_GetModuleHandleExA p_GetModuleHandleExA = NULL; + HMODULE hmodule = NULL; + + if (!address) + return NULL; + + if (!beenhere) + { + p_GetModuleHandleExA = + (t_GetModuleHandleExA) GetProcAddress (GetModuleHandle ("kernel32.dll"), + "GetModuleHandleExA"); + beenhere = TRUE; + } + + if (p_GetModuleHandleExA == NULL || + !(*p_GetModuleHandleExA) (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT | + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + address, &hmodule)) + { + MEMORY_BASIC_INFORMATION mbi; + VirtualQuery (address, &mbi, sizeof (mbi)); + hmodule = (HMODULE) mbi.AllocationBase; + } + + return hmodule; +} + +static gchar * +get_module_share_dir (gconstpointer address) +{ + HMODULE hmodule; + gchar *filename; + gchar *retval; + + hmodule = get_module_for_address (address); + if (hmodule == NULL) + return NULL; + + filename = g_win32_get_package_installation_directory_of_module (hmodule); + retval = g_build_filename (filename, "share", NULL); + g_free (filename); + + return retval; +} + +const gchar * const * +g_win32_get_system_data_dirs_for_module (void (*address_of_function)()) +{ + GArray *data_dirs; + HMODULE hmodule; + static GHashTable *per_module_data_dirs = NULL; + gchar **retval; + gchar *p; + gchar *exe_root; + + if (address_of_function) + { + G_LOCK (g_utils_global); + hmodule = get_module_for_address (address_of_function); + if (hmodule != NULL) + { + if (per_module_data_dirs == NULL) + per_module_data_dirs = g_hash_table_new (NULL, NULL); + else + { + retval = g_hash_table_lookup (per_module_data_dirs, hmodule); + + if (retval != NULL) + { + G_UNLOCK (g_utils_global); + return (const gchar * const *) retval; + } + } + } + } + + data_dirs = g_array_new (TRUE, TRUE, sizeof (char *)); + + /* Documents and Settings\All Users\Application Data */ + p = get_special_folder (CSIDL_COMMON_APPDATA); + if (p) + g_array_append_val (data_dirs, p); + + /* Documents and Settings\All Users\Documents */ + p = get_special_folder (CSIDL_COMMON_DOCUMENTS); + if (p) + g_array_append_val (data_dirs, p); + + /* Using the above subfolders of Documents and Settings perhaps + * makes sense from a Windows perspective. + * + * But looking at the actual use cases of this function in GTK+ + * and GNOME software, what we really want is the "share" + * subdirectory of the installation directory for the package + * our caller is a part of. + * + * The address_of_function parameter, if non-NULL, points to a + * function in the calling module. Use that to determine that + * module's installation folder, and use its "share" subfolder. + * + * Additionally, also use the "share" subfolder of the installation + * locations of GLib and the .exe file being run. + * + * To guard against none of the above being what is really wanted, + * callers of this function should have Win32-specific code to look + * up their installation folder themselves, and handle a subfolder + * "share" of it in the same way as the folders returned from this + * function. + */ + + p = get_module_share_dir (address_of_function); + if (p) + g_array_append_val (data_dirs, p); + + if (glib_dll != NULL) + { + gchar *glib_root = g_win32_get_package_installation_directory_of_module (glib_dll); + p = g_build_filename (glib_root, "share", NULL); + if (p) + g_array_append_val (data_dirs, p); + g_free (glib_root); + } + + exe_root = g_win32_get_package_installation_directory_of_module (NULL); + p = g_build_filename (exe_root, "share", NULL); + if (p) + g_array_append_val (data_dirs, p); + g_free (exe_root); + + retval = (gchar **) g_array_free (data_dirs, FALSE); + + if (address_of_function) + { + if (hmodule != NULL) + g_hash_table_insert (per_module_data_dirs, hmodule, retval); + G_UNLOCK (g_utils_global); + } + + return (const gchar * const *) retval; +} + +#endif + +/** + * g_get_system_data_dirs: + * + * Returns an ordered list of base directories in which to access + * system-wide application data. + * + * On UNIX platforms this is determined using the mechanisms described in + * the + * XDG Base Directory Specification + * In this case the list of directories retrieved will be XDG_DATA_DIRS. + * + * On Windows the first elements in the list are the Application Data + * and Documents folders for All Users. (These can be determined only + * on Windows 2000 or later and are not present in the list on other + * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and + * CSIDL_COMMON_DOCUMENTS. + * + * Then follows the "share" subfolder in the installation folder for + * the package containing the DLL that calls this function, if it can + * be determined. + * + * Finally the list contains the "share" subfolder in the installation + * folder for GLib, and in the installation folder for the package the + * application's .exe file belongs to. + * + * The installation folders above are determined by looking up the + * folder where the module (DLL or EXE) in question is located. If the + * folder's name is "bin", its parent is used, otherwise the folder + * itself. + * + * Note that on Windows the returned list can vary depending on where + * this function is called. + * + * Return value: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by GLib that must + * not be modified or freed. + * Since: 2.6 + **/ +const gchar * const * +g_get_system_data_dirs (void) +{ + gchar **data_dir_vector; + + G_LOCK (g_utils_global); + + if (!g_system_data_dirs) + { +#ifdef G_OS_WIN32 + data_dir_vector = (gchar **) g_win32_get_system_data_dirs_for_module (NULL); +#else + gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS"); + + if (!data_dirs || !data_dirs[0]) + data_dirs = "/usr/local/share/:/usr/share/"; + + data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0); +#endif + + g_system_data_dirs = data_dir_vector; + } + else + data_dir_vector = g_system_data_dirs; + + G_UNLOCK (g_utils_global); + + return (const gchar * const *) data_dir_vector; +} + +/** + * g_get_system_config_dirs: + * + * Returns an ordered list of base directories in which to access + * system-wide configuration information. + * + * On UNIX platforms this is determined using the mechanisms described in + * the + * XDG Base Directory Specification. + * In this case the list of directories retrieved will be XDG_CONFIG_DIRS. + * + * On Windows is the directory that contains application data for all users. + * A typical path is C:\Documents and Settings\All Users\Application Data. + * This folder is used for application data that is not user specific. + * For example, an application can store a spell-check dictionary, a database + * of clip art, or a log file in the CSIDL_COMMON_APPDATA folder. + * This information will not roam and is available to anyone using the computer. + * + * Return value: (array zero-terminated=1) (transfer none): a %NULL-terminated array of strings owned by GLib that must + * not be modified or freed. + * Since: 2.6 + **/ +const gchar * const * +g_get_system_config_dirs (void) +{ + gchar *conf_dirs, **conf_dir_vector; + + G_LOCK (g_utils_global); + + if (!g_system_config_dirs) + { +#ifdef G_OS_WIN32 + conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA); + if (conf_dirs) + { + conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0); + g_free (conf_dirs); + } + else + { + /* Return empty list */ + conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0); + } +#else + conf_dirs = (gchar *) g_getenv ("XDG_CONFIG_DIRS"); + + if (!conf_dirs || !conf_dirs[0]) + conf_dirs = "/etc/xdg"; + + conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0); +#endif + + g_system_config_dirs = conf_dir_vector; + } + else + conf_dir_vector = g_system_config_dirs; + G_UNLOCK (g_utils_global); + + return (const gchar * const *) conf_dir_vector; +} + +/** + * g_nullify_pointer: + * @nullify_location: the memory address of the pointer. + * + * Set the pointer at the specified location to %NULL. + **/ +void +g_nullify_pointer (gpointer *nullify_location) +{ + g_return_if_fail (nullify_location != NULL); + + *nullify_location = NULL; +} + +#define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1000)) +#define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR) +#define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR) +#define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR) +#define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR) +#define EXABYTE_FACTOR (PETABYTE_FACTOR * KILOBYTE_FACTOR) + +#define KIBIBYTE_FACTOR (G_GOFFSET_CONSTANT (1024)) +#define MEBIBYTE_FACTOR (KIBIBYTE_FACTOR * KIBIBYTE_FACTOR) +#define GIBIBYTE_FACTOR (MEBIBYTE_FACTOR * KIBIBYTE_FACTOR) +#define TEBIBYTE_FACTOR (GIBIBYTE_FACTOR * KIBIBYTE_FACTOR) +#define PEBIBYTE_FACTOR (TEBIBYTE_FACTOR * KIBIBYTE_FACTOR) +#define EXBIBYTE_FACTOR (PEBIBYTE_FACTOR * KIBIBYTE_FACTOR) + +/** + * g_format_size: + * @size: a size in bytes + * + * Formats a size (for example the size of a file) into a human readable + * string. Sizes are rounded to the nearest size prefix (kB, MB, GB) + * and are displayed rounded to the nearest tenth. E.g. the file size + * 3292528 bytes will be converted into the string "3.2 MB". + * + * The prefix units base is 1000 (i.e. 1 kB is 1000 bytes). + * + * This string should be freed with g_free() when not needed any longer. + * + * See g_format_size_full() for more options about how the size might be + * formatted. + * + * Returns: a newly-allocated formatted string containing a human readable + * file size + * + * Since: 2.30 + */ +gchar * +g_format_size (guint64 size) +{ + return g_format_size_full (size, G_FORMAT_SIZE_DEFAULT); +} + +/** + * GFormatSizeFlags: + * @G_FORMAT_SIZE_DEFAULT: behave the same as g_format_size() + * @G_FORMAT_SIZE_LONG_FORMAT: include the exact number of bytes as part + * of the returned string. For example, "45.6 kB (45,612 bytes)". + * @G_FORMAT_SIZE_IEC_UNITS: use IEC (base 1024) units with "KiB"-style + * suffixes. IEC units should only be used for reporting things with + * a strong "power of 2" basis, like RAM sizes or RAID stripe sizes. + * Network and storage sizes should be reported in the normal SI units. + * + * Flags to modify the format of the string returned by g_format_size_full(). + */ + +/** + * g_format_size_full: + * @size: a size in bytes + * @flags: #GFormatSizeFlags to modify the output + * + * Formats a size. + * + * This function is similar to g_format_size() but allows for flags + * that modify the output. See #GFormatSizeFlags. + * + * Returns: a newly-allocated formatted string containing a human + * readable file size + * + * Since: 2.30 + */ +gchar * +g_format_size_full (guint64 size, + GFormatSizeFlags flags) +{ + GString *string; + + string = g_string_new (NULL); + + if (flags & G_FORMAT_SIZE_IEC_UNITS) + { + if (size < KIBIBYTE_FACTOR) + { + g_string_printf (string, + g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size), + (guint) size); + flags &= ~G_FORMAT_SIZE_LONG_FORMAT; + } + + else if (size < MEBIBYTE_FACTOR) + g_string_printf (string, _("%.1f KiB"), (gdouble) size / (gdouble) KIBIBYTE_FACTOR); + else if (size < GIBIBYTE_FACTOR) + g_string_printf (string, _("%.1f MiB"), (gdouble) size / (gdouble) MEBIBYTE_FACTOR); + + else if (size < TEBIBYTE_FACTOR) + g_string_printf (string, _("%.1f GiB"), (gdouble) size / (gdouble) GIBIBYTE_FACTOR); + + else if (size < PEBIBYTE_FACTOR) + g_string_printf (string, _("%.1f TiB"), (gdouble) size / (gdouble) TEBIBYTE_FACTOR); + + else if (size < EXBIBYTE_FACTOR) + g_string_printf (string, _("%.1f PiB"), (gdouble) size / (gdouble) PEBIBYTE_FACTOR); + + else + g_string_printf (string, _("%.1f EiB"), (gdouble) size / (gdouble) EXBIBYTE_FACTOR); + } + else + { + if (size < KILOBYTE_FACTOR) + { + g_string_printf (string, + g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes", (guint) size), + (guint) size); + flags &= ~G_FORMAT_SIZE_LONG_FORMAT; + } + + else if (size < MEGABYTE_FACTOR) + g_string_printf (string, _("%.1f kB"), (gdouble) size / (gdouble) KILOBYTE_FACTOR); + + else if (size < GIGABYTE_FACTOR) + g_string_printf (string, _("%.1f MB"), (gdouble) size / (gdouble) MEGABYTE_FACTOR); + + else if (size < TERABYTE_FACTOR) + g_string_printf (string, _("%.1f GB"), (gdouble) size / (gdouble) GIGABYTE_FACTOR); + else if (size < PETABYTE_FACTOR) + g_string_printf (string, _("%.1f TB"), (gdouble) size / (gdouble) TERABYTE_FACTOR); + + else if (size < EXABYTE_FACTOR) + g_string_printf (string, _("%.1f PB"), (gdouble) size / (gdouble) PETABYTE_FACTOR); + + else + g_string_printf (string, _("%.1f EB"), (gdouble) size / (gdouble) EXABYTE_FACTOR); + } + + if (flags & G_FORMAT_SIZE_LONG_FORMAT) + { + /* First problem: we need to use the number of bytes to decide on + * the plural form that is used for display, but the number of + * bytes potentially exceeds the size of a guint (which is what + * ngettext() takes). + * + * From a pragmatic standpoint, it seems that all known languages + * base plural forms on one or both of the following: + * + * - the lowest digits of the number + * + * - if the number if greater than some small value + * + * Here's how we fake it: Draw an arbitrary line at one thousand. + * If the number is below that, then fine. If it is above it, + * then we take the modulus of the number by one thousand (in + * order to keep the lowest digits) and add one thousand to that + * (in order to ensure that 1001 is not treated the same as 1). + */ + guint plural_form = size < 1000 ? size : size % 1000 + 1000; + + /* Second problem: we need to translate the string "%u byte" and + * "%u bytes" for pluralisation, but the correct number format to + * use for a gsize is different depending on which architecture + * we're on. + * + * Solution: format the number separately and use "%s bytes" on + * all platforms. + */ + const gchar *translated_format; + gchar *formatted_number; + + /* Translators: the %s in "%s bytes" will always be replaced by a number. */ + translated_format = g_dngettext(GETTEXT_PACKAGE, "%s byte", "%s bytes", plural_form); + /* XXX: Windows doesn't support the "'" format modifier, so we + * must not use it there. Instead, just display the number + * without separation. Bug #655336 is open until a solution is + * found. + */ +#ifndef G_OS_WIN32 + formatted_number = g_strdup_printf ("%'"G_GUINT64_FORMAT, size); +#else + formatted_number = g_strdup_printf ("%"G_GUINT64_FORMAT, size); +#endif + + g_string_append (string, " ("); + g_string_append_printf (string, translated_format, formatted_number); + g_free (formatted_number); + g_string_append (string, ")"); + } + + return g_string_free (string, FALSE); +} + +/** + * g_format_size_for_display: + * @size: a size in bytes + * + * Formats a size (for example the size of a file) into a human + * readable string. Sizes are rounded to the nearest size prefix + * (KB, MB, GB) and are displayed rounded to the nearest tenth. + * E.g. the file size 3292528 bytes will be converted into the + * string "3.1 MB". + * + * The prefix units base is 1024 (i.e. 1 KB is 1024 bytes). + * + * This string should be freed with g_free() when not needed any longer. + * + * Returns: a newly-allocated formatted string containing a human + * readable file size + * + * Since: 2.16 + * + * Deprecated:2.30: This function is broken due to its use of SI + * suffixes to denote IEC units. Use g_format_size() instead. + */ +gchar * +g_format_size_for_display (goffset size) +{ + if (size < (goffset) KIBIBYTE_FACTOR) + return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size); + else + { + gdouble displayed_size; + + if (size < (goffset) MEBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) KIBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f KB"), displayed_size); + } + else if (size < (goffset) GIBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) MEBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f MB"), displayed_size); + } + else if (size < (goffset) TEBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) GIBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f GB"), displayed_size); + } + else if (size < (goffset) PEBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) TEBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f TB"), displayed_size); + } + else if (size < (goffset) EXBIBYTE_FACTOR) + { + displayed_size = (gdouble) size / (gdouble) PEBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f PB"), displayed_size); + } + else + { + displayed_size = (gdouble) size / (gdouble) EXBIBYTE_FACTOR; + return g_strdup_printf (_("%.1f EB"), displayed_size); + } + } +} + +#if defined (G_OS_WIN32) && !defined (_WIN64) + +/* Binary compatibility versions. Not for newly compiled code. */ + +#undef g_find_program_in_path + +gchar* +g_find_program_in_path (const gchar *program) +{ + gchar *utf8_program = g_locale_to_utf8 (program, -1, NULL, NULL, NULL); + gchar *utf8_retval = g_find_program_in_path_utf8 (utf8_program); + gchar *retval; + + g_free (utf8_program); + if (utf8_retval == NULL) + return NULL; + retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL); + g_free (utf8_retval); + + return retval; +} + +#undef g_get_user_name + +const gchar * +g_get_user_name (void) +{ + g_get_any_init_locked (); + return g_user_name_cp; +} + +#undef g_get_real_name + +const gchar * +g_get_real_name (void) +{ + g_get_any_init_locked (); + return g_real_name_cp; +} + +#undef g_get_home_dir + +const gchar * +g_get_home_dir (void) +{ + g_get_any_init_locked (); + return g_home_dir_cp; +} + +#undef g_get_tmp_dir + +const gchar * +g_get_tmp_dir (void) +{ + g_get_any_init_locked (); + return g_tmp_dir_cp; +} + +#endif diff --git a/glib/glib/gutils.h b/glib/glib/gutils.h new file mode 100644 index 0000000..95114d8 --- /dev/null +++ b/glib/glib/gutils.h @@ -0,0 +1,373 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_UTILS_H__ +#define __G_UTILS_H__ + +#include +#include + +G_BEGIN_DECLS + +/* Define G_VA_COPY() to do the right thing for copying va_list variables. + * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy. + */ +#if !defined (G_VA_COPY) +# if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32)) +# define G_VA_COPY(ap1, ap2) (*(ap1) = *(ap2)) +# elif defined (G_VA_COPY_AS_ARRAY) +# define G_VA_COPY(ap1, ap2) g_memmove ((ap1), (ap2), sizeof (va_list)) +# else /* va_list is a pointer */ +# define G_VA_COPY(ap1, ap2) ((ap1) = (ap2)) +# endif /* va_list is a pointer */ +#endif /* !G_VA_COPY */ + +/* inlining hassle. for compilers that don't allow the `inline' keyword, + * mostly because of strict ANSI C compliance or dumbness, we try to fall + * back to either `__inline__' or `__inline'. + * G_CAN_INLINE is defined in glibconfig.h if the compiler seems to be + * actually *capable* to do function inlining, in which case inline + * function bodies do make sense. we also define G_INLINE_FUNC to properly + * export the function prototypes if no inlining can be performed. + * inline function bodies have to be special cased with G_CAN_INLINE and a + * .c file specific macro to allow one compiled instance with extern linkage + * of the functions by defining G_IMPLEMENT_INLINES and the .c file macro. + */ +#if defined (G_HAVE_INLINE) && defined (__GNUC__) && defined (__STRICT_ANSI__) +# undef inline +# define inline __inline__ +#elif !defined (G_HAVE_INLINE) +# undef inline +# if defined (G_HAVE___INLINE__) +# define inline __inline__ +# elif defined (G_HAVE___INLINE) +# define inline __inline +# else /* !inline && !__inline__ && !__inline */ +# define inline /* don't inline, then */ +# endif +#endif +#ifdef G_IMPLEMENT_INLINES +# define G_INLINE_FUNC +# undef G_CAN_INLINE +#elif defined (__GNUC__) +# define G_INLINE_FUNC static __inline __attribute__ ((unused)) +#elif defined (G_CAN_INLINE) +# define G_INLINE_FUNC static inline +#else /* can't inline */ +# define G_INLINE_FUNC +#endif /* !G_INLINE_FUNC */ + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +#define g_get_user_name g_get_user_name_utf8 +#define g_get_real_name g_get_real_name_utf8 +#define g_get_home_dir g_get_home_dir_utf8 +#define g_get_tmp_dir g_get_tmp_dir_utf8 +#endif +#endif + +const gchar * g_get_user_name (void); +const gchar * g_get_real_name (void); +const gchar * g_get_home_dir (void); +const gchar * g_get_tmp_dir (void); +const gchar * g_get_host_name (void); +gchar * g_get_prgname (void); +void g_set_prgname (const gchar *prgname); +const gchar * g_get_application_name (void); +void g_set_application_name (const gchar *application_name); + +void g_reload_user_special_dirs_cache (void); +const gchar * g_get_user_data_dir (void); +const gchar * g_get_user_config_dir (void); +const gchar * g_get_user_cache_dir (void); +const gchar * const * g_get_system_data_dirs (void); + +#ifdef G_OS_WIN32 +/* This functions is not part of the public GLib API */ +const gchar * const * g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void)); +#endif + +#if defined (G_OS_WIN32) && defined (G_CAN_INLINE) && !defined (__cplusplus) +/* This function is not part of the public GLib API either. Just call + * g_get_system_data_dirs() in your code, never mind that that is + * actually a macro and you will in fact call this inline function. + */ +static inline const gchar * const * +_g_win32_get_system_data_dirs (void) +{ + return g_win32_get_system_data_dirs_for_module ((void (*)(void)) &_g_win32_get_system_data_dirs); +} +#define g_get_system_data_dirs _g_win32_get_system_data_dirs +#endif + +const gchar * const * g_get_system_config_dirs (void); + +const gchar * g_get_user_runtime_dir (void); + +/** + * GUserDirectory: + * @G_USER_DIRECTORY_DESKTOP: the user's Desktop directory + * @G_USER_DIRECTORY_DOCUMENTS: the user's Documents directory + * @G_USER_DIRECTORY_DOWNLOAD: the user's Downloads directory + * @G_USER_DIRECTORY_MUSIC: the user's Music directory + * @G_USER_DIRECTORY_PICTURES: the user's Pictures directory + * @G_USER_DIRECTORY_PUBLIC_SHARE: the user's shared directory + * @G_USER_DIRECTORY_TEMPLATES: the user's Templates directory + * @G_USER_DIRECTORY_VIDEOS: the user's Movies directory + * @G_USER_N_DIRECTORIES: the number of enum values + * + * These are logical ids for special directories which are defined + * depending on the platform used. You should use g_get_user_special_dir() + * to retrieve the full path associated to the logical id. + * + * The #GUserDirectory enumeration can be extended at later date. Not + * every platform has a directory for every logical id in this + * enumeration. + * + * Since: 2.14 + */ +typedef enum { + G_USER_DIRECTORY_DESKTOP, + G_USER_DIRECTORY_DOCUMENTS, + G_USER_DIRECTORY_DOWNLOAD, + G_USER_DIRECTORY_MUSIC, + G_USER_DIRECTORY_PICTURES, + G_USER_DIRECTORY_PUBLIC_SHARE, + G_USER_DIRECTORY_TEMPLATES, + G_USER_DIRECTORY_VIDEOS, + + G_USER_N_DIRECTORIES +} GUserDirectory; + +const gchar * g_get_user_special_dir (GUserDirectory directory); + +/** + * GDebugKey: + * @key: the string + * @value: the flag + * + * Associates a string with a bit flag. + * Used in g_parse_debug_string(). + */ +typedef struct _GDebugKey GDebugKey; +struct _GDebugKey +{ + const gchar *key; + guint value; +}; + +/* Miscellaneous utility functions + */ +guint g_parse_debug_string (const gchar *string, + const GDebugKey *keys, + guint nkeys); + +gint g_snprintf (gchar *string, + gulong n, + gchar const *format, + ...) G_GNUC_PRINTF (3, 4); +gint g_vsnprintf (gchar *string, + gulong n, + gchar const *format, + va_list args); + +void g_nullify_pointer (gpointer *nullify_location); + +typedef enum +{ + G_FORMAT_SIZE_DEFAULT = 0, + G_FORMAT_SIZE_LONG_FORMAT = 1 << 0, + G_FORMAT_SIZE_IEC_UNITS = 1 << 1 +} GFormatSizeFlags; + +gchar *g_format_size_full (guint64 size, + GFormatSizeFlags flags); +gchar *g_format_size (guint64 size); + +GLIB_DEPRECATED_FOR(g_format_size) +gchar *g_format_size_for_display (goffset size); + +#ifndef G_DISABLE_DEPRECATED +/** + * GVoidFunc: + * + * Declares a type of function which takes no arguments + * and has no return value. It is used to specify the type + * function passed to g_atexit(). + */ +typedef void (*GVoidFunc) (void); +#ifndef ATEXIT +# define ATEXIT(proc) g_ATEXIT(proc) +#else +# define G_NATIVE_ATEXIT +#endif /* ATEXIT */ +/* we use a GLib function as a replacement for ATEXIT, so + * the programmer is not required to check the return value + * (if there is any in the implementation) and doesn't encounter + * missing include files. + */ +GLIB_DEPRECATED +void g_atexit (GVoidFunc func); + +#ifdef G_OS_WIN32 +/* It's a bad idea to wrap atexit() on Windows. If the GLib DLL calls + * atexit(), the function will be called when the GLib DLL is detached + * from the program, which is not what the caller wants. The caller + * wants the function to be called when it *itself* exits (or is + * detached, in case the caller, too, is a DLL). + */ +#if (defined(__MINGW_H) && !defined(_STDLIB_H_)) || (defined(_MSC_VER) && !defined(_INC_STDLIB)) +int atexit (void (*)(void)); +#endif +#define g_atexit(func) atexit(func) +#endif + +#endif /* G_DISABLE_DEPRECATED */ + +#ifndef __GTK_DOC_IGNORE__ +#ifdef G_OS_WIN32 +#define g_find_program_in_path g_find_program_in_path_utf8 +#endif +#endif + +/* Look for an executable in PATH, following execvp() rules */ +gchar* g_find_program_in_path (const gchar *program); + +/* Bit tests + */ +G_INLINE_FUNC gint g_bit_nth_lsf (gulong mask, + gint nth_bit) G_GNUC_CONST; +G_INLINE_FUNC gint g_bit_nth_msf (gulong mask, + gint nth_bit) G_GNUC_CONST; +G_INLINE_FUNC guint g_bit_storage (gulong number) G_GNUC_CONST; + +/* inline function implementations + */ +#if defined (G_CAN_INLINE) || defined (__G_UTILS_C__) +G_INLINE_FUNC gint +g_bit_nth_lsf (gulong mask, + gint nth_bit) +{ + if (G_UNLIKELY (nth_bit < -1)) + nth_bit = -1; + while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1)) + { + nth_bit++; + if (mask & (1UL << nth_bit)) + return nth_bit; + } + return -1; +} +G_INLINE_FUNC gint +g_bit_nth_msf (gulong mask, + gint nth_bit) +{ + if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8)) + nth_bit = GLIB_SIZEOF_LONG * 8; + while (nth_bit > 0) + { + nth_bit--; + if (mask & (1UL << nth_bit)) + return nth_bit; + } + return -1; +} +G_INLINE_FUNC guint +g_bit_storage (gulong number) +{ +#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__) + return G_LIKELY (number) ? + ((GLIB_SIZEOF_LONG * 8U - 1) ^ __builtin_clzl(number)) + 1 : 1; +#else + register guint n_bits = 0; + + do + { + n_bits++; + number >>= 1; + } + while (number); + return n_bits; +#endif +} +#endif /* G_CAN_INLINE || __G_UTILS_C__ */ + +G_END_DECLS + +#ifndef G_DISABLE_DEPRECATED + +/* + * This macro is deprecated. This DllMain() is too complex. It is + * recommended to write an explicit minimal DLlMain() that just saves + * the handle to the DLL and then use that handle instead, for + * instance passing it to + * g_win32_get_package_installation_directory_of_module(). + * + * On Windows, this macro defines a DllMain function that stores the + * actual DLL name that the code being compiled will be included in. + * STATIC should be empty or 'static'. DLL_NAME is the name of the + * (pointer to the) char array where the DLL name will be stored. If + * this is used, you must also include . If you need a more complex + * DLL entry point function, you cannot use this. + * + * On non-Windows platforms, expands to nothing. + */ + +#ifndef G_PLATFORM_WIN32 +# define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name) +#else +# define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name) \ +static char *dll_name; \ + \ +BOOL WINAPI \ +DllMain (HINSTANCE hinstDLL, \ + DWORD fdwReason, \ + LPVOID lpvReserved) \ +{ \ + wchar_t wcbfr[1000]; \ + char *tem; \ + switch (fdwReason) \ + { \ + case DLL_PROCESS_ATTACH: \ + GetModuleFileNameW ((HMODULE) hinstDLL, wcbfr, G_N_ELEMENTS (wcbfr)); \ + tem = g_utf16_to_utf8 (wcbfr, -1, NULL, NULL, NULL); \ + dll_name = g_path_get_basename (tem); \ + g_free (tem); \ + break; \ + } \ + \ + return TRUE; \ +} + +#endif /* !G_DISABLE_DEPRECATED */ + +#endif /* G_PLATFORM_WIN32 */ + +#endif /* __G_UTILS_H__ */ diff --git a/glib/glib/gvariant-core.c b/glib/glib/gvariant-core.c new file mode 100644 index 0000000..1633463 --- /dev/null +++ b/glib/glib/gvariant-core.c @@ -0,0 +1,1075 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * This file includes the structure definition for GVariant and a small + * set of functions that are allowed to access the structure directly. + * + * This minimises the amount of code that can possibly touch a GVariant + * structure directly to a few simple fundamental operations. These few + * operations are written to be completely threadsafe with respect to + * all possible outside access. This means that we only need to be + * concerned about thread safety issues in this one small file. + * + * Most GVariant API functions are in gvariant.c. + */ + +/** + * GVariant: + * + * #GVariant is an opaque data structure and can only be accessed + * using the following functions. + * + * Since: 2.24 + **/ +struct _GVariant +/* see below for field member documentation */ +{ + GVariantTypeInfo *type_info; + gsize size; + + union + { + struct + { + GBytes *bytes; + gconstpointer data; + } serialised; + + struct + { + GVariant **children; + gsize n_children; + } tree; + } contents; + + gint state; + gint ref_count; +}; + +/* struct GVariant: + * + * There are two primary forms of GVariant instances: "serialised form" + * and "tree form". + * + * "serialised form": A serialised GVariant instance stores its value in + * the GVariant serialisation format. All + * basic-typed instances (ie: non-containers) are in + * serialised format, as are some containers. + * + * "tree form": Some containers are in "tree form". In this case, + * instead of containing the serialised data for the + * container, the instance contains an array of pointers to + * the child values of the container (thus forming a tree). + * + * It is possible for an instance to transition from tree form to + * serialised form. This happens, implicitly, if the serialised data is + * requested (eg: via g_variant_get_data()). Serialised form instances + * never transition into tree form. + * + * + * The fields of the structure are documented here: + * + * type_info: this is a reference to a GVariantTypeInfo describing the + * type of the instance. When the instance is freed, this + * reference must be released with g_variant_type_info_unref(). + * + * The type_info field never changes during the life of the + * instance, so it can be accessed without a lock. + * + * size: this is the size of the serialised form for the instance, if it + * is known. If the instance is in serialised form then it is, by + * definition, known. If the instance is in tree form then it may + * be unknown (in which case it is -1). It is possible for the + * size to be known when in tree form if, for example, the user + * has called g_variant_get_size() without calling + * g_variant_get_data(). Additionally, even when the user calls + * g_variant_get_data() the size of the data must first be + * determined so that a large enough buffer can be allocated for + * the data. + * + * Once the size is known, it can never become unknown again. + * g_variant_ensure_size() is used to ensure that the size is in + * the known state -- it calculates the size if needed. After + * that, the size field can be accessed without a lock. + * + * contents: a union containing either the information associated with + * holding a value in serialised form or holding a value in + * tree form. + * + * .serialised: Only valid when the instance is in serialised form. + * + * Since an instance can never transition away from + * serialised form, once these fields are set, they will + * never be changed. It is therefore valid to access + * them without holding a lock. + * + * .bytes: the #GBytes that contains the memory pointed to by + * .data, or %NULL if .data is %NULL. In the event that + * the instance was deserialised from another instance, + * then the bytes will be shared by both of them. When + * the instance is freed, this reference must be released + * with g_bytes_unref(). + * + * .data: the serialised data (of size 'size') of the instance. + * This pointer should not be freed or modified in any way. + * #GBytes is responsible for memory management. + * + * This pointer may be %NULL in two cases: + * + * - if the serialised size of the instance is 0 + * + * - if the instance is of a fixed-sized type and was + * deserialised out of a corrupted container such that + * the container contains too few bytes to point to the + * entire proper fixed-size of this instance. In this + * case, 'size' will still be equal to the proper fixed + * size, but this pointer will be %NULL. This is exactly + * the reason that g_variant_get_data() sometimes returns + * %NULL. For all other calls, the effect should be as + * if .data pointed to the appropriate number of nul + * bytes. + * + * .tree: Only valid when the instance is in tree form. + * + * Note that accesses from other threads could result in + * conversion of the instance from tree form to serialised form + * at any time. For this reason, the instance lock must always + * be held while performing any operations on 'contents.tree'. + * + * .children: the array of the child instances of this instance. + * When the instance is freed (or converted to serialised + * form) then each child must have g_variant_unref() + * called on it and the array must be freed using + * g_free(). + * + * .n_children: the number of items in the .children array. + * + * state: a bitfield describing the state of the instance. It is a + * bitwise-or of the following STATE_* constants: + * + * STATE_LOCKED: the instance lock is held. This is the bit used by + * g_bit_lock(). + * + * STATE_SERIALISED: the instance is in serialised form. If this + * flag is not set then the instance is in tree + * form. + * + * STATE_TRUSTED: for serialised form instances, this means that the + * serialised data is known to be in normal form (ie: + * not corrupted). + * + * For tree form instances, this means that all of the + * child instances in the contents.tree.children array + * are trusted. This means that if the container is + * serialised then the resulting data will be in + * normal form. + * + * If this flag is unset it does not imply that the + * data is corrupted. It merely means that we're not + * sure that it's valid. See g_variant_is_trusted(). + * + * STATE_FLOATING: if this flag is set then the object has a floating + * reference. See g_variant_ref_sink(). + * + * ref_count: the reference count of the instance + */ +#define STATE_LOCKED 1 +#define STATE_SERIALISED 2 +#define STATE_TRUSTED 4 +#define STATE_FLOATING 8 + +/* -- private -- */ +/* < private > + * g_variant_lock: + * @value: a #GVariant + * + * Locks @value for performing sensitive operations. + */ +static void +g_variant_lock (GVariant *value) +{ + g_bit_lock (&value->state, 0); +} + +/* < private > + * g_variant_unlock: + * @value: a #GVariant + * + * Unlocks @value after performing sensitive operations. + */ +static void +g_variant_unlock (GVariant *value) +{ + g_bit_unlock (&value->state, 0); +} + +/* < private > + * g_variant_release_children: + * @value: a #GVariant + * + * Releases the reference held on each child in the 'children' array of + * @value and frees the array itself. @value must be in tree form. + * + * This is done when freeing a tree-form instance or converting it to + * serialised form. + * + * The current thread must hold the lock on @value. + */ +static void +g_variant_release_children (GVariant *value) +{ + gsize i; + + g_assert (value->state & STATE_LOCKED); + g_assert (~value->state & STATE_SERIALISED); + + for (i = 0; i < value->contents.tree.n_children; i++) + g_variant_unref (value->contents.tree.children[i]); + + g_free (value->contents.tree.children); +} + +/* This begins the main body of the recursive serialiser. + * + * There are 3 functions here that work as a team with the serialiser to + * get things done. g_variant_store() has a trivial role, but as a + * public API function, it has its definition elsewhere. + * + * Note that "serialisation" of an instance does not mean that the + * instance is converted to serialised form -- it means that the + * serialised form of an instance is written to an external buffer. + * g_variant_ensure_serialised() (which is not part of this set of + * functions) is the function that is responsible for converting an + * instance to serialised form. + * + * We are only concerned here with container types since non-container + * instances are always in serialised form. For these instances, + * storing their serialised form merely involves a memcpy(). + * + * Serialisation is a two-step process. First, the size of the + * serialised data must be calculated so that an appropriately-sized + * buffer can be allocated. Second, the data is written into the + * buffer. + * + * Determining the size: + * The process of determining the size is triggered by a call to + * g_variant_ensure_size() on a container. This invokes the + * serialiser code to determine the size. The serialiser is passed + * g_variant_fill_gvs() as a callback. + * + * g_variant_fill_gvs() is called by the serialiser on each child of + * the container which, in turn, calls g_variant_ensure_size() on + * itself and fills in the result of its own size calculation. + * + * The serialiser uses the size information from the children to + * calculate the size needed for the entire container. + * + * Writing the data: + * After the buffer has been allocated, g_variant_serialise() is + * called on the container. This invokes the serialiser code to write + * the bytes to the container. The serialiser is, again, passed + * g_variant_fill_gvs() as a callback. + * + * This time, when g_variant_fill_gvs() is called for each child, the + * child is given a pointer to a sub-region of the allocated buffer + * where it should write its data. This is done by calling + * g_variant_store(). In the event that the instance is in serialised + * form this means a memcpy() of the serialised data into the + * allocated buffer. In the event that the instance is in tree form + * this means a recursive call back into g_variant_serialise(). + * + * + * The forward declaration here allows corecursion via callback: + */ +static void g_variant_fill_gvs (GVariantSerialised *, gpointer); + +/* < private > + * g_variant_ensure_size: + * @value: a #GVariant + * + * Ensures that the ->size field of @value is filled in properly. This + * must be done as a precursor to any serialisation of the value in + * order to know how large of a buffer is needed to store the data. + * + * The current thread must hold the lock on @value. + */ +static void +g_variant_ensure_size (GVariant *value) +{ + g_assert (value->state & STATE_LOCKED); + + if (value->size == (gssize) -1) + { + gpointer *children; + gsize n_children; + + children = (gpointer *) value->contents.tree.children; + n_children = value->contents.tree.n_children; + value->size = g_variant_serialiser_needed_size (value->type_info, + g_variant_fill_gvs, + children, n_children); + } +} + +/* < private > + * g_variant_serialise: + * @value: a #GVariant + * @data: an appropriately-sized buffer + * + * Serialises @value into @data. @value must be in tree form. + * + * No change is made to @value. + * + * The current thread must hold the lock on @value. + */ +static void +g_variant_serialise (GVariant *value, + gpointer data) +{ + GVariantSerialised serialised = { 0, }; + gpointer *children; + gsize n_children; + + g_assert (~value->state & STATE_SERIALISED); + g_assert (value->state & STATE_LOCKED); + + serialised.type_info = value->type_info; + serialised.size = value->size; + serialised.data = data; + + children = (gpointer *) value->contents.tree.children; + n_children = value->contents.tree.n_children; + + g_variant_serialiser_serialise (serialised, g_variant_fill_gvs, + children, n_children); +} + +/* < private > + * g_variant_fill_gvs: + * @serialised: a pointer to a #GVariantSerialised + * @data: a #GVariant instance + * + * This is the callback that is passed by a tree-form container instance + * to the serialiser. This callback gets called on each child of the + * container. Each child is responsible for performing the following + * actions: + * + * - reporting its type + * + * - reporting its serialised size (requires knowing the size first) + * + * - possibly storing its serialised form into the provided buffer + */ +static void +g_variant_fill_gvs (GVariantSerialised *serialised, + gpointer data) +{ + GVariant *value = data; + + g_variant_lock (value); + g_variant_ensure_size (value); + g_variant_unlock (value); + + if (serialised->type_info == NULL) + serialised->type_info = value->type_info; + g_assert (serialised->type_info == value->type_info); + + if (serialised->size == 0) + serialised->size = value->size; + g_assert (serialised->size == value->size); + + if (serialised->data) + /* g_variant_store() is a public API, so it + * it will reacquire the lock if it needs to. + */ + g_variant_store (value, serialised->data); +} + +/* this ends the main body of the recursive serialiser */ + +/* < private > + * g_variant_ensure_serialised: + * @value: a #GVariant + * + * Ensures that @value is in serialised form. + * + * If @value is in tree form then this function ensures that the + * serialised size is known and then allocates a buffer of that size and + * serialises the instance into the buffer. The 'children' array is + * then released and the instance is set to serialised form based on the + * contents of the buffer. + * + * The current thread must hold the lock on @value. + */ +static void +g_variant_ensure_serialised (GVariant *value) +{ + g_assert (value->state & STATE_LOCKED); + + if (~value->state & STATE_SERIALISED) + { + GBytes *bytes; + gpointer data; + + g_variant_ensure_size (value); + data = g_malloc (value->size); + g_variant_serialise (value, data); + + g_variant_release_children (value); + + bytes = g_bytes_new_take (data, value->size); + value->contents.serialised.data = g_bytes_get_data (bytes, NULL); + value->contents.serialised.bytes = bytes; + value->state |= STATE_SERIALISED; + } +} + +/* < private > + * g_variant_alloc: + * @type: the type of the new instance + * @serialised: if the instance will be in serialised form + * @trusted: if the instance will be trusted + * + * Allocates a #GVariant instance and does some common work (such as + * looking up and filling in the type info), setting the state field, + * and setting the ref_count to 1. + * + * Returns: a new #GVariant with a floating reference + */ +static GVariant * +g_variant_alloc (const GVariantType *type, + gboolean serialised, + gboolean trusted) +{ + GVariant *value; + + value = g_slice_new (GVariant); + value->type_info = g_variant_type_info_get (type); + value->state = (serialised ? STATE_SERIALISED : 0) | + (trusted ? STATE_TRUSTED : 0) | + STATE_FLOATING; + value->size = (gssize) -1; + value->ref_count = 1; + + return value; +} + +/* -- internal -- */ +/* < internal > + * g_variant_new_from_bytes: + * @type: a #GVariantType + * @bytes: a #GBytes + * @trusted: if the contents of @bytes are trusted + * + * Constructs a new serialised-mode #GVariant instance. This is the + * inner interface for creation of new serialised values that gets + * called from various functions in gvariant.c. + * + * A reference is taken on @bytes. + * + * Returns: a new #GVariant with a floating reference + */ +GVariant * +g_variant_new_from_bytes (const GVariantType *type, + GBytes *bytes, + gboolean trusted) +{ + GVariant *value; + guint alignment; + gsize size; + + value = g_variant_alloc (type, TRUE, trusted); + + value->contents.serialised.bytes = g_bytes_ref (bytes); + + g_variant_type_info_query (value->type_info, + &alignment, &size); + + if (size && g_bytes_get_size (bytes) != size) + { + /* Creating a fixed-sized GVariant with a bytes of the wrong + * size. + * + * We should do the equivalent of pulling a fixed-sized child out + * of a brozen container (ie: data is NULL size is equal to the correct + * fixed size). + */ + value->contents.serialised.data = NULL; + value->size = size; + } + else + { + value->contents.serialised.data = g_bytes_get_data (bytes, &value->size); + } + + return value; +} + +/* < internal > + * g_variant_new_from_children: + * @type: a #GVariantType + * @children: an array of #GVariant pointers. Consumed. + * @n_children: the length of @children + * @trusted: %TRUE if every child in @children in trusted + * + * Constructs a new tree-mode #GVariant instance. This is the inner + * interface for creation of new serialised values that gets called from + * various functions in gvariant.c. + * + * @children is consumed by this function. g_free() will be called on + * it some time later. + * + * Returns: a new #GVariant with a floating reference + */ +GVariant * +g_variant_new_from_children (const GVariantType *type, + GVariant **children, + gsize n_children, + gboolean trusted) +{ + GVariant *value; + + value = g_variant_alloc (type, FALSE, trusted); + value->contents.tree.children = children; + value->contents.tree.n_children = n_children; + + return value; +} + +/* < internal > + * g_variant_get_type_info: + * @value: a #GVariant + * + * Returns the #GVariantTypeInfo corresponding to the type of @value. A + * reference is not added, so the return value is only good for the + * duration of the life of @value. + * + * Returns: the #GVariantTypeInfo for @value + */ +GVariantTypeInfo * +g_variant_get_type_info (GVariant *value) +{ + return value->type_info; +} + +/* < internal > + * g_variant_is_trusted: + * @value: a #GVariant + * + * Determines if @value is trusted by #GVariant to contain only + * fully-valid data. All values constructed solely via #GVariant APIs + * are trusted, but values containing data read in from other sources + * are usually not trusted. + * + * The main advantage of trusted data is that certain checks can be + * skipped. For example, we don't need to check that a string is + * properly nul-terminated or that an object path is actually a + * properly-formatted object path. + * + * Returns: if @value is trusted + */ +gboolean +g_variant_is_trusted (GVariant *value) +{ + return (value->state & STATE_TRUSTED) != 0; +} + +/* -- public -- */ + +/** + * g_variant_unref: + * @value: a #GVariant + * + * Decreases the reference count of @value. When its reference count + * drops to 0, the memory used by the variant is freed. + * + * Since: 2.24 + **/ +void +g_variant_unref (GVariant *value) +{ + g_return_if_fail (value != NULL); + g_return_if_fail (value->ref_count > 0); + + if (g_atomic_int_dec_and_test (&value->ref_count)) + { + if G_UNLIKELY (value->state & STATE_LOCKED) + g_critical ("attempting to free a locked GVariant instance. " + "This should never happen."); + + value->state |= STATE_LOCKED; + + g_variant_type_info_unref (value->type_info); + + if (value->state & STATE_SERIALISED) + g_bytes_unref (value->contents.serialised.bytes); + else + g_variant_release_children (value); + + memset (value, 0, sizeof (GVariant)); + g_slice_free (GVariant, value); + } +} + +/** + * g_variant_ref: + * @value: a #GVariant + * + * Increases the reference count of @value. + * + * Returns: the same @value + * + * Since: 2.24 + **/ +GVariant * +g_variant_ref (GVariant *value) +{ + g_return_val_if_fail (value != NULL, NULL); + g_return_val_if_fail (value->ref_count > 0, NULL); + + g_atomic_int_inc (&value->ref_count); + + return value; +} + +/** + * g_variant_ref_sink: + * @value: a #GVariant + * + * #GVariant uses a floating reference count system. All functions with + * names starting with g_variant_new_ return floating + * references. + * + * Calling g_variant_ref_sink() on a #GVariant with a floating reference + * will convert the floating reference into a full reference. Calling + * g_variant_ref_sink() on a non-floating #GVariant results in an + * additional normal reference being added. + * + * In other words, if the @value is floating, then this call "assumes + * ownership" of the floating reference, converting it to a normal + * reference. If the @value is not floating, then this call adds a + * new normal reference increasing the reference count by one. + * + * All calls that result in a #GVariant instance being inserted into a + * container will call g_variant_ref_sink() on the instance. This means + * that if the value was just created (and has only its floating + * reference) then the container will assume sole ownership of the value + * at that point and the caller will not need to unreference it. This + * makes certain common styles of programming much easier while still + * maintaining normal refcounting semantics in situations where values + * are not floating. + * + * Returns: the same @value + * + * Since: 2.24 + **/ +GVariant * +g_variant_ref_sink (GVariant *value) +{ + g_return_val_if_fail (value != NULL, NULL); + g_return_val_if_fail (value->ref_count > 0, NULL); + + g_variant_lock (value); + + if (~value->state & STATE_FLOATING) + g_variant_ref (value); + else + value->state &= ~STATE_FLOATING; + + g_variant_unlock (value); + + return value; +} + +/** + * g_variant_take_ref: + * @value: a #GVariant + * + * If @value is floating, sink it. Otherwise, do nothing. + * + * Typically you want to use g_variant_ref_sink() in order to + * automatically do the correct thing with respect to floating or + * non-floating references, but there is one specific scenario where + * this function is helpful. + * + * The situation where this function is helpful is when creating an API + * that allows the user to provide a callback function that returns a + * #GVariant. We certainly want to allow the user the flexibility to + * return a non-floating reference from this callback (for the case + * where the value that is being returned already exists). + * + * At the same time, the style of the #GVariant API makes it likely that + * for newly-created #GVariant instances, the user can be saved some + * typing if they are allowed to return a #GVariant with a floating + * reference. + * + * Using this function on the return value of the user's callback allows + * the user to do whichever is more convenient for them. The caller + * will alway receives exactly one full reference to the value: either + * the one that was returned in the first place, or a floating reference + * that has been converted to a full reference. + * + * This function has an odd interaction when combined with + * g_variant_ref_sink() running at the same time in another thread on + * the same #GVariant instance. If g_variant_ref_sink() runs first then + * the result will be that the floating reference is converted to a hard + * reference. If g_variant_take_ref() runs first then the result will + * be that the floating reference is converted to a hard reference and + * an additional reference on top of that one is added. It is best to + * avoid this situation. + * + * Returns: the same @value + **/ +GVariant * +g_variant_take_ref (GVariant *value) +{ + g_return_val_if_fail (value != NULL, NULL); + g_return_val_if_fail (value->ref_count > 0, NULL); + + g_atomic_int_and (&value->state, ~STATE_FLOATING); + + return value; +} + +/** + * g_variant_is_floating: + * @value: a #GVariant + * + * Checks whether @value has a floating reference count. + * + * This function should only ever be used to assert that a given variant + * is or is not floating, or for debug purposes. To acquire a reference + * to a variant that might be floating, always use g_variant_ref_sink() + * or g_variant_take_ref(). + * + * See g_variant_ref_sink() for more information about floating reference + * counts. + * + * Returns: whether @value is floating + * + * Since: 2.26 + **/ +gboolean +g_variant_is_floating (GVariant *value) +{ + g_return_val_if_fail (value != NULL, FALSE); + + return (value->state & STATE_FLOATING) != 0; +} + +/** + * g_variant_get_size: + * @value: a #GVariant instance + * + * Determines the number of bytes that would be required to store @value + * with g_variant_store(). + * + * If @value has a fixed-sized type then this function always returned + * that fixed size. + * + * In the case that @value is already in serialised form or the size has + * already been calculated (ie: this function has been called before) + * then this function is O(1). Otherwise, the size is calculated, an + * operation which is approximately O(n) in the number of values + * involved. + * + * Returns: the serialised size of @value + * + * Since: 2.24 + **/ +gsize +g_variant_get_size (GVariant *value) +{ + g_variant_lock (value); + g_variant_ensure_size (value); + g_variant_unlock (value); + + return value->size; +} + +/** + * g_variant_get_data: + * @value: a #GVariant instance + * + * Returns a pointer to the serialised form of a #GVariant instance. + * The returned data may not be in fully-normalised form if read from an + * untrusted source. The returned data must not be freed; it remains + * valid for as long as @value exists. + * + * If @value is a fixed-sized value that was deserialised from a + * corrupted serialised container then %NULL may be returned. In this + * case, the proper thing to do is typically to use the appropriate + * number of nul bytes in place of @value. If @value is not fixed-sized + * then %NULL is never returned. + * + * In the case that @value is already in serialised form, this function + * is O(1). If the value is not already in serialised form, + * serialisation occurs implicitly and is approximately O(n) in the size + * of the result. + * + * To deserialise the data returned by this function, in addition to the + * serialised data, you must know the type of the #GVariant, and (if the + * machine might be different) the endianness of the machine that stored + * it. As a result, file formats or network messages that incorporate + * serialised #GVariants must include this information either + * implicitly (for instance "the file always contains a + * %G_VARIANT_TYPE_VARIANT and it is always in little-endian order") or + * explicitly (by storing the type and/or endianness in addition to the + * serialised data). + * + * Returns: (transfer none): the serialised form of @value, or %NULL + * + * Since: 2.24 + **/ +gconstpointer +g_variant_get_data (GVariant *value) +{ + g_variant_lock (value); + g_variant_ensure_serialised (value); + g_variant_unlock (value); + + return value->contents.serialised.data; +} + +/** + * g_variant_n_children: + * @value: a container #GVariant + * + * Determines the number of children in a container #GVariant instance. + * This includes variants, maybes, arrays, tuples and dictionary + * entries. It is an error to call this function on any other type of + * #GVariant. + * + * For variants, the return value is always 1. For values with maybe + * types, it is always zero or one. For arrays, it is the length of the + * array. For tuples it is the number of tuple items (which depends + * only on the type). For dictionary entries, it is always 2 + * + * This function is O(1). + * + * Returns: the number of children in the container + * + * Since: 2.24 + **/ +gsize +g_variant_n_children (GVariant *value) +{ + gsize n_children; + + g_variant_lock (value); + + if (value->state & STATE_SERIALISED) + { + GVariantSerialised serialised = { + value->type_info, + (gpointer) value->contents.serialised.data, + value->size + }; + + n_children = g_variant_serialised_n_children (serialised); + } + else + n_children = value->contents.tree.n_children; + + g_variant_unlock (value); + + return n_children; +} + +/** + * g_variant_get_child_value: + * @value: a container #GVariant + * @index_: the index of the child to fetch + * + * Reads a child item out of a container #GVariant instance. This + * includes variants, maybes, arrays, tuples and dictionary + * entries. It is an error to call this function on any other type of + * #GVariant. + * + * It is an error if @index_ is greater than the number of child items + * in the container. See g_variant_n_children(). + * + * The returned value is never floating. You should free it with + * g_variant_unref() when you're done with it. + * + * This function is O(1). + * + * Returns: (transfer full): the child at the specified index + * + * Since: 2.24 + **/ +GVariant * +g_variant_get_child_value (GVariant *value, + gsize index_) +{ + g_return_val_if_fail (index_ < g_variant_n_children (value), NULL); + + if (~g_atomic_int_get (&value->state) & STATE_SERIALISED) + { + g_variant_lock (value); + + if (~value->state & STATE_SERIALISED) + { + GVariant *child; + + child = g_variant_ref (value->contents.tree.children[index_]); + g_variant_unlock (value); + + return child; + } + + g_variant_unlock (value); + } + + { + GVariantSerialised serialised = { + value->type_info, + (gpointer) value->contents.serialised.data, + value->size + }; + GVariantSerialised s_child; + GVariant *child; + + /* get the serialiser to extract the serialised data for the child + * from the serialised data for the container + */ + s_child = g_variant_serialised_get_child (serialised, index_); + + /* create a new serialised instance out of it */ + child = g_slice_new (GVariant); + child->type_info = s_child.type_info; + child->state = (value->state & STATE_TRUSTED) | + STATE_SERIALISED; + child->size = s_child.size; + child->ref_count = 1; + child->contents.serialised.bytes = + g_bytes_ref (value->contents.serialised.bytes); + child->contents.serialised.data = s_child.data; + + return child; + } +} + +/** + * g_variant_store: + * @value: the #GVariant to store + * @data: the location to store the serialised data at + * + * Stores the serialised form of @value at @data. @data should be + * large enough. See g_variant_get_size(). + * + * The stored data is in machine native byte order but may not be in + * fully-normalised form if read from an untrusted source. See + * g_variant_get_normal_form() for a solution. + * + * As with g_variant_get_data(), to be able to deserialise the + * serialised variant successfully, its type and (if the destination + * machine might be different) its endianness must also be available. + * + * This function is approximately O(n) in the size of @data. + * + * Since: 2.24 + **/ +void +g_variant_store (GVariant *value, + gpointer data) +{ + g_variant_lock (value); + + if (value->state & STATE_SERIALISED) + { + if (value->contents.serialised.data != NULL) + memcpy (data, value->contents.serialised.data, value->size); + else + memset (data, 0, value->size); + } + else + g_variant_serialise (value, data); + + g_variant_unlock (value); +} + +/** + * g_variant_is_normal_form: + * @value: a #GVariant instance + * + * Checks if @value is in normal form. + * + * The main reason to do this is to detect if a given chunk of + * serialised data is in normal form: load the data into a #GVariant + * using g_variant_new_from_data() and then use this function to + * check. + * + * If @value is found to be in normal form then it will be marked as + * being trusted. If the value was already marked as being trusted then + * this function will immediately return %TRUE. + * + * Returns: %TRUE if @value is in normal form + * + * Since: 2.24 + **/ +gboolean +g_variant_is_normal_form (GVariant *value) +{ + if (value->state & STATE_TRUSTED) + return TRUE; + + g_variant_lock (value); + + if (value->state & STATE_SERIALISED) + { + GVariantSerialised serialised = { + value->type_info, + (gpointer) value->contents.serialised.data, + value->size + }; + + if (g_variant_serialised_is_normal (serialised)) + value->state |= STATE_TRUSTED; + } + else + { + gboolean normal = TRUE; + gsize i; + + for (i = 0; i < value->contents.tree.n_children; i++) + normal &= g_variant_is_normal_form (value->contents.tree.children[i]); + + if (normal) + value->state |= STATE_TRUSTED; + } + + g_variant_unlock (value); + + return (value->state & STATE_TRUSTED) != 0; +} diff --git a/glib/glib/gvariant-core.h b/glib/glib/gvariant-core.h new file mode 100644 index 0000000..1fd4829 --- /dev/null +++ b/glib/glib/gvariant-core.h @@ -0,0 +1,46 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __G_VARIANT_CORE_H__ +#define __G_VARIANT_CORE_H__ + +#include +#include +#include + +/* gvariant-core.c */ +G_GNUC_INTERNAL +GVariant * g_variant_new_from_bytes (const GVariantType *type, + GBytes *bytes, + gboolean trusted); + +G_GNUC_INTERNAL +GVariant * g_variant_new_from_children (const GVariantType *type, + GVariant **children, + gsize n_children, + gboolean trusted); + +G_GNUC_INTERNAL +gboolean g_variant_is_trusted (GVariant *value); + +G_GNUC_INTERNAL +GVariantTypeInfo * g_variant_get_type_info (GVariant *value); + +#endif /* __G_VARIANT_CORE_H__ */ diff --git a/glib/glib/gvariant-internal.h b/glib/glib/gvariant-internal.h new file mode 100644 index 0000000..66a080a --- /dev/null +++ b/glib/glib/gvariant-internal.h @@ -0,0 +1,49 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + + +/* The purpose of this header is to allow certain internal symbols of + * GVariant to be put under test cases. + */ + +#ifndef __G_VARIANT_INTERNAL_H__ +#define __G_VARIANT_INTERNAL_H__ + +#ifndef GLIB_COMPILATION +#define GLIB_COMPILATION +#endif + +#include +#include + +#include "gvariant-serialiser.h" +#include "gvarianttypeinfo.h" + +gboolean g_variant_format_string_scan (const gchar *string, + const gchar *limit, + const gchar **endptr); + +GVariantType * g_variant_format_string_scan_type (const gchar *string, + const gchar *limit, + const gchar **endptr); + +#endif /* __G_VARIANT_INTERNAL_H__ */ diff --git a/glib/glib/gvariant-parser.c b/glib/glib/gvariant-parser.c new file mode 100644 index 0000000..c0dc8da --- /dev/null +++ b/glib/glib/gvariant-parser.c @@ -0,0 +1,2550 @@ +/* + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include +#include +#include + +#include "gerror.h" +#include "gquark.h" +#include "gstring.h" +#include "gstrfuncs.h" +#include "gtestutils.h" +#include "gvariant.h" +#include "gvarianttype.h" +#include "gslice.h" + +/* + * two-pass algorithm + * designed by ryan lortie and william hua + * designed in itb-229 and at ghazi's, 2009. + */ + +/** + * G_VARIANT_PARSE_ERROR: + * + * Error domain for GVariant text format parsing. Specific error codes + * are not currently defined for this domain. See #GError for + * information on error domains. + **/ +/** + * GVariantParseError: + * @G_VARIANT_PARSE_ERROR_FAILED: generic error (unused) + * @G_VARIANT_PARSE_ERROR_BASIC_TYPE_EXPECTED: a non-basic #GVariantType was given where a basic type was expected + * @G_VARIANT_PARSE_ERROR_CANNOT_INFER_TYPE: cannot infer the #GVariantType + * @G_VARIANT_PARSE_ERROR_DEFINITE_TYPE_EXPECTED: an indefinite #GVariantType was given where a definite type was expected + * @G_VARIANT_PARSE_ERROR_INPUT_NOT_AT_END: extra data after parsing finished + * @G_VARIANT_PARSE_ERROR_INVALID_CHARACTER: invalid character in number or unicode escape + * @G_VARIANT_PARSE_ERROR_INVALID_FORMAT_STRING: not a valid #GVariant format string + * @G_VARIANT_PARSE_ERROR_INVALID_OBJECT_PATH: not a valid object path + * @G_VARIANT_PARSE_ERROR_INVALID_SIGNATURE: not a valid type signature + * @G_VARIANT_PARSE_ERROR_INVALID_TYPE_STRING: not a valid #GVariant type string + * @G_VARIANT_PARSE_ERROR_NO_COMMON_TYPE: could not find a common type for array entries + * @G_VARIANT_PARSE_ERROR_NUMBER_OUT_OF_RANGE: the numerical value is out of range of the given type + * @G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG: the numerical value is out of range for any type + * @G_VARIANT_PARSE_ERROR_TYPE_ERROR: cannot parse as variant of the specified type + * @G_VARIANT_PARSE_ERROR_UNEXPECTED_TOKEN: an unexpected token was encountered + * @G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD: an unknown keyword was encountered + * @G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT: unterminated string constant + * @G_VARIANT_PARSE_ERROR_VALUE_EXPECTED: no value given + * + * Error codes returned by parsing text-format GVariants. + **/ +GQuark +g_variant_parser_get_error_quark (void) +{ + static GQuark the_quark; + + if (the_quark == 0) + the_quark = g_quark_from_static_string ("g-variant-parse-error-quark"); + + return the_quark; +} + +typedef struct +{ + gint start, end; +} SourceRef; + +static void +parser_set_error_va (GError **error, + SourceRef *location, + SourceRef *other, + gint code, + const gchar *format, + va_list ap) +{ + GString *msg = g_string_new (NULL); + + if (location->start == location->end) + g_string_append_printf (msg, "%d", location->start); + else + g_string_append_printf (msg, "%d-%d", location->start, location->end); + + if (other != NULL) + { + g_assert (other->start != other->end); + g_string_append_printf (msg, ",%d-%d", other->start, other->end); + } + g_string_append_c (msg, ':'); + + g_string_append_vprintf (msg, format, ap); + g_set_error_literal (error, G_VARIANT_PARSE_ERROR, code, msg->str); + g_string_free (msg, TRUE); +} + +static void +parser_set_error (GError **error, + SourceRef *location, + SourceRef *other, + gint code, + const gchar *format, + ...) +{ + va_list ap; + + va_start (ap, format); + parser_set_error_va (error, location, other, code, format, ap); + va_end (ap); +} + +typedef struct +{ + const gchar *start; + const gchar *stream; + const gchar *end; + + const gchar *this; +} TokenStream; + + +static void +token_stream_set_error (TokenStream *stream, + GError **error, + gboolean this_token, + gint code, + const gchar *format, + ...) +{ + SourceRef ref; + va_list ap; + + ref.start = stream->this - stream->start; + + if (this_token) + ref.end = stream->stream - stream->start; + else + ref.end = ref.start; + + va_start (ap, format); + parser_set_error_va (error, &ref, NULL, code, format, ap); + va_end (ap); +} + +static gboolean +token_stream_prepare (TokenStream *stream) +{ + gint brackets = 0; + const gchar *end; + + if (stream->this != NULL) + return TRUE; + + while (stream->stream != stream->end && g_ascii_isspace (*stream->stream)) + stream->stream++; + + if (stream->stream == stream->end || *stream->stream == '\0') + { + stream->this = stream->stream; + return FALSE; + } + + switch (stream->stream[0]) + { + case '-': case '+': case '.': case '0': case '1': case '2': + case '3': case '4': case '5': case '6': case '7': case '8': + case '9': + for (end = stream->stream; end != stream->end; end++) + if (!g_ascii_isalnum (*end) && + *end != '-' && *end != '+' && *end != '.') + break; + break; + + case 'b': + if (stream->stream[1] == '\'' || stream->stream[1] == '"') + { + for (end = stream->stream + 2; end != stream->end; end++) + if (*end == stream->stream[1] || *end == '\0' || + (*end == '\\' && (++end == stream->end || *end == '\0'))) + break; + + if (end != stream->end && *end) + end++; + break; + } + + else /* ↓↓↓ */; + + case 'a': /* 'b' */ case 'c': case 'd': case 'e': case 'f': + case 'g': case 'h': case 'i': case 'j': case 'k': case 'l': + case 'm': case 'n': case 'o': case 'p': case 'q': case 'r': + case 's': case 't': case 'u': case 'v': case 'w': case 'x': + case 'y': case 'z': + for (end = stream->stream; end != stream->end; end++) + if (!g_ascii_isalnum (*end)) + break; + break; + + case '\'': case '"': + for (end = stream->stream + 1; end != stream->end; end++) + if (*end == stream->stream[0] || *end == '\0' || + (*end == '\\' && (++end == stream->end || *end == '\0'))) + break; + + if (end != stream->end && *end) + end++; + break; + + case '@': case '%': + /* stop at the first space, comma, colon or unmatched bracket. + * deals nicely with cases like (%i, %i) or {%i: %i}. + */ + for (end = stream->stream + 1; + end != stream->end && *end != ',' && + *end != ':' && *end != '>' && !g_ascii_isspace (*end); + end++) + + if (*end == '(' || *end == '{') + brackets++; + + else if ((*end == ')' || *end == '}') && !brackets--) + break; + + break; + + default: + end = stream->stream + 1; + break; + } + + stream->this = stream->stream; + stream->stream = end; + + return TRUE; +} + +static void +token_stream_next (TokenStream *stream) +{ + stream->this = NULL; +} + +static gboolean +token_stream_peek (TokenStream *stream, + gchar first_char) +{ + if (!token_stream_prepare (stream)) + return FALSE; + + return stream->this[0] == first_char; +} + +static gboolean +token_stream_peek2 (TokenStream *stream, + gchar first_char, + gchar second_char) +{ + if (!token_stream_prepare (stream)) + return FALSE; + + return stream->this[0] == first_char && + stream->this[1] == second_char; +} + +static gboolean +token_stream_is_keyword (TokenStream *stream) +{ + if (!token_stream_prepare (stream)) + return FALSE; + + return g_ascii_isalpha (stream->this[0]) && + g_ascii_isalpha (stream->this[1]); +} + +static gboolean +token_stream_is_numeric (TokenStream *stream) +{ + if (!token_stream_prepare (stream)) + return FALSE; + + return (g_ascii_isdigit (stream->this[0]) || + stream->this[0] == '-' || + stream->this[0] == '+' || + stream->this[0] == '.'); +} + +static gboolean +token_stream_peek_string (TokenStream *stream, + const gchar *token) +{ + gint length = strlen (token); + + return token_stream_prepare (stream) && + stream->stream - stream->this == length && + memcmp (stream->this, token, length) == 0; +} + +static gboolean +token_stream_consume (TokenStream *stream, + const gchar *token) +{ + if (!token_stream_peek_string (stream, token)) + return FALSE; + + token_stream_next (stream); + return TRUE; +} + +static gboolean +token_stream_require (TokenStream *stream, + const gchar *token, + const gchar *purpose, + GError **error) +{ + + if (!token_stream_consume (stream, token)) + { + token_stream_set_error (stream, error, FALSE, + G_VARIANT_PARSE_ERROR_UNEXPECTED_TOKEN, + "expected `%s'%s", token, purpose); + return FALSE; + } + + return TRUE; +} + +static void +token_stream_assert (TokenStream *stream, + const gchar *token) +{ + gboolean correct_token; + + correct_token = token_stream_consume (stream, token); + g_assert (correct_token); +} + +static gchar * +token_stream_get (TokenStream *stream) +{ + gchar *result; + + if (!token_stream_prepare (stream)) + return NULL; + + result = g_strndup (stream->this, stream->stream - stream->this); + + return result; +} + +static void +token_stream_start_ref (TokenStream *stream, + SourceRef *ref) +{ + token_stream_prepare (stream); + ref->start = stream->this - stream->start; +} + +static void +token_stream_end_ref (TokenStream *stream, + SourceRef *ref) +{ + ref->end = stream->stream - stream->start; +} + +static void +pattern_copy (gchar **out, + const gchar **in) +{ + gint brackets = 0; + + while (**in == 'a' || **in == 'm' || **in == 'M') + *(*out)++ = *(*in)++; + + do + { + if (**in == '(' || **in == '{') + brackets++; + + else if (**in == ')' || **in == '}') + brackets--; + + *(*out)++ = *(*in)++; + } + while (brackets); +} + +static gchar * +pattern_coalesce (const gchar *left, + const gchar *right) +{ + gchar *result; + gchar *out; + + /* the length of the output is loosely bound by the sum of the input + * lengths, not simply the greater of the two lengths. + * + * (*(iii)) + ((iii)*) ((iii)(iii)) + * + * 8 + 8 = 12 + */ + out = result = g_malloc (strlen (left) + strlen (right)); + + while (*left && *right) + { + if (*left == *right) + { + *out++ = *left++; + right++; + } + + else + { + const gchar **one = &left, **the_other = &right; + + again: + if (**one == '*' && **the_other != ')') + { + pattern_copy (&out, the_other); + (*one)++; + } + + else if (**one == 'M' && **the_other == 'm') + { + *out++ = *(*the_other)++; + } + + else if (**one == 'M' && **the_other != 'm') + { + (*one)++; + } + + else if (**one == 'N' && strchr ("ynqiuxthd", **the_other)) + { + *out++ = *(*the_other)++; + (*one)++; + } + + else if (**one == 'S' && strchr ("sog", **the_other)) + { + *out++ = *(*the_other)++; + (*one)++; + } + + else if (one == &left) + { + one = &right, the_other = &left; + goto again; + } + + else + break; + } + } + + if (*left || *right) + { + g_free (result); + result = NULL; + } + else + *out++ = '\0'; + + return result; +} + +typedef struct _AST AST; +typedef gchar * (*get_pattern_func) (AST *ast, + GError **error); +typedef GVariant * (*get_value_func) (AST *ast, + const GVariantType *type, + GError **error); +typedef GVariant * (*get_base_value_func) (AST *ast, + const GVariantType *type, + GError **error); +typedef void (*free_func) (AST *ast); + +typedef struct +{ + gchar * (* get_pattern) (AST *ast, + GError **error); + GVariant * (* get_value) (AST *ast, + const GVariantType *type, + GError **error); + GVariant * (* get_base_value) (AST *ast, + const GVariantType *type, + GError **error); + void (* free) (AST *ast); +} ASTClass; + +struct _AST +{ + const ASTClass *class; + SourceRef source_ref; +}; + +static gchar * +ast_get_pattern (AST *ast, + GError **error) +{ + return ast->class->get_pattern (ast, error); +} + +static GVariant * +ast_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + return ast->class->get_value (ast, type, error); +} + +static void +ast_free (AST *ast) +{ + ast->class->free (ast); +} + +static void +ast_set_error (AST *ast, + GError **error, + AST *other_ast, + gint code, + const gchar *format, + ...) +{ + va_list ap; + + va_start (ap, format); + parser_set_error_va (error, &ast->source_ref, + other_ast ? & other_ast->source_ref : NULL, + code, + format, ap); + va_end (ap); +} + +static GVariant * +ast_type_error (AST *ast, + const GVariantType *type, + GError **error) +{ + gchar *typestr; + + typestr = g_variant_type_dup_string (type); + ast_set_error (ast, error, NULL, + G_VARIANT_PARSE_ERROR_TYPE_ERROR, + "can not parse as value of type `%s'", + typestr); + g_free (typestr); + + return NULL; +} + +static GVariant * +ast_resolve (AST *ast, + GError **error) +{ + GVariant *value; + gchar *pattern; + gint i, j = 0; + + pattern = ast_get_pattern (ast, error); + + if (pattern == NULL) + return NULL; + + /* choose reasonable defaults + * + * 1) favour non-maybe values where possible + * 2) default type for strings is 's' + * 3) default type for integers is 'i' + */ + for (i = 0; pattern[i]; i++) + switch (pattern[i]) + { + case '*': + ast_set_error (ast, error, NULL, + G_VARIANT_PARSE_ERROR_CANNOT_INFER_TYPE, + "unable to infer type"); + g_free (pattern); + return NULL; + + case 'M': + break; + + case 'S': + pattern[j++] = 's'; + break; + + case 'N': + pattern[j++] = 'i'; + break; + + default: + pattern[j++] = pattern[i]; + break; + } + pattern[j++] = '\0'; + + value = ast_get_value (ast, G_VARIANT_TYPE (pattern), error); + g_free (pattern); + + return value; +} + + +static AST *parse (TokenStream *stream, + va_list *app, + GError **error); + +static void +ast_array_append (AST ***array, + gint *n_items, + AST *ast) +{ + if ((*n_items & (*n_items - 1)) == 0) + *array = g_renew (AST *, *array, *n_items ? 2 ** n_items : 1); + + (*array)[(*n_items)++] = ast; +} + +static void +ast_array_free (AST **array, + gint n_items) +{ + gint i; + + for (i = 0; i < n_items; i++) + ast_free (array[i]); + g_free (array); +} + +static gchar * +ast_array_get_pattern (AST **array, + gint n_items, + GError **error) +{ + gchar *pattern; + gint i; + + pattern = ast_get_pattern (array[0], error); + + if (pattern == NULL) + return NULL; + + for (i = 1; i < n_items; i++) + { + gchar *tmp, *merged; + + tmp = ast_get_pattern (array[i], error); + + if (tmp == NULL) + { + g_free (pattern); + return NULL; + } + + merged = pattern_coalesce (pattern, tmp); + g_free (pattern); + pattern = merged; + + if (merged == NULL) + /* set coalescence implies pairwise coalescence (i think). + * we should therefore be able to trace the failure to a single + * pair of values. + */ + { + int j = 0; + + while (TRUE) + { + gchar *tmp2; + gchar *m; + + /* if 'j' reaches 'i' then we failed to find the pair */ + g_assert (j < i); + + tmp2 = ast_get_pattern (array[j], NULL); + g_assert (tmp2 != NULL); + + m = pattern_coalesce (tmp, tmp2); + g_free (tmp2); + g_free (m); + + if (m == NULL) + { + /* we found a conflict between 'i' and 'j'. + * + * report the error. note: 'j' is first. + */ + ast_set_error (array[j], error, array[i], + G_VARIANT_PARSE_ERROR_NO_COMMON_TYPE, + "unable to find a common type"); + g_free (tmp); + return NULL; + } + + j++; + } + + } + + g_free (tmp); + } + + return pattern; +} + +typedef struct +{ + AST ast; + + AST *child; +} Maybe; + +static gchar * +maybe_get_pattern (AST *ast, + GError **error) +{ + Maybe *maybe = (Maybe *) ast; + + if (maybe->child != NULL) + { + gchar *child_pattern; + gchar *pattern; + + child_pattern = ast_get_pattern (maybe->child, error); + + if (child_pattern == NULL) + return NULL; + + pattern = g_strdup_printf ("m%s", child_pattern); + g_free (child_pattern); + + return pattern; + } + + return g_strdup ("m*"); +} + +static GVariant * +maybe_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + Maybe *maybe = (Maybe *) ast; + GVariant *value; + + if (!g_variant_type_is_maybe (type)) + return ast_type_error (ast, type, error); + + type = g_variant_type_element (type); + + if (maybe->child) + { + value = ast_get_value (maybe->child, type, error); + + if (value == NULL) + return NULL; + } + else + value = NULL; + + return g_variant_new_maybe (type, value); +} + +static void +maybe_free (AST *ast) +{ + Maybe *maybe = (Maybe *) ast; + + if (maybe->child != NULL) + ast_free (maybe->child); + + g_slice_free (Maybe, maybe); +} + +static AST * +maybe_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass maybe_class = { + maybe_get_pattern, + maybe_get_value, NULL, + maybe_free + }; + AST *child = NULL; + Maybe *maybe; + + if (token_stream_consume (stream, "just")) + { + child = parse (stream, app, error); + if (child == NULL) + return NULL; + } + + else if (!token_stream_consume (stream, "nothing")) + { + token_stream_set_error (stream, error, TRUE, + G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD, + "unknown keyword"); + return NULL; + } + + maybe = g_slice_new (Maybe); + maybe->ast.class = &maybe_class; + maybe->child = child; + + return (AST *) maybe; +} + +static GVariant * +maybe_wrapper (AST *ast, + const GVariantType *type, + GError **error) +{ + const GVariantType *t; + GVariant *value; + int depth; + + for (depth = 0, t = type; + g_variant_type_is_maybe (t); + depth++, t = g_variant_type_element (t)); + + value = ast->class->get_base_value (ast, t, error); + + if (value == NULL) + return NULL; + + while (depth--) + value = g_variant_new_maybe (NULL, value); + + return value; +} + +typedef struct +{ + AST ast; + + AST **children; + gint n_children; +} Array; + +static gchar * +array_get_pattern (AST *ast, + GError **error) +{ + Array *array = (Array *) ast; + gchar *pattern; + gchar *result; + + if (array->n_children == 0) + return g_strdup ("Ma*"); + + pattern = ast_array_get_pattern (array->children, array->n_children, error); + + if (pattern == NULL) + return NULL; + + result = g_strdup_printf ("Ma%s", pattern); + g_free (pattern); + + return result; +} + +static GVariant * +array_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + Array *array = (Array *) ast; + const GVariantType *childtype; + GVariantBuilder builder; + gint i; + + if (!g_variant_type_is_array (type)) + return ast_type_error (ast, type, error); + + g_variant_builder_init (&builder, type); + childtype = g_variant_type_element (type); + + for (i = 0; i < array->n_children; i++) + { + GVariant *child; + + if (!(child = ast_get_value (array->children[i], childtype, error))) + { + g_variant_builder_clear (&builder); + return NULL; + } + + g_variant_builder_add_value (&builder, child); + } + + return g_variant_builder_end (&builder); +} + +static void +array_free (AST *ast) +{ + Array *array = (Array *) ast; + + ast_array_free (array->children, array->n_children); + g_slice_free (Array, array); +} + +static AST * +array_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass array_class = { + array_get_pattern, + maybe_wrapper, array_get_value, + array_free + }; + gboolean need_comma = FALSE; + Array *array; + + array = g_slice_new (Array); + array->ast.class = &array_class; + array->children = NULL; + array->n_children = 0; + + token_stream_assert (stream, "["); + while (!token_stream_consume (stream, "]")) + { + AST *child; + + if (need_comma && + !token_stream_require (stream, ",", + " or `]' to follow array element", + error)) + goto error; + + child = parse (stream, app, error); + + if (!child) + goto error; + + ast_array_append (&array->children, &array->n_children, child); + need_comma = TRUE; + } + + return (AST *) array; + + error: + ast_array_free (array->children, array->n_children); + g_slice_free (Array, array); + + return NULL; +} + +typedef struct +{ + AST ast; + + AST **children; + gint n_children; +} Tuple; + +static gchar * +tuple_get_pattern (AST *ast, + GError **error) +{ + Tuple *tuple = (Tuple *) ast; + gchar *result = NULL; + gchar **parts; + gint i; + + parts = g_new (gchar *, tuple->n_children + 4); + parts[tuple->n_children + 1] = (gchar *) ")"; + parts[tuple->n_children + 2] = NULL; + parts[0] = (gchar *) "M("; + + for (i = 0; i < tuple->n_children; i++) + if (!(parts[i + 1] = ast_get_pattern (tuple->children[i], error))) + break; + + if (i == tuple->n_children) + result = g_strjoinv ("", parts); + + /* parts[0] should not be freed */ + while (i) + g_free (parts[i--]); + g_free (parts); + + return result; +} + +static GVariant * +tuple_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + Tuple *tuple = (Tuple *) ast; + const GVariantType *childtype; + GVariantBuilder builder; + gint i; + + if (!g_variant_type_is_tuple (type)) + return ast_type_error (ast, type, error); + + g_variant_builder_init (&builder, type); + childtype = g_variant_type_first (type); + + for (i = 0; i < tuple->n_children; i++) + { + GVariant *child; + + if (childtype == NULL) + { + g_variant_builder_clear (&builder); + return ast_type_error (ast, type, error); + } + + if (!(child = ast_get_value (tuple->children[i], childtype, error))) + { + g_variant_builder_clear (&builder); + return FALSE; + } + + g_variant_builder_add_value (&builder, child); + childtype = g_variant_type_next (childtype); + } + + if (childtype != NULL) + { + g_variant_builder_clear (&builder); + return ast_type_error (ast, type, error); + } + + return g_variant_builder_end (&builder); +} + +static void +tuple_free (AST *ast) +{ + Tuple *tuple = (Tuple *) ast; + + ast_array_free (tuple->children, tuple->n_children); + g_slice_free (Tuple, tuple); +} + +static AST * +tuple_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass tuple_class = { + tuple_get_pattern, + maybe_wrapper, tuple_get_value, + tuple_free + }; + gboolean need_comma = FALSE; + gboolean first = TRUE; + Tuple *tuple; + + tuple = g_slice_new (Tuple); + tuple->ast.class = &tuple_class; + tuple->children = NULL; + tuple->n_children = 0; + + token_stream_assert (stream, "("); + while (!token_stream_consume (stream, ")")) + { + AST *child; + + if (need_comma && + !token_stream_require (stream, ",", + " or `)' to follow tuple element", + error)) + goto error; + + child = parse (stream, app, error); + + if (!child) + goto error; + + ast_array_append (&tuple->children, &tuple->n_children, child); + + /* the first time, we absolutely require a comma, so grab it here + * and leave need_comma = FALSE so that the code above doesn't + * require a second comma. + * + * the second and remaining times, we set need_comma = TRUE. + */ + if (first) + { + if (!token_stream_require (stream, ",", + " after first tuple element", error)) + goto error; + + first = FALSE; + } + else + need_comma = TRUE; + } + + return (AST *) tuple; + + error: + ast_array_free (tuple->children, tuple->n_children); + g_slice_free (Tuple, tuple); + + return NULL; +} + +typedef struct +{ + AST ast; + + AST *value; +} Variant; + +static gchar * +variant_get_pattern (AST *ast, + GError **error) +{ + return g_strdup ("Mv"); +} + +static GVariant * +variant_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + Variant *variant = (Variant *) ast; + GVariant *child; + + g_assert (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT)); + child = ast_resolve (variant->value, error); + + if (child == NULL) + return NULL; + + return g_variant_new_variant (child); +} + +static void +variant_free (AST *ast) +{ + Variant *variant = (Variant *) ast; + + ast_free (variant->value); + g_slice_free (Variant, variant); +} + +static AST * +variant_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass variant_class = { + variant_get_pattern, + maybe_wrapper, variant_get_value, + variant_free + }; + Variant *variant; + AST *value; + + token_stream_assert (stream, "<"); + value = parse (stream, app, error); + + if (!value) + return NULL; + + if (!token_stream_require (stream, ">", " to follow variant value", error)) + { + ast_free (value); + return NULL; + } + + variant = g_slice_new (Variant); + variant->ast.class = &variant_class; + variant->value = value; + + return (AST *) variant; +} + +typedef struct +{ + AST ast; + + AST **keys; + AST **values; + gint n_children; +} Dictionary; + +static gchar * +dictionary_get_pattern (AST *ast, + GError **error) +{ + Dictionary *dict = (Dictionary *) ast; + gchar *value_pattern; + gchar *key_pattern; + gchar key_char; + gchar *result; + + if (dict->n_children == 0) + return g_strdup ("Ma{**}"); + + key_pattern = ast_array_get_pattern (dict->keys, + abs (dict->n_children), + error); + + if (key_pattern == NULL) + return NULL; + + /* we can not have maybe keys */ + if (key_pattern[0] == 'M') + key_char = key_pattern[1]; + else + key_char = key_pattern[0]; + + g_free (key_pattern); + + /* the basic types, + * plus undetermined number type and undetermined string type. + */ + if (!strchr ("bynqiuxthdsogNS", key_char)) + { + ast_set_error (ast, error, NULL, + G_VARIANT_PARSE_ERROR_BASIC_TYPE_EXPECTED, + "dictionary keys must have basic types"); + return NULL; + } + + value_pattern = ast_get_pattern (dict->values[0], error); + + if (value_pattern == NULL) + return NULL; + + result = g_strdup_printf ("M%s{%c%s}", + dict->n_children > 0 ? "a" : "", + key_char, value_pattern); + g_free (value_pattern); + + return result; +} + +static GVariant * +dictionary_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + Dictionary *dict = (Dictionary *) ast; + + if (dict->n_children == -1) + { + const GVariantType *subtype; + GVariantBuilder builder; + GVariant *subvalue; + + if (!g_variant_type_is_dict_entry (type)) + return ast_type_error (ast, type, error); + + g_variant_builder_init (&builder, type); + + subtype = g_variant_type_key (type); + if (!(subvalue = ast_get_value (dict->keys[0], subtype, error))) + { + g_variant_builder_clear (&builder); + return NULL; + } + g_variant_builder_add_value (&builder, subvalue); + + subtype = g_variant_type_value (type); + if (!(subvalue = ast_get_value (dict->values[0], subtype, error))) + { + g_variant_builder_clear (&builder); + return NULL; + } + g_variant_builder_add_value (&builder, subvalue); + + return g_variant_builder_end (&builder); + } + else + { + const GVariantType *entry, *key, *val; + GVariantBuilder builder; + gint i; + + if (!g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_DICTIONARY)) + return ast_type_error (ast, type, error); + + entry = g_variant_type_element (type); + key = g_variant_type_key (entry); + val = g_variant_type_value (entry); + + g_variant_builder_init (&builder, type); + + for (i = 0; i < dict->n_children; i++) + { + GVariant *subvalue; + + g_variant_builder_open (&builder, entry); + + if (!(subvalue = ast_get_value (dict->keys[i], key, error))) + { + g_variant_builder_clear (&builder); + return NULL; + } + g_variant_builder_add_value (&builder, subvalue); + + if (!(subvalue = ast_get_value (dict->values[i], val, error))) + { + g_variant_builder_clear (&builder); + return NULL; + } + g_variant_builder_add_value (&builder, subvalue); + g_variant_builder_close (&builder); + } + + return g_variant_builder_end (&builder); + } +} + +static void +dictionary_free (AST *ast) +{ + Dictionary *dict = (Dictionary *) ast; + gint n_children; + + if (dict->n_children > -1) + n_children = dict->n_children; + else + n_children = 1; + + ast_array_free (dict->keys, n_children); + ast_array_free (dict->values, n_children); + g_slice_free (Dictionary, dict); +} + +static AST * +dictionary_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass dictionary_class = { + dictionary_get_pattern, + maybe_wrapper, dictionary_get_value, + dictionary_free + }; + gint n_keys, n_values; + gboolean only_one; + Dictionary *dict; + AST *first; + + dict = g_slice_new (Dictionary); + dict->ast.class = &dictionary_class; + dict->keys = NULL; + dict->values = NULL; + n_keys = n_values = 0; + + token_stream_assert (stream, "{"); + + if (token_stream_consume (stream, "}")) + { + dict->n_children = 0; + return (AST *) dict; + } + + if ((first = parse (stream, app, error)) == NULL) + goto error; + + ast_array_append (&dict->keys, &n_keys, first); + + only_one = token_stream_consume (stream, ","); + if (!only_one && + !token_stream_require (stream, ":", + " or `,' to follow dictionary entry key", + error)) + goto error; + + if ((first = parse (stream, app, error)) == NULL) + goto error; + + ast_array_append (&dict->values, &n_values, first); + + if (only_one) + { + if (!token_stream_require (stream, "}", " at end of dictionary entry", + error)) + goto error; + + g_assert (n_keys == 1 && n_values == 1); + dict->n_children = -1; + + return (AST *) dict; + } + + while (!token_stream_consume (stream, "}")) + { + AST *child; + + if (!token_stream_require (stream, ",", + " or `}' to follow dictionary entry", error)) + goto error; + + child = parse (stream, app, error); + + if (!child) + goto error; + + ast_array_append (&dict->keys, &n_keys, child); + + if (!token_stream_require (stream, ":", + " to follow dictionary entry key", error)) + goto error; + + child = parse (stream, app, error); + + if (!child) + goto error; + + ast_array_append (&dict->values, &n_values, child); + } + + g_assert (n_keys == n_values); + dict->n_children = n_keys; + + return (AST *) dict; + + error: + ast_array_free (dict->keys, n_keys); + ast_array_free (dict->values, n_values); + g_slice_free (Dictionary, dict); + + return NULL; +} + +typedef struct +{ + AST ast; + gchar *string; +} String; + +static gchar * +string_get_pattern (AST *ast, + GError **error) +{ + return g_strdup ("MS"); +} + +static GVariant * +string_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + String *string = (String *) ast; + + if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING)) + return g_variant_new_string (string->string); + + else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH)) + { + if (!g_variant_is_object_path (string->string)) + { + ast_set_error (ast, error, NULL, + G_VARIANT_PARSE_ERROR_INVALID_OBJECT_PATH, + "not a valid object path"); + return NULL; + } + + return g_variant_new_object_path (string->string); + } + + else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE)) + { + if (!g_variant_is_signature (string->string)) + { + ast_set_error (ast, error, NULL, + G_VARIANT_PARSE_ERROR_INVALID_SIGNATURE, + "not a valid signature"); + return NULL; + } + + return g_variant_new_signature (string->string); + } + + else + return ast_type_error (ast, type, error); +} + +static void +string_free (AST *ast) +{ + String *string = (String *) ast; + + g_free (string->string); + g_slice_free (String, string); +} + +static gboolean +unicode_unescape (const gchar *src, + gint *src_ofs, + gchar *dest, + gint *dest_ofs, + gint length, + SourceRef *ref, + GError **error) +{ + gchar buffer[9]; + guint64 value; + gchar *end; + + (*src_ofs)++; + + g_assert (length < sizeof (buffer)); + strncpy (buffer, src + *src_ofs, length); + buffer[length] = '\0'; + + value = g_ascii_strtoull (buffer, &end, 0x10); + + if (value == 0 || end != buffer + length) + { + parser_set_error (error, ref, NULL, + G_VARIANT_PARSE_ERROR_INVALID_CHARACTER, + "invalid %d-character unicode escape", length); + return FALSE; + } + + g_assert (value <= G_MAXUINT32); + + *dest_ofs += g_unichar_to_utf8 (value, dest + *dest_ofs); + *src_ofs += length; + + return TRUE; +} + +static AST * +string_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass string_class = { + string_get_pattern, + maybe_wrapper, string_get_value, + string_free + }; + String *string; + SourceRef ref; + gchar *token; + gsize length; + gchar quote; + gchar *str; + gint i, j; + + token_stream_start_ref (stream, &ref); + token = token_stream_get (stream); + token_stream_end_ref (stream, &ref); + length = strlen (token); + quote = token[0]; + + str = g_malloc (length); + g_assert (quote == '"' || quote == '\''); + j = 0; + i = 1; + while (token[i] != quote) + switch (token[i]) + { + case '\0': + parser_set_error (error, &ref, NULL, + G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT, + "unterminated string constant"); + g_free (token); + g_free (str); + return NULL; + + case '\\': + switch (token[++i]) + { + case '\0': + parser_set_error (error, &ref, NULL, + G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT, + "unterminated string constant"); + g_free (token); + g_free (str); + return NULL; + + case 'u': + if (!unicode_unescape (token, &i, str, &j, 4, &ref, error)) + { + g_free (token); + g_free (str); + return NULL; + } + continue; + + case 'U': + if (!unicode_unescape (token, &i, str, &j, 8, &ref, error)) + { + g_free (token); + g_free (str); + return NULL; + } + continue; + + case 'a': str[j++] = '\a'; i++; continue; + case 'b': str[j++] = '\b'; i++; continue; + case 'f': str[j++] = '\f'; i++; continue; + case 'n': str[j++] = '\n'; i++; continue; + case 'r': str[j++] = '\r'; i++; continue; + case 't': str[j++] = '\t'; i++; continue; + case 'v': str[j++] = '\v'; i++; continue; + case '\n': i++; continue; + } + + default: + str[j++] = token[i++]; + } + str[j++] = '\0'; + g_free (token); + + string = g_slice_new (String); + string->ast.class = &string_class; + string->string = str; + + token_stream_next (stream); + + return (AST *) string; +} + +typedef struct +{ + AST ast; + gchar *string; +} ByteString; + +static gchar * +bytestring_get_pattern (AST *ast, + GError **error) +{ + return g_strdup ("May"); +} + +static GVariant * +bytestring_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + ByteString *string = (ByteString *) ast; + + g_assert (g_variant_type_equal (type, G_VARIANT_TYPE_BYTESTRING)); + + return g_variant_new_bytestring (string->string); +} + +static void +bytestring_free (AST *ast) +{ + ByteString *string = (ByteString *) ast; + + g_free (string->string); + g_slice_free (ByteString, string); +} + +static AST * +bytestring_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass bytestring_class = { + bytestring_get_pattern, + maybe_wrapper, bytestring_get_value, + bytestring_free + }; + ByteString *string; + SourceRef ref; + gchar *token; + gsize length; + gchar quote; + gchar *str; + gint i, j; + + token_stream_start_ref (stream, &ref); + token = token_stream_get (stream); + token_stream_end_ref (stream, &ref); + g_assert (token[0] == 'b'); + length = strlen (token); + quote = token[1]; + + str = g_malloc (length); + g_assert (quote == '"' || quote == '\''); + j = 0; + i = 2; + while (token[i] != quote) + switch (token[i]) + { + case '\0': + parser_set_error (error, &ref, NULL, + G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT, + "unterminated string constant"); + g_free (token); + return NULL; + + case '\\': + switch (token[++i]) + { + case '\0': + parser_set_error (error, &ref, NULL, + G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT, + "unterminated string constant"); + g_free (token); + return NULL; + + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + { + /* up to 3 characters */ + guchar val = token[i++] - '0'; + + if ('0' <= token[i] && token[i] < '8') + val = (val << 3) | (token[i++] - '0'); + + if ('0' <= token[i] && token[i] < '8') + val = (val << 3) | (token[i++] - '0'); + + str[j++] = val; + } + continue; + + case 'a': str[j++] = '\a'; i++; continue; + case 'b': str[j++] = '\b'; i++; continue; + case 'f': str[j++] = '\f'; i++; continue; + case 'n': str[j++] = '\n'; i++; continue; + case 'r': str[j++] = '\r'; i++; continue; + case 't': str[j++] = '\t'; i++; continue; + case 'v': str[j++] = '\v'; i++; continue; + case '\n': i++; continue; + } + + default: + str[j++] = token[i++]; + } + str[j++] = '\0'; + g_free (token); + + string = g_slice_new (ByteString); + string->ast.class = &bytestring_class; + string->string = str; + + token_stream_next (stream); + + return (AST *) string; +} + +typedef struct +{ + AST ast; + + gchar *token; +} Number; + +static gchar * +number_get_pattern (AST *ast, + GError **error) +{ + Number *number = (Number *) ast; + + if (strchr (number->token, '.') || + (!g_str_has_prefix (number->token, "0x") && strchr (number->token, 'e')) || + strstr (number->token, "inf") || + strstr (number->token, "nan")) + return g_strdup ("Md"); + + return g_strdup ("MN"); +} + +static GVariant * +number_overflow (AST *ast, + const GVariantType *type, + GError **error) +{ + ast_set_error (ast, error, NULL, + G_VARIANT_PARSE_ERROR_NUMBER_OUT_OF_RANGE, + "number out of range for type `%c'", + g_variant_type_peek_string (type)[0]); + return NULL; +} + +static GVariant * +number_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + Number *number = (Number *) ast; + const gchar *token; + gboolean negative; + gboolean floating; + guint64 abs_val; + gdouble dbl_val; + gchar *end; + + token = number->token; + + if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE)) + { + floating = TRUE; + + errno = 0; + dbl_val = g_ascii_strtod (token, &end); + if (dbl_val != 0.0 && errno == ERANGE) + { + ast_set_error (ast, error, NULL, + G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG, + "number too big for any type"); + return NULL; + } + + /* silence uninitialised warnings... */ + negative = FALSE; + abs_val = 0; + } + else + { + floating = FALSE; + negative = token[0] == '-'; + if (token[0] == '-') + token++; + + errno = 0; + abs_val = g_ascii_strtoull (token, &end, 0); + if (abs_val == G_MAXUINT64 && errno == ERANGE) + { + ast_set_error (ast, error, NULL, + G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG, + "integer too big for any type"); + return NULL; + } + + if (abs_val == 0) + negative = FALSE; + + /* silence uninitialised warning... */ + dbl_val = 0.0; + } + + if (*end != '\0') + { + SourceRef ref; + + ref = ast->source_ref; + ref.start += end - number->token; + ref.end = ref.start + 1; + + parser_set_error (error, &ref, NULL, + G_VARIANT_PARSE_ERROR_INVALID_CHARACTER, + "invalid character in number"); + return NULL; + } + + if (floating) + return g_variant_new_double (dbl_val); + + switch (*g_variant_type_peek_string (type)) + { + case 'y': + if (negative || abs_val > G_MAXUINT8) + return number_overflow (ast, type, error); + return g_variant_new_byte (abs_val); + + case 'n': + if (abs_val - negative > G_MAXINT16) + return number_overflow (ast, type, error); + return g_variant_new_int16 (negative ? -abs_val : abs_val); + + case 'q': + if (negative || abs_val > G_MAXUINT16) + return number_overflow (ast, type, error); + return g_variant_new_uint16 (abs_val); + + case 'i': + if (abs_val - negative > G_MAXINT32) + return number_overflow (ast, type, error); + return g_variant_new_int32 (negative ? -abs_val : abs_val); + + case 'u': + if (negative || abs_val > G_MAXUINT32) + return number_overflow (ast, type, error); + return g_variant_new_uint32 (abs_val); + + case 'x': + if (abs_val - negative > G_MAXINT64) + return number_overflow (ast, type, error); + return g_variant_new_int64 (negative ? -abs_val : abs_val); + + case 't': + if (negative) + return number_overflow (ast, type, error); + return g_variant_new_uint64 (abs_val); + + case 'h': + if (abs_val - negative > G_MAXINT32) + return number_overflow (ast, type, error); + return g_variant_new_handle (negative ? -abs_val : abs_val); + + default: + return ast_type_error (ast, type, error); + } +} + +static void +number_free (AST *ast) +{ + Number *number = (Number *) ast; + + g_free (number->token); + g_slice_free (Number, number); +} + +static AST * +number_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass number_class = { + number_get_pattern, + maybe_wrapper, number_get_value, + number_free + }; + Number *number; + + number = g_slice_new (Number); + number->ast.class = &number_class; + number->token = token_stream_get (stream); + token_stream_next (stream); + + return (AST *) number; +} + +typedef struct +{ + AST ast; + gboolean value; +} Boolean; + +static gchar * +boolean_get_pattern (AST *ast, + GError **error) +{ + return g_strdup ("Mb"); +} + +static GVariant * +boolean_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + Boolean *boolean = (Boolean *) ast; + + if (!g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN)) + return ast_type_error (ast, type, error); + + return g_variant_new_boolean (boolean->value); +} + +static void +boolean_free (AST *ast) +{ + Boolean *boolean = (Boolean *) ast; + + g_slice_free (Boolean, boolean); +} + +static AST * +boolean_new (gboolean value) +{ + static const ASTClass boolean_class = { + boolean_get_pattern, + maybe_wrapper, boolean_get_value, + boolean_free + }; + Boolean *boolean; + + boolean = g_slice_new (Boolean); + boolean->ast.class = &boolean_class; + boolean->value = value; + + return (AST *) boolean; +} + +typedef struct +{ + AST ast; + + GVariant *value; +} Positional; + +static gchar * +positional_get_pattern (AST *ast, + GError **error) +{ + Positional *positional = (Positional *) ast; + + return g_strdup (g_variant_get_type_string (positional->value)); +} + +static GVariant * +positional_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + Positional *positional = (Positional *) ast; + GVariant *value; + + g_assert (positional->value != NULL); + + if G_UNLIKELY (!g_variant_is_of_type (positional->value, type)) + return ast_type_error (ast, type, error); + + /* NOTE: if _get is called more than once then + * things get messed up with respect to floating refs. + * + * fortunately, this function should only ever get called once. + */ + g_assert (positional->value != NULL); + value = positional->value; + positional->value = NULL; + + return value; +} + +static void +positional_free (AST *ast) +{ + Positional *positional = (Positional *) ast; + + /* if positional->value is set, just leave it. + * memory management doesn't matter in case of programmer error. + */ + g_slice_free (Positional, positional); +} + +static AST * +positional_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass positional_class = { + positional_get_pattern, + positional_get_value, NULL, + positional_free + }; + Positional *positional; + const gchar *endptr; + gchar *token; + + token = token_stream_get (stream); + g_assert (token[0] == '%'); + + positional = g_slice_new (Positional); + positional->ast.class = &positional_class; + positional->value = g_variant_new_va (token + 1, &endptr, app); + + if (*endptr || positional->value == NULL) + { + token_stream_set_error (stream, error, TRUE, + G_VARIANT_PARSE_ERROR_INVALID_FORMAT_STRING, + "invalid GVariant format string"); + /* memory management doesn't matter in case of programmer error. */ + return NULL; + } + + token_stream_next (stream); + g_free (token); + + return (AST *) positional; +} + +typedef struct +{ + AST ast; + + GVariantType *type; + AST *child; +} TypeDecl; + +static gchar * +typedecl_get_pattern (AST *ast, + GError **error) +{ + TypeDecl *decl = (TypeDecl *) ast; + + return g_variant_type_dup_string (decl->type); +} + +static GVariant * +typedecl_get_value (AST *ast, + const GVariantType *type, + GError **error) +{ + TypeDecl *decl = (TypeDecl *) ast; + + return ast_get_value (decl->child, type, error); +} + +static void +typedecl_free (AST *ast) +{ + TypeDecl *decl = (TypeDecl *) ast; + + ast_free (decl->child); + g_variant_type_free (decl->type); + g_slice_free (TypeDecl, decl); +} + +static AST * +typedecl_parse (TokenStream *stream, + va_list *app, + GError **error) +{ + static const ASTClass typedecl_class = { + typedecl_get_pattern, + typedecl_get_value, NULL, + typedecl_free + }; + GVariantType *type; + TypeDecl *decl; + AST *child; + + if (token_stream_peek (stream, '@')) + { + gchar *token; + + token = token_stream_get (stream); + + if (!g_variant_type_string_is_valid (token + 1)) + { + token_stream_set_error (stream, error, TRUE, + G_VARIANT_PARSE_ERROR_INVALID_TYPE_STRING, + "invalid type declaration"); + g_free (token); + + return NULL; + } + + type = g_variant_type_new (token + 1); + + if (!g_variant_type_is_definite (type)) + { + token_stream_set_error (stream, error, TRUE, + G_VARIANT_PARSE_ERROR_DEFINITE_TYPE_EXPECTED, + "type declarations must be definite"); + g_variant_type_free (type); + g_free (token); + + return NULL; + } + + token_stream_next (stream); + g_free (token); + } + else + { + if (token_stream_consume (stream, "boolean")) + type = g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN); + + else if (token_stream_consume (stream, "byte")) + type = g_variant_type_copy (G_VARIANT_TYPE_BYTE); + + else if (token_stream_consume (stream, "int16")) + type = g_variant_type_copy (G_VARIANT_TYPE_INT16); + + else if (token_stream_consume (stream, "uint16")) + type = g_variant_type_copy (G_VARIANT_TYPE_UINT16); + + else if (token_stream_consume (stream, "int32")) + type = g_variant_type_copy (G_VARIANT_TYPE_INT32); + + else if (token_stream_consume (stream, "handle")) + type = g_variant_type_copy (G_VARIANT_TYPE_HANDLE); + + else if (token_stream_consume (stream, "uint32")) + type = g_variant_type_copy (G_VARIANT_TYPE_UINT32); + + else if (token_stream_consume (stream, "int64")) + type = g_variant_type_copy (G_VARIANT_TYPE_INT64); + + else if (token_stream_consume (stream, "uint64")) + type = g_variant_type_copy (G_VARIANT_TYPE_UINT64); + + else if (token_stream_consume (stream, "double")) + type = g_variant_type_copy (G_VARIANT_TYPE_DOUBLE); + + else if (token_stream_consume (stream, "string")) + type = g_variant_type_copy (G_VARIANT_TYPE_STRING); + + else if (token_stream_consume (stream, "objectpath")) + type = g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH); + + else if (token_stream_consume (stream, "signature")) + type = g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE); + + else + { + token_stream_set_error (stream, error, TRUE, + G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD, + "unknown keyword"); + return NULL; + } + } + + if ((child = parse (stream, app, error)) == NULL) + { + g_variant_type_free (type); + return NULL; + } + + decl = g_slice_new (TypeDecl); + decl->ast.class = &typedecl_class; + decl->type = type; + decl->child = child; + + return (AST *) decl; +} + +static AST * +parse (TokenStream *stream, + va_list *app, + GError **error) +{ + SourceRef source_ref; + AST *result; + + token_stream_prepare (stream); + token_stream_start_ref (stream, &source_ref); + + if (token_stream_peek (stream, '[')) + result = array_parse (stream, app, error); + + else if (token_stream_peek (stream, '(')) + result = tuple_parse (stream, app, error); + + else if (token_stream_peek (stream, '<')) + result = variant_parse (stream, app, error); + + else if (token_stream_peek (stream, '{')) + result = dictionary_parse (stream, app, error); + + else if (app && token_stream_peek (stream, '%')) + result = positional_parse (stream, app, error); + + else if (token_stream_consume (stream, "true")) + result = boolean_new (TRUE); + + else if (token_stream_consume (stream, "false")) + result = boolean_new (FALSE); + + else if (token_stream_is_numeric (stream) || + token_stream_peek_string (stream, "inf") || + token_stream_peek_string (stream, "nan")) + result = number_parse (stream, app, error); + + else if (token_stream_peek (stream, 'n') || + token_stream_peek (stream, 'j')) + result = maybe_parse (stream, app, error); + + else if (token_stream_peek (stream, '@') || + token_stream_is_keyword (stream)) + result = typedecl_parse (stream, app, error); + + else if (token_stream_peek (stream, '\'') || + token_stream_peek (stream, '"')) + result = string_parse (stream, app, error); + + else if (token_stream_peek2 (stream, 'b', '\'') || + token_stream_peek2 (stream, 'b', '"')) + result = bytestring_parse (stream, app, error); + + else + { + token_stream_set_error (stream, error, FALSE, + G_VARIANT_PARSE_ERROR_VALUE_EXPECTED, + "expected value"); + return NULL; + } + + if (result != NULL) + { + token_stream_end_ref (stream, &source_ref); + result->source_ref = source_ref; + } + + return result; +} + +/** + * g_variant_parse: + * @type: a #GVariantType, or %NULL + * @text: a string containing a GVariant in text form + * @limit: a pointer to the end of @text, or %NULL + * @endptr: a location to store the end pointer, or %NULL + * @error: a pointer to a %NULL #GError pointer, or %NULL + * @Returns: a reference to a #GVariant, or %NULL + * + * Parses a #GVariant from a text representation. + * + * A single #GVariant is parsed from the content of @text. + * + * The format is described here. + * + * The memory at @limit will never be accessed and the parser behaves as + * if the character at @limit is the nul terminator. This has the + * effect of bounding @text. + * + * If @endptr is non-%NULL then @text is permitted to contain data + * following the value that this function parses and @endptr will be + * updated to point to the first character past the end of the text + * parsed by this function. If @endptr is %NULL and there is extra data + * then an error is returned. + * + * If @type is non-%NULL then the value will be parsed to have that + * type. This may result in additional parse errors (in the case that + * the parsed value doesn't fit the type) but may also result in fewer + * errors (in the case that the type would have been ambiguous, such as + * with empty arrays). + * + * In the event that the parsing is successful, the resulting #GVariant + * is returned. + * + * In case of any error, %NULL will be returned. If @error is non-%NULL + * then it will be set to reflect the error that occurred. + * + * Officially, the language understood by the parser is "any string + * produced by g_variant_print()". + **/ +GVariant * +g_variant_parse (const GVariantType *type, + const gchar *text, + const gchar *limit, + const gchar **endptr, + GError **error) +{ + TokenStream stream = { 0, }; + GVariant *result = NULL; + AST *ast; + + g_return_val_if_fail (text != NULL, NULL); + g_return_val_if_fail (text == limit || text != NULL, NULL); + + stream.start = text; + stream.stream = text; + stream.end = limit; + + if ((ast = parse (&stream, NULL, error))) + { + if (type == NULL) + result = ast_resolve (ast, error); + else + result = ast_get_value (ast, type, error); + + if (result != NULL) + { + g_variant_ref_sink (result); + + if (endptr == NULL) + { + while (stream.stream != limit && + g_ascii_isspace (*stream.stream)) + stream.stream++; + + if (stream.stream != limit && *stream.stream != '\0') + { + SourceRef ref = { stream.stream - text, + stream.stream - text }; + + parser_set_error (error, &ref, NULL, + G_VARIANT_PARSE_ERROR_INPUT_NOT_AT_END, + "expected end of input"); + g_variant_unref (result); + + result = NULL; + } + } + else + *endptr = stream.stream; + } + + ast_free (ast); + } + + return result; +} + +/** + * g_variant_new_parsed_va: + * @format: a text format #GVariant + * @app: a pointer to a #va_list + * + * Parses @format and returns the result. + * + * This is the version of g_variant_new_parsed() intended to be used + * from libraries. + * + * The return value will be floating if it was a newly created GVariant + * instance. In the case that @format simply specified the collection + * of a #GVariant pointer (eg: @format was "%*") then the collected + * #GVariant pointer will be returned unmodified, without adding any + * additional references. + * + * In order to behave correctly in all cases it is necessary for the + * calling function to g_variant_ref_sink() the return result before + * returning control to the user that originally provided the pointer. + * At this point, the caller will have their own full reference to the + * result. This can also be done by adding the result to a container, + * or by passing it to another g_variant_new() call. + * + * Returns: a new, usually floating, #GVariant + **/ +GVariant * +g_variant_new_parsed_va (const gchar *format, + va_list *app) +{ + TokenStream stream = { 0, }; + GVariant *result = NULL; + GError *error = NULL; + AST *ast; + + g_return_val_if_fail (format != NULL, NULL); + g_return_val_if_fail (app != NULL, NULL); + + stream.start = format; + stream.stream = format; + stream.end = NULL; + + if ((ast = parse (&stream, app, &error))) + { + result = ast_resolve (ast, &error); + ast_free (ast); + } + + if (result == NULL) + g_error ("g_variant_new_parsed: %s", error->message); + + if (*stream.stream) + g_error ("g_variant_new_parsed: trailing text after value"); + + return result; +} + +/** + * g_variant_new_parsed: + * @format: a text format #GVariant + * @...: arguments as per @format + * + * Parses @format and returns the result. + * + * @format must be a text format #GVariant with one extension: at any + * point that a value may appear in the text, a '%' character followed + * by a GVariant format string (as per g_variant_new()) may appear. In + * that case, the same arguments are collected from the argument list as + * g_variant_new() would have collected. + * + * Consider this simple example: + * + * + * g_variant_new_parsed ("[('one', 1), ('two', %i), (%s, 3)]", 2, "three"); + * + * + * In the example, the variable argument parameters are collected and + * filled in as if they were part of the original string to produce the + * result of [('one', 1), ('two', 2), ('three', 3)]. + * + * This function is intended only to be used with @format as a string + * literal. Any parse error is fatal to the calling process. If you + * want to parse data from untrusted sources, use g_variant_parse(). + * + * You may not use this function to return, unmodified, a single + * #GVariant pointer from the argument list. ie: @format may not solely + * be anything along the lines of "%*", "%?", "\%r", or anything starting + * with "%@". + * + * Returns: a new floating #GVariant instance + **/ +GVariant * +g_variant_new_parsed (const gchar *format, + ...) +{ + GVariant *result; + va_list ap; + + va_start (ap, format); + result = g_variant_new_parsed_va (format, &ap); + va_end (ap); + + return result; +} + +/** + * g_variant_builder_add_parsed: + * @builder: a #GVariantBuilder + * @format: a text format #GVariant + * @...: arguments as per @format + * + * Adds to a #GVariantBuilder. + * + * This call is a convenience wrapper that is exactly equivalent to + * calling g_variant_new_parsed() followed by + * g_variant_builder_add_value(). + * + * This function might be used as follows: + * + * + * GVariant * + * make_pointless_dictionary (void) + * { + * GVariantBuilder *builder; + * int i; + * + * builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + * g_variant_builder_add_parsed (builder, "{'width', <%i>}", 600); + * g_variant_builder_add_parsed (builder, "{'title', <%s>}", "foo"); + * g_variant_builder_add_parsed (builder, "{'transparency', <0.5>}"); + * return g_variant_builder_end (builder); + * } + * + * + * Since: 2.26 + **/ +void +g_variant_builder_add_parsed (GVariantBuilder *builder, + const gchar *format, + ...) +{ + va_list ap; + + va_start (ap, format); + g_variant_builder_add_value (builder, g_variant_new_parsed_va (format, &ap)); + va_end (ap); +} diff --git a/glib/glib/gvariant-serialiser.c b/glib/glib/gvariant-serialiser.c new file mode 100644 index 0000000..f072511 --- /dev/null +++ b/glib/glib/gvariant-serialiser.c @@ -0,0 +1,1689 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +/* Prologue {{{1 */ +#include "config.h" + +#include "gvariant-serialiser.h" + +#include +#include +#include + +#include + + +/* GVariantSerialiser + * + * After this prologue section, this file has roughly 2 parts. + * + * The first part is split up into sections according to various + * container types. Maybe, Array, Tuple, Variant. The Maybe and Array + * sections are subdivided for element types being fixed or + * variable-sized types. + * + * Each section documents the format of that particular type of + * container and implements 5 functions for dealing with it: + * + * n_children: + * - determines (according to serialised data) how many child values + * are inside a particular container value. + * + * get_child: + * - gets the type of and the serialised data corresponding to a + * given child value within the container value. + * + * needed_size: + * - determines how much space would be required to serialise a + * container of this type, containing the given children so that + * buffers can be preallocated before serialising. + * + * serialise: + * - write the serialised data for a container of this type, + * containing the given children, to a buffer. + * + * is_normal: + * - check the given data to ensure that it is in normal form. For a + * given set of child values, there is exactly one normal form for + * the serialised data of a container. Other forms are possible + * while maintaining the same children (for example, by inserting + * something other than zero bytes as padding) but only one form is + * the normal form. + * + * The second part contains the main entry point for each of the above 5 + * functions and logic to dispatch it to the handler for the appropriate + * container type code. + * + * The second part also contains a routine to byteswap serialised + * values. This code makes use of the n_children() and get_child() + * functions above to do its work so no extra support is needed on a + * per-container-type basis. + * + * There is also additional code for checking for normal form. All + * numeric types are always in normal form since the full range of + * values is permitted (eg: 0 to 255 is a valid byte). Special checks + * need to be performed for booleans (only 0 or 1 allowed), strings + * (properly nul-terminated) and object paths and signature strings + * (meeting the D-Bus specification requirements). + */ + +/* < private > + * GVariantSerialised: + * @type_info: the #GVariantTypeInfo of this value + * @data: the serialised data of this value, or %NULL + * @size: the size of this value + * + * A structure representing a GVariant in serialised form. This + * structure is used with #GVariantSerialisedFiller functions and as the + * primary interface to the serialiser. See #GVariantSerialisedFiller + * for a description of its use there. + * + * When used with the serialiser API functions, the following invariants + * apply to all #GVariantTypeSerialised structures passed to and + * returned from the serialiser. + * + * @type_info must be non-%NULL. + * + * @data must be properly aligned for the type described by @type_info. + * + * If @type_info describes a fixed-sized type then @size must always be + * equal to the fixed size of that type. + * + * For fixed-sized types (and only fixed-sized types), @data may be + * %NULL even if @size is non-zero. This happens when a framing error + * occurs while attempting to extract a fixed-sized value out of a + * variable-sized container. There is no data to return for the + * fixed-sized type, yet @size must be non-zero. The effect of this + * combination should be as if @data were a pointer to an + * appropriately-sized zero-filled region. + */ + +/* < private > + * g_variant_serialised_check: + * @serialised: a #GVariantSerialised struct + * + * Checks @serialised for validity according to the invariants described + * above. + */ +static void +g_variant_serialised_check (GVariantSerialised serialised) +{ + gsize fixed_size; + guint alignment; + + g_assert (serialised.type_info != NULL); + g_variant_type_info_query (serialised.type_info, &alignment, &fixed_size); + + if (fixed_size) + g_assert_cmpint (serialised.size, ==, fixed_size); + else + g_assert (serialised.size == 0 || serialised.data != NULL); + + /* Depending on the native alignment requirements of the machine, the + * compiler will insert either 3 or 7 padding bytes after the char. + * This will result in the sizeof() the struct being 12 or 16. + * Subtract 9 to get 3 or 7 which is a nice bitmask to apply to get + * the alignment bits that we "care about" being zero: in the + * 4-aligned case, we care about 2 bits, and in the 8-aligned case, we + * care about 3 bits. + */ + alignment &= sizeof (struct { + char a; + union { + guint64 x; + void *y; + gdouble z; + } b; + } + ) - 9; + + /* Some OSes (FreeBSD is a known example) have a malloc() that returns + * unaligned memory if you request small sizes. 'malloc (1);', for + * example, has been seen to return pointers aligned to 6 mod 16. + * + * Check if this is a small allocation and return without enforcing + * the alignment assertion if this is the case. + */ + if (serialised.size <= alignment) + return; + + g_assert_cmpint (alignment & (gsize) serialised.data, ==, 0); +} + +/* < private > + * GVariantSerialisedFiller: + * @serialised: a #GVariantSerialised instance to fill + * @data: data from the children array + * + * This function is called back from g_variant_serialiser_needed_size() + * and g_variant_serialiser_serialise(). It fills in missing details + * from a partially-complete #GVariantSerialised. + * + * The @data parameter passed back to the function is one of the items + * that was passed to the serialiser in the @children array. It + * represents a single child item of the container that is being + * serialised. The information filled in to @serialised is the + * information for this child. + * + * If the @type_info field of @serialised is %NULL then the callback + * function must set it to the type information corresponding to the + * type of the child. No reference should be added. If it is non-%NULL + * then the callback should assert that it is equal to the actual type + * of the child. + * + * If the @size field is zero then the callback must fill it in with the + * required amount of space to store the serialised form of the child. + * If it is non-zero then the callback should assert that it is equal to + * the needed size of the child. + * + * If @data is non-%NULL then it points to a space that is properly + * aligned for and large enough to store the serialised data of the + * child. The callback must store the serialised form of the child at + * @data. + * + * If the child value is another container then the callback will likely + * recurse back into the serialiser by calling + * g_variant_serialiser_needed_size() to determine @size and + * g_variant_serialiser_serialise() to write to @data. + */ + +/* PART 1: Container types {{{1 + * + * This section contains the serialiser implementation functions for + * each container type. + */ + +/* Maybe {{{2 + * + * Maybe types are handled depending on if the element type of the maybe + * type is a fixed-sized or variable-sized type. Although all maybe + * types themselves are variable-sized types, herein, a maybe value with + * a fixed-sized element type is called a "fixed-sized maybe" for + * convenience and a maybe value with a variable-sized element type is + * called a "variable-sized maybe". + */ + +/* Fixed-sized Maybe {{{3 + * + * The size of a maybe value with a fixed-sized element type is either 0 + * or equal to the fixed size of its element type. The case where the + * size of the maybe value is zero corresponds to the "Nothing" case and + * the case where the size of the maybe value is equal to the fixed size + * of the element type corresponds to the "Just" case; in that case, the + * serialised data of the child value forms the entire serialised data + * of the maybe value. + * + * In the event that a fixed-sized maybe value is presented with a size + * that is not equal to the fixed size of the element type then the + * value must be taken to be "Nothing". + */ + +static gsize +gvs_fixed_sized_maybe_n_children (GVariantSerialised value) +{ + gsize element_fixed_size; + + g_variant_type_info_query_element (value.type_info, NULL, + &element_fixed_size); + + return (element_fixed_size == value.size) ? 1 : 0; +} + +static GVariantSerialised +gvs_fixed_sized_maybe_get_child (GVariantSerialised value, + gsize index_) +{ + /* the child has the same bounds as the + * container, so just update the type. + */ + value.type_info = g_variant_type_info_element (value.type_info); + g_variant_type_info_ref (value.type_info); + + return value; +} + +static gsize +gvs_fixed_sized_maybe_needed_size (GVariantTypeInfo *type_info, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + if (n_children) + { + gsize element_fixed_size; + + g_variant_type_info_query_element (type_info, NULL, + &element_fixed_size); + + return element_fixed_size; + } + else + return 0; +} + +static void +gvs_fixed_sized_maybe_serialise (GVariantSerialised value, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + if (n_children) + { + GVariantSerialised child = { NULL, value.data, value.size }; + + gvs_filler (&child, children[0]); + } +} + +static gboolean +gvs_fixed_sized_maybe_is_normal (GVariantSerialised value) +{ + if (value.size > 0) + { + gsize element_fixed_size; + + g_variant_type_info_query_element (value.type_info, + NULL, &element_fixed_size); + + if (value.size != element_fixed_size) + return FALSE; + + /* proper element size: "Just". recurse to the child. */ + value.type_info = g_variant_type_info_element (value.type_info); + + return g_variant_serialised_is_normal (value); + } + + /* size of 0: "Nothing" */ + return TRUE; +} + +/* Variable-sized Maybe + * + * The size of a maybe value with a variable-sized element type is + * either 0 or strictly greater than 0. The case where the size of the + * maybe value is zero corresponds to the "Nothing" case and the case + * where the size of the maybe value is greater than zero corresponds to + * the "Just" case; in that case, the serialised data of the child value + * forms the first part of the serialised data of the maybe value and is + * followed by a single zero byte. This zero byte is always appended, + * regardless of any zero bytes that may already be at the end of the + * serialised ata of the child value. + */ + +static gsize +gvs_variable_sized_maybe_n_children (GVariantSerialised value) +{ + return (value.size > 0) ? 1 : 0; +} + +static GVariantSerialised +gvs_variable_sized_maybe_get_child (GVariantSerialised value, + gsize index_) +{ + /* remove the padding byte and update the type. */ + value.type_info = g_variant_type_info_element (value.type_info); + g_variant_type_info_ref (value.type_info); + value.size--; + + /* if it's zero-sized then it may as well be NULL */ + if (value.size == 0) + value.data = NULL; + + return value; +} + +static gsize +gvs_variable_sized_maybe_needed_size (GVariantTypeInfo *type_info, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + if (n_children) + { + GVariantSerialised child = { 0, }; + + gvs_filler (&child, children[0]); + + return child.size + 1; + } + else + return 0; +} + +static void +gvs_variable_sized_maybe_serialise (GVariantSerialised value, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + if (n_children) + { + GVariantSerialised child = { NULL, value.data, value.size - 1 }; + + /* write the data for the child. */ + gvs_filler (&child, children[0]); + value.data[child.size] = '\0'; + } +} + +static gboolean +gvs_variable_sized_maybe_is_normal (GVariantSerialised value) +{ + if (value.size == 0) + return TRUE; + + if (value.data[value.size - 1] != '\0') + return FALSE; + + value.type_info = g_variant_type_info_element (value.type_info); + value.size--; + + return g_variant_serialised_is_normal (value); +} + +/* Arrays {{{2 + * + * Just as with maybe types, array types are handled depending on if the + * element type of the array type is a fixed-sized or variable-sized + * type. Similar to maybe types, for convenience, an array value with a + * fixed-sized element type is called a "fixed-sized array" and an array + * value with a variable-sized element type is called a "variable sized + * array". + */ + +/* Fixed-sized Array {{{3 + * + * For fixed sized arrays, the serialised data is simply a concatenation + * of the serialised data of each element, in order. Since fixed-sized + * values always have a fixed size that is a multiple of their alignment + * requirement no extra padding is required. + * + * In the event that a fixed-sized array is presented with a size that + * is not an integer multiple of the element size then the value of the + * array must be taken as being empty. + */ + +static gsize +gvs_fixed_sized_array_n_children (GVariantSerialised value) +{ + gsize element_fixed_size; + + g_variant_type_info_query_element (value.type_info, NULL, + &element_fixed_size); + + if (value.size % element_fixed_size == 0) + return value.size / element_fixed_size; + + return 0; +} + +static GVariantSerialised +gvs_fixed_sized_array_get_child (GVariantSerialised value, + gsize index_) +{ + GVariantSerialised child = { 0, }; + + child.type_info = g_variant_type_info_element (value.type_info); + g_variant_type_info_query (child.type_info, NULL, &child.size); + child.data = value.data + (child.size * index_); + g_variant_type_info_ref (child.type_info); + + return child; +} + +static gsize +gvs_fixed_sized_array_needed_size (GVariantTypeInfo *type_info, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + gsize element_fixed_size; + + g_variant_type_info_query_element (type_info, NULL, &element_fixed_size); + + return element_fixed_size * n_children; +} + +static void +gvs_fixed_sized_array_serialise (GVariantSerialised value, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + GVariantSerialised child = { 0, }; + gsize i; + + child.type_info = g_variant_type_info_element (value.type_info); + g_variant_type_info_query (child.type_info, NULL, &child.size); + child.data = value.data; + + for (i = 0; i < n_children; i++) + { + gvs_filler (&child, children[i]); + child.data += child.size; + } +} + +static gboolean +gvs_fixed_sized_array_is_normal (GVariantSerialised value) +{ + GVariantSerialised child = { 0, }; + + child.type_info = g_variant_type_info_element (value.type_info); + g_variant_type_info_query (child.type_info, NULL, &child.size); + + if (value.size % child.size != 0) + return FALSE; + + for (child.data = value.data; + child.data < value.data + value.size; + child.data += child.size) + { + if (!g_variant_serialised_is_normal (child)) + return FALSE; + } + + return TRUE; +} + +/* Variable-sized Array {{{3 + * + * Variable sized arrays, containing variable-sized elements, must be + * able to determine the boundaries between the elements. The items + * cannot simply be concatenated. Additionally, we are faced with the + * fact that non-fixed-sized values do not necessarily have a size that + * is a multiple of their alignment requirement, so we may need to + * insert zero-filled padding. + * + * While it is possible to find the start of an item by starting from + * the end of the item before it and padding for alignment, it is not + * generally possible to do the reverse operation. For this reason, we + * record the end point of each element in the array. + * + * GVariant works in terms of "offsets". An offset is a pointer to a + * boundary between two bytes. In 4 bytes of serialised data, there + * would be 5 possible offsets: one at the start ('0'), one between each + * pair of adjacent bytes ('1', '2', '3') and one at the end ('4'). + * + * The numeric value of an offset is an unsigned integer given relative + * to the start of the serialised data of the array. Offsets are always + * stored in little endian byte order and are always only as big as they + * need to be. For example, in 255 bytes of serialised data, there are + * 256 offsets. All possibilities can be stored in an 8 bit unsigned + * integer. In 256 bytes of serialised data, however, there are 257 + * possible offsets so 16 bit integers must be used. The size of an + * offset is always a power of 2. + * + * The offsets are stored at the end of the serialised data of the + * array. They are simply concatenated on without any particular + * alignment. The size of the offsets is included in the size of the + * serialised data for purposes of determining the size of the offsets. + * This presents a possibly ambiguity; in certain cases, a particular + * value of array could have two different serialised forms. + * + * Imagine an array containing a single string of 253 bytes in length + * (so, 254 bytes including the nul terminator). Now the offset must be + * written. If an 8 bit offset is written, it will bring the size of + * the array's serialised data to 255 -- which means that the use of an + * 8 bit offset was valid. If a 16 bit offset is used then the total + * size of the array will be 256 -- which means that the use of a 16 bit + * offset was valid. Although both of these will be accepted by the + * deserialiser, only the smaller of the two is considered to be in + * normal form and that is the one that the serialiser must produce. + */ + +static inline gsize +gvs_read_unaligned_le (guchar *bytes, + guint size) +{ + union + { + guchar bytes[GLIB_SIZEOF_SIZE_T]; + gsize integer; + } tmpvalue; + + tmpvalue.integer = 0; + memcpy (&tmpvalue.bytes, bytes, size); + + return GSIZE_FROM_LE (tmpvalue.integer); +} + +static inline void +gvs_write_unaligned_le (guchar *bytes, + gsize value, + guint size) +{ + union + { + guchar bytes[GLIB_SIZEOF_SIZE_T]; + gsize integer; + } tmpvalue; + + tmpvalue.integer = GSIZE_TO_LE (value); + memcpy (bytes, &tmpvalue.bytes, size); +} + +static guint +gvs_get_offset_size (gsize size) +{ + if (size > G_MAXUINT32) + return 8; + + else if (size > G_MAXUINT16) + return 4; + + else if (size > G_MAXUINT8) + return 2; + + else if (size > 0) + return 1; + + return 0; +} + +static gsize +gvs_calculate_total_size (gsize body_size, + gsize offsets) +{ + if (body_size + 1 * offsets <= G_MAXUINT8) + return body_size + 1 * offsets; + + if (body_size + 2 * offsets <= G_MAXUINT16) + return body_size + 2 * offsets; + + if (body_size + 4 * offsets <= G_MAXUINT32) + return body_size + 4 * offsets; + + return body_size + 8 * offsets; +} + +static gsize +gvs_variable_sized_array_n_children (GVariantSerialised value) +{ + gsize offsets_array_size; + gsize offset_size; + gsize last_end; + + if (value.size == 0) + return 0; + + offset_size = gvs_get_offset_size (value.size); + + last_end = gvs_read_unaligned_le (value.data + value.size - + offset_size, offset_size); + + if (last_end > value.size) + return 0; + + offsets_array_size = value.size - last_end; + + if (offsets_array_size % offset_size) + return 0; + + return offsets_array_size / offset_size; +} + +static GVariantSerialised +gvs_variable_sized_array_get_child (GVariantSerialised value, + gsize index_) +{ + GVariantSerialised child = { 0, }; + gsize offset_size; + gsize last_end; + gsize start; + gsize end; + + child.type_info = g_variant_type_info_element (value.type_info); + g_variant_type_info_ref (child.type_info); + + offset_size = gvs_get_offset_size (value.size); + + last_end = gvs_read_unaligned_le (value.data + value.size - + offset_size, offset_size); + + if (index_ > 0) + { + guint alignment; + + start = gvs_read_unaligned_le (value.data + last_end + + (offset_size * (index_ - 1)), + offset_size); + + g_variant_type_info_query (child.type_info, &alignment, NULL); + start += (-start) & alignment; + } + else + start = 0; + + end = gvs_read_unaligned_le (value.data + last_end + + (offset_size * index_), + offset_size); + + if (start < end && end <= value.size) + { + child.data = value.data + start; + child.size = end - start; + } + + return child; +} + +static gsize +gvs_variable_sized_array_needed_size (GVariantTypeInfo *type_info, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + guint alignment; + gsize offset; + gsize i; + + g_variant_type_info_query (type_info, &alignment, NULL); + offset = 0; + + for (i = 0; i < n_children; i++) + { + GVariantSerialised child = { 0, }; + + offset += (-offset) & alignment; + gvs_filler (&child, children[i]); + offset += child.size; + } + + return gvs_calculate_total_size (offset, n_children); +} + +static void +gvs_variable_sized_array_serialise (GVariantSerialised value, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + guchar *offset_ptr; + gsize offset_size; + guint alignment; + gsize offset; + gsize i; + + g_variant_type_info_query (value.type_info, &alignment, NULL); + offset_size = gvs_get_offset_size (value.size); + offset = 0; + + offset_ptr = value.data + value.size - offset_size * n_children; + + for (i = 0; i < n_children; i++) + { + GVariantSerialised child = { 0, }; + + while (offset & alignment) + value.data[offset++] = '\0'; + + child.data = value.data + offset; + gvs_filler (&child, children[i]); + offset += child.size; + + gvs_write_unaligned_le (offset_ptr, offset, offset_size); + offset_ptr += offset_size; + } +} + +static gboolean +gvs_variable_sized_array_is_normal (GVariantSerialised value) +{ + GVariantSerialised child = { 0, }; + gsize offsets_array_size; + guchar *offsets_array; + guint offset_size; + guint alignment; + gsize last_end; + gsize length; + gsize offset; + gsize i; + + if (value.size == 0) + return TRUE; + + offset_size = gvs_get_offset_size (value.size); + last_end = gvs_read_unaligned_le (value.data + value.size - + offset_size, offset_size); + + if (last_end > value.size) + return FALSE; + + offsets_array_size = value.size - last_end; + + if (offsets_array_size % offset_size) + return FALSE; + + offsets_array = value.data + value.size - offsets_array_size; + length = offsets_array_size / offset_size; + + if (length == 0) + return FALSE; + + child.type_info = g_variant_type_info_element (value.type_info); + g_variant_type_info_query (child.type_info, &alignment, NULL); + offset = 0; + + for (i = 0; i < length; i++) + { + gsize this_end; + + this_end = gvs_read_unaligned_le (offsets_array + offset_size * i, + offset_size); + + if (this_end < offset || this_end > last_end) + return FALSE; + + while (offset & alignment) + { + if (!(offset < this_end && value.data[offset] == '\0')) + return FALSE; + offset++; + } + + child.data = value.data + offset; + child.size = this_end - offset; + + if (child.size == 0) + child.data = NULL; + + if (!g_variant_serialised_is_normal (child)) + return FALSE; + + offset = this_end; + } + + g_assert (offset == last_end); + + return TRUE; +} + +/* Tuples {{{2 + * + * Since tuples can contain a mix of variable- and fixed-sized items, + * they are, in terms of serialisation, a hybrid of variable-sized and + * fixed-sized arrays. + * + * Offsets are only stored for variable-sized items. Also, since the + * number of items in a tuple is known from its type, we are able to + * know exactly how many offsets to expect in the serialised data (and + * therefore how much space is taken up by the offset array). This + * means that we know where the end of the serialised data for the last + * item is -- we can just subtract the size of the offset array from the + * total size of the tuple. For this reason, the last item in the tuple + * doesn't need an offset stored. + * + * Tuple offsets are stored in reverse. This design choice allows + * iterator-based deserialisers to be more efficient. + * + * Most of the "heavy lifting" here is handled by the GVariantTypeInfo + * for the tuple. See the notes in gvarianttypeinfo.h. + */ + +static gsize +gvs_tuple_n_children (GVariantSerialised value) +{ + return g_variant_type_info_n_members (value.type_info); +} + +static GVariantSerialised +gvs_tuple_get_child (GVariantSerialised value, + gsize index_) +{ + const GVariantMemberInfo *member_info; + GVariantSerialised child = { 0, }; + gsize offset_size; + gsize start, end; + + member_info = g_variant_type_info_member_info (value.type_info, index_); + child.type_info = g_variant_type_info_ref (member_info->type_info); + offset_size = gvs_get_offset_size (value.size); + + /* tuples are the only (potentially) fixed-sized containers, so the + * only ones that have to deal with the possibility of having %NULL + * data with a non-zero %size if errors occurred elsewhere. + */ + if G_UNLIKELY (value.data == NULL && value.size != 0) + { + g_variant_type_info_query (child.type_info, NULL, &child.size); + + /* this can only happen in fixed-sized tuples, + * so the child must also be fixed sized. + */ + g_assert (child.size != 0); + child.data = NULL; + + return child; + } + + if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET) + { + if (offset_size * (member_info->i + 2) > value.size) + return child; + } + else + { + if (offset_size * (member_info->i + 1) > value.size) + { + /* if the child is fixed size, return its size. + * if child is not fixed-sized, return size = 0. + */ + g_variant_type_info_query (child.type_info, NULL, &child.size); + + return child; + } + } + + if (member_info->i + 1) + start = gvs_read_unaligned_le (value.data + value.size - + offset_size * (member_info->i + 1), + offset_size); + else + start = 0; + + start += member_info->a; + start &= member_info->b; + start |= member_info->c; + + if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST) + end = value.size - offset_size * (member_info->i + 1); + + else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED) + { + gsize fixed_size; + + g_variant_type_info_query (child.type_info, NULL, &fixed_size); + end = start + fixed_size; + child.size = fixed_size; + } + + else /* G_VARIANT_MEMEBER_ENDING_OFFSET */ + end = gvs_read_unaligned_le (value.data + value.size - + offset_size * (member_info->i + 2), + offset_size); + + if (start < end && end <= value.size) + { + child.data = value.data + start; + child.size = end - start; + } + + return child; +} + +static gsize +gvs_tuple_needed_size (GVariantTypeInfo *type_info, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + const GVariantMemberInfo *member_info = NULL; + gsize fixed_size; + gsize offset; + gsize i; + + g_variant_type_info_query (type_info, NULL, &fixed_size); + + if (fixed_size) + return fixed_size; + + offset = 0; + + for (i = 0; i < n_children; i++) + { + guint alignment; + + member_info = g_variant_type_info_member_info (type_info, i); + g_variant_type_info_query (member_info->type_info, + &alignment, &fixed_size); + offset += (-offset) & alignment; + + if (fixed_size) + offset += fixed_size; + else + { + GVariantSerialised child = { 0, }; + + gvs_filler (&child, children[i]); + offset += child.size; + } + } + + return gvs_calculate_total_size (offset, member_info->i + 1); +} + +static void +gvs_tuple_serialise (GVariantSerialised value, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + gsize offset_size; + gsize offset; + gsize i; + + offset_size = gvs_get_offset_size (value.size); + offset = 0; + + for (i = 0; i < n_children; i++) + { + const GVariantMemberInfo *member_info; + GVariantSerialised child = { 0, }; + guint alignment; + + member_info = g_variant_type_info_member_info (value.type_info, i); + g_variant_type_info_query (member_info->type_info, &alignment, NULL); + + while (offset & alignment) + value.data[offset++] = '\0'; + + child.data = value.data + offset; + gvs_filler (&child, children[i]); + offset += child.size; + + if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET) + { + value.size -= offset_size; + gvs_write_unaligned_le (value.data + value.size, + offset, offset_size); + } + } + + while (offset < value.size) + value.data[offset++] = '\0'; +} + +static gboolean +gvs_tuple_is_normal (GVariantSerialised value) +{ + guint offset_size; + gsize offset_ptr; + gsize length; + gsize offset; + gsize i; + + offset_size = gvs_get_offset_size (value.size); + length = g_variant_type_info_n_members (value.type_info); + offset_ptr = value.size; + offset = 0; + + for (i = 0; i < length; i++) + { + const GVariantMemberInfo *member_info; + GVariantSerialised child; + gsize fixed_size; + guint alignment; + gsize end; + + member_info = g_variant_type_info_member_info (value.type_info, i); + child.type_info = member_info->type_info; + + g_variant_type_info_query (child.type_info, &alignment, &fixed_size); + + while (offset & alignment) + { + if (offset > value.size || value.data[offset] != '\0') + return FALSE; + offset++; + } + + child.data = value.data + offset; + + switch (member_info->ending_type) + { + case G_VARIANT_MEMBER_ENDING_FIXED: + end = offset + fixed_size; + break; + + case G_VARIANT_MEMBER_ENDING_LAST: + end = offset_ptr; + break; + + case G_VARIANT_MEMBER_ENDING_OFFSET: + offset_ptr -= offset_size; + + if (offset_ptr < offset) + return FALSE; + + end = gvs_read_unaligned_le (value.data + offset_ptr, offset_size); + break; + + default: + g_assert_not_reached (); + } + + if (end < offset || end > offset_ptr) + return FALSE; + + child.size = end - offset; + + if (child.size == 0) + child.data = NULL; + + if (!g_variant_serialised_is_normal (child)) + return FALSE; + + offset = end; + } + + { + gsize fixed_size; + guint alignment; + + g_variant_type_info_query (value.type_info, &alignment, &fixed_size); + + if (fixed_size) + { + g_assert (fixed_size == value.size); + g_assert (offset_ptr == value.size); + + if (i == 0) + { + if (value.data[offset++] != '\0') + return FALSE; + } + else + { + while (offset & alignment) + if (value.data[offset++] != '\0') + return FALSE; + } + + g_assert (offset == value.size); + } + } + + return offset_ptr == offset; +} + +/* Variants {{{2 + * + * Variants are stored by storing the serialised data of the child, + * followed by a '\0' character, followed by the type string of the + * child. + * + * In the case that a value is presented that contains no '\0' + * character, or doesn't have a single well-formed definite type string + * following that character, the variant must be taken as containing the + * unit tuple: (). + */ + +static inline gsize +gvs_variant_n_children (GVariantSerialised value) +{ + return 1; +} + +static inline GVariantSerialised +gvs_variant_get_child (GVariantSerialised value, + gsize index_) +{ + GVariantSerialised child = { 0, }; + + /* NOTE: not O(1) and impossible for it to be... */ + if (value.size) + { + /* find '\0' character */ + for (child.size = value.size - 1; child.size; child.size--) + if (value.data[child.size] == '\0') + break; + + /* ensure we didn't just hit the start of the string */ + if (value.data[child.size] == '\0') + { + const gchar *type_string = (gchar *) &value.data[child.size + 1]; + const gchar *limit = (gchar *) &value.data[value.size]; + const gchar *end; + + if (g_variant_type_string_scan (type_string, limit, &end) && + end == limit) + { + const GVariantType *type = (GVariantType *) type_string; + + if (g_variant_type_is_definite (type)) + { + gsize fixed_size; + + child.type_info = g_variant_type_info_get (type); + + if (child.size != 0) + /* only set to non-%NULL if size > 0 */ + child.data = value.data; + + g_variant_type_info_query (child.type_info, + NULL, &fixed_size); + + if (!fixed_size || fixed_size == child.size) + return child; + + g_variant_type_info_unref (child.type_info); + } + } + } + } + + child.type_info = g_variant_type_info_get (G_VARIANT_TYPE_UNIT); + child.data = NULL; + child.size = 1; + + return child; +} + +static inline gsize +gvs_variant_needed_size (GVariantTypeInfo *type_info, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + GVariantSerialised child = { 0, }; + const gchar *type_string; + + gvs_filler (&child, children[0]); + type_string = g_variant_type_info_get_type_string (child.type_info); + + return child.size + 1 + strlen (type_string); +} + +static inline void +gvs_variant_serialise (GVariantSerialised value, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + GVariantSerialised child = { 0, }; + const gchar *type_string; + + child.data = value.data; + + gvs_filler (&child, children[0]); + type_string = g_variant_type_info_get_type_string (child.type_info); + value.data[child.size] = '\0'; + memcpy (value.data + child.size + 1, type_string, strlen (type_string)); +} + +static inline gboolean +gvs_variant_is_normal (GVariantSerialised value) +{ + GVariantSerialised child; + gboolean normal; + + child = gvs_variant_get_child (value, 0); + + normal = (child.data != NULL || child.size == 0) && + g_variant_serialised_is_normal (child); + + g_variant_type_info_unref (child.type_info); + + return normal; +} + + + +/* PART 2: Serialiser API {{{1 + * + * This is the implementation of the API of the serialiser as advertised + * in gvariant-serialiser.h. + */ + +/* Dispatch Utilities {{{2 + * + * These macros allow a given function (for example, + * g_variant_serialiser_serialise) to be dispatched to the appropriate + * type-specific function above (fixed/variable-sized maybe, + * fixed/variable-sized array, tuple or variant). + */ +#define DISPATCH_FIXED(type_info, before, after) \ + { \ + gsize fixed_size; \ + \ + g_variant_type_info_query_element (type_info, NULL, \ + &fixed_size); \ + \ + if (fixed_size) \ + { \ + before ## fixed_sized ## after \ + } \ + else \ + { \ + before ## variable_sized ## after \ + } \ + } + +#define DISPATCH_CASES(type_info, before, after) \ + switch (g_variant_type_info_get_type_char (type_info)) \ + { \ + case G_VARIANT_TYPE_INFO_CHAR_MAYBE: \ + DISPATCH_FIXED (type_info, before, _maybe ## after) \ + \ + case G_VARIANT_TYPE_INFO_CHAR_ARRAY: \ + DISPATCH_FIXED (type_info, before, _array ## after) \ + \ + case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY: \ + case G_VARIANT_TYPE_INFO_CHAR_TUPLE: \ + { \ + before ## tuple ## after \ + } \ + \ + case G_VARIANT_TYPE_INFO_CHAR_VARIANT: \ + { \ + before ## variant ## after \ + } \ + } + +/* Serialiser entry points {{{2 + * + * These are the functions that are called in order for the serialiser + * to do its thing. + */ + +/* < private > + * g_variant_serialised_n_children: + * @serialised: a #GVariantSerialised + * + * For serialised data that represents a container value (maybes, + * tuples, arrays, variants), determine how many child items are inside + * that container. + * + * Returns: the number of children + */ +gsize +g_variant_serialised_n_children (GVariantSerialised serialised) +{ + g_variant_serialised_check (serialised); + + DISPATCH_CASES (serialised.type_info, + + return gvs_/**/,/**/_n_children (serialised); + + ) + g_assert_not_reached (); +} + +/* < private > + * g_variant_serialised_get_child: + * @serialised: a #GVariantSerialised + * @index_: the index of the child to fetch + * + * Extracts a child from a serialised data representing a container + * value. + * + * It is an error to call this function with an index out of bounds. + * + * If the result .data == %NULL and .size > 0 then there has been an + * error extracting the requested fixed-sized value. This number of + * zero bytes needs to be allocated instead. + * + * In the case that .data == %NULL and .size == 0 then a zero-sized + * item of a variable-sized type is being returned. + * + * .data is never non-%NULL if size is 0. + * + * Returns: a #GVariantSerialised for the child + */ +GVariantSerialised +g_variant_serialised_get_child (GVariantSerialised serialised, + gsize index_) +{ + GVariantSerialised child; + + g_variant_serialised_check (serialised); + + if G_LIKELY (index_ < g_variant_serialised_n_children (serialised)) + { + DISPATCH_CASES (serialised.type_info, + + child = gvs_/**/,/**/_get_child (serialised, index_); + g_assert (child.size || child.data == NULL); + g_variant_serialised_check (child); + return child; + + ) + g_assert_not_reached (); + } + + g_error ("Attempt to access item %"G_GSIZE_FORMAT + " in a container with only %"G_GSIZE_FORMAT" items", + index_, g_variant_serialised_n_children (serialised)); +} + +/* < private > + * g_variant_serialiser_serialise: + * @serialised: a #GVariantSerialised, properly set up + * @gvs_filler: the filler function + * @children: an array of child items + * @n_children: the size of @children + * + * Writes data in serialised form. + * + * The type_info field of @serialised must be filled in to type info for + * the type that we are serialising. + * + * The size field of @serialised must be filled in with the value + * returned by a previous call to g_variant_serialiser_needed_size(). + * + * The data field of @serialised must be a pointer to a properly-aligned + * memory region large enough to serialise into (ie: at least as big as + * the size field). + * + * This function is only resonsible for serialising the top-level + * container. @gvs_filler is called on each child of the container in + * order for all of the data of that child to be filled in. + */ +void +g_variant_serialiser_serialise (GVariantSerialised serialised, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + g_variant_serialised_check (serialised); + + DISPATCH_CASES (serialised.type_info, + + gvs_/**/,/**/_serialise (serialised, gvs_filler, + children, n_children); + return; + + ) + g_assert_not_reached (); +} + +/* < private > + * g_variant_serialiser_needed_size: + * @type_info: the type to serialise for + * @gvs_filler: the filler function + * @children: an array of child items + * @n_children: the size of @children + * + * Determines how much memory would be needed to serialise this value. + * + * This function is only resonsible for performing calculations for the + * top-level container. @gvs_filler is called on each child of the + * container in order to determine its size. + */ +gsize +g_variant_serialiser_needed_size (GVariantTypeInfo *type_info, + GVariantSerialisedFiller gvs_filler, + const gpointer *children, + gsize n_children) +{ + DISPATCH_CASES (type_info, + + return gvs_/**/,/**/_needed_size (type_info, gvs_filler, + children, n_children); + + ) + g_assert_not_reached (); +} + +/* Byteswapping {{{2 */ + +/* < private > + * g_variant_serialised_byteswap: + * @value: a #GVariantSerialised + * + * Byte-swap serialised data. The result of this function is only + * well-defined if the data is in normal form. + */ +void +g_variant_serialised_byteswap (GVariantSerialised serialised) +{ + gsize fixed_size; + guint alignment; + + g_variant_serialised_check (serialised); + + if (!serialised.data) + return; + + /* the types we potentially need to byteswap are + * exactly those with alignment requirements. + */ + g_variant_type_info_query (serialised.type_info, &alignment, &fixed_size); + if (!alignment) + return; + + /* if fixed size and alignment are equal then we are down + * to the base integer type and we should swap it. the + * only exception to this is if we have a tuple with a + * single item, and then swapping it will be OK anyway. + */ + if (alignment + 1 == fixed_size) + { + switch (fixed_size) + { + case 2: + { + guint16 *ptr = (guint16 *) serialised.data; + + g_assert_cmpint (serialised.size, ==, 2); + *ptr = GUINT16_SWAP_LE_BE (*ptr); + } + return; + + case 4: + { + guint32 *ptr = (guint32 *) serialised.data; + + g_assert_cmpint (serialised.size, ==, 4); + *ptr = GUINT32_SWAP_LE_BE (*ptr); + } + return; + + case 8: + { + guint64 *ptr = (guint64 *) serialised.data; + + g_assert_cmpint (serialised.size, ==, 8); + *ptr = GUINT64_SWAP_LE_BE (*ptr); + } + return; + + default: + g_assert_not_reached (); + } + } + + /* else, we have a container that potentially contains + * some children that need to be byteswapped. + */ + else + { + gsize children, i; + + children = g_variant_serialised_n_children (serialised); + for (i = 0; i < children; i++) + { + GVariantSerialised child; + + child = g_variant_serialised_get_child (serialised, i); + g_variant_serialised_byteswap (child); + g_variant_type_info_unref (child.type_info); + } + } +} + +/* Normal form checking {{{2 */ + +/* < private > + * g_variant_serialised_is_normal: + * @serialised: a #GVariantSerialised + * + * Determines, recursively if @serialised is in normal form. There is + * precisely one normal form of serialised data for each possible value. + * + * It is possible that multiple byte sequences form the serialised data + * for a given value if, for example, the padding bytes are filled in + * with something other than zeros, but only one form is the normal + * form. + */ +gboolean +g_variant_serialised_is_normal (GVariantSerialised serialised) +{ + DISPATCH_CASES (serialised.type_info, + + return gvs_/**/,/**/_is_normal (serialised); + + ) + + if (serialised.data == NULL) + return FALSE; + + /* some hard-coded terminal cases */ + switch (g_variant_type_info_get_type_char (serialised.type_info)) + { + case 'b': /* boolean */ + return serialised.data[0] < 2; + + case 's': /* string */ + return g_variant_serialiser_is_string (serialised.data, + serialised.size); + + case 'o': + return g_variant_serialiser_is_object_path (serialised.data, + serialised.size); + + case 'g': + return g_variant_serialiser_is_signature (serialised.data, + serialised.size); + + default: + /* all of the other types are fixed-sized numerical types for + * which all possible values are valid (including various NaN + * representations for floating point values). + */ + return TRUE; + } +} + +/* Validity-checking functions {{{2 + * + * Checks if strings, object paths and signature strings are valid. + */ + +/* < private > + * g_variant_serialiser_is_string: + * @data: a possible string + * @size: the size of @data + * + * Ensures that @data is a valid string with a nul terminator at the end + * and no nul bytes embedded. + */ +gboolean +g_variant_serialiser_is_string (gconstpointer data, + gsize size) +{ + const gchar *end; + + g_utf8_validate (data, size, &end); + + return data == end - (size - 1); +} + +/* < private > + * g_variant_serialiser_is_object_path: + * @data: a possible D-Bus object path + * @size: the size of @data + * + * Performs the checks for being a valid string. + * + * Also, ensures that @data is a valid DBus object path, as per the D-Bus + * specification. + */ +gboolean +g_variant_serialiser_is_object_path (gconstpointer data, + gsize size) +{ + const gchar *string = data; + gsize i; + + if (!g_variant_serialiser_is_string (data, size)) + return FALSE; + + /* The path must begin with an ASCII '/' (integer 47) character */ + if (string[0] != '/') + return FALSE; + + for (i = 1; string[i]; i++) + /* Each element must only contain the ASCII characters + * "[A-Z][a-z][0-9]_" + */ + if (g_ascii_isalnum (string[i]) || string[i] == '_') + ; + + /* must consist of elements separated by slash characters. */ + else if (string[i] == '/') + { + /* No element may be the empty string. */ + /* Multiple '/' characters cannot occur in sequence. */ + if (string[i - 1] == '/') + return FALSE; + } + + else + return FALSE; + + /* A trailing '/' character is not allowed unless the path is the + * root path (a single '/' character). + */ + if (i > 1 && string[i - 1] == '/') + return FALSE; + + return TRUE; +} + +/* < private > + * g_variant_serialiser_is_signature: + * @data: a possible D-Bus signature + * @size: the size of @data + * + * Performs the checks for being a valid string. + * + * Also, ensures that @data is a valid D-Bus type signature, as per the + * D-Bus specification. + */ +gboolean +g_variant_serialiser_is_signature (gconstpointer data, + gsize size) +{ + const gchar *string = data; + gsize first_invalid; + + if (!g_variant_serialiser_is_string (data, size)) + return FALSE; + + /* make sure no non-definite characters appear */ + first_invalid = strspn (string, "ybnqiuxthdvasog(){}"); + if (string[first_invalid]) + return FALSE; + + /* make sure each type string is well-formed */ + while (*string) + if (!g_variant_type_string_scan (string, NULL, &string)) + return FALSE; + + return TRUE; +} + +/* Epilogue {{{1 */ +/* vim:set foldmethod=marker: */ diff --git a/glib/glib/gvariant-serialiser.h b/glib/glib/gvariant-serialiser.h new file mode 100644 index 0000000..f26b118 --- /dev/null +++ b/glib/glib/gvariant-serialiser.h @@ -0,0 +1,66 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#ifndef __G_VARIANT_SERIALISER_H__ +#define __G_VARIANT_SERIALISER_H__ + +#include "gvarianttypeinfo.h" + +typedef struct +{ + GVariantTypeInfo *type_info; + guchar *data; + gsize size; +} GVariantSerialised; + +/* deserialisation */ +gsize g_variant_serialised_n_children (GVariantSerialised container); +GVariantSerialised g_variant_serialised_get_child (GVariantSerialised container, + gsize index); + +/* serialisation */ +typedef void (*GVariantSerialisedFiller) (GVariantSerialised *serialised, + gpointer data); + +gsize g_variant_serialiser_needed_size (GVariantTypeInfo *info, + GVariantSerialisedFiller gsv_filler, + const gpointer *children, + gsize n_children); + +void g_variant_serialiser_serialise (GVariantSerialised container, + GVariantSerialisedFiller gsv_filler, + const gpointer *children, + gsize n_children); + +/* misc */ +gboolean g_variant_serialised_is_normal (GVariantSerialised value); +void g_variant_serialised_byteswap (GVariantSerialised value); + +/* validation of strings */ +gboolean g_variant_serialiser_is_string (gconstpointer data, + gsize size); +gboolean g_variant_serialiser_is_object_path (gconstpointer data, + gsize size); +gboolean g_variant_serialiser_is_signature (gconstpointer data, + gsize size); + +#endif /* __G_VARIANT_SERIALISER_H__ */ diff --git a/glib/glib/gvariant.c b/glib/glib/gvariant.c new file mode 100644 index 0000000..22341ff --- /dev/null +++ b/glib/glib/gvariant.c @@ -0,0 +1,5192 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +/* Prologue {{{1 */ + +#include "config.h" + +#include +#include "gvariant-internal.h" +#include +#include +#include +#include +#include +#include + +#include + + +/** + * SECTION:gvariant + * @title: GVariant + * @short_description: strongly typed value datatype + * @see_also: GVariantType + * + * #GVariant is a variant datatype; it stores a value along with + * information about the type of that value. The range of possible + * values is determined by the type. The type system used by #GVariant + * is #GVariantType. + * + * #GVariant instances always have a type and a value (which are given + * at construction time). The type and value of a #GVariant instance + * can never change other than by the #GVariant itself being + * destroyed. A #GVariant cannot contain a pointer. + * + * #GVariant is reference counted using g_variant_ref() and + * g_variant_unref(). #GVariant also has floating reference counts -- + * see g_variant_ref_sink(). + * + * #GVariant is completely threadsafe. A #GVariant instance can be + * concurrently accessed in any way from any number of threads without + * problems. + * + * #GVariant is heavily optimised for dealing with data in serialised + * form. It works particularly well with data located in memory-mapped + * files. It can perform nearly all deserialisation operations in a + * small constant time, usually touching only a single memory page. + * Serialised #GVariant data can also be sent over the network. + * + * #GVariant is largely compatible with D-Bus. Almost all types of + * #GVariant instances can be sent over D-Bus. See #GVariantType for + * exceptions. (However, #GVariant's serialisation format is not the same + * as the serialisation format of a D-Bus message body: use #GDBusMessage, + * in the gio library, for those.) + * + * For space-efficiency, the #GVariant serialisation format does not + * automatically include the variant's type or endianness, which must + * either be implied from context (such as knowledge that a particular + * file format always contains a little-endian %G_VARIANT_TYPE_VARIANT) + * or supplied out-of-band (for instance, a type and/or endianness + * indicator could be placed at the beginning of a file, network message + * or network stream). + * + * A #GVariant's size is limited mainly by any lower level operating + * system constraints, such as the number of bits in #gsize. For + * example, it is reasonable to have a 2GB file mapped into memory + * with #GMappedFile, and call g_variant_new_from_data() on it. + * + * For convenience to C programmers, #GVariant features powerful + * varargs-based value construction and destruction. This feature is + * designed to be embedded in other libraries. + * + * There is a Python-inspired text language for describing #GVariant + * values. #GVariant includes a printer for this language and a parser + * with type inferencing. + * + * + * Memory Use + * + * #GVariant tries to be quite efficient with respect to memory use. + * This section gives a rough idea of how much memory is used by the + * current implementation. The information here is subject to change + * in the future. + * + * + * The memory allocated by #GVariant can be grouped into 4 broad + * purposes: memory for serialised data, memory for the type + * information cache, buffer management memory and memory for the + * #GVariant structure itself. + * + * + * Serialised Data Memory + * + * This is the memory that is used for storing GVariant data in + * serialised form. This is what would be sent over the network or + * what would end up on disk. + * + * + * The amount of memory required to store a boolean is 1 byte. 16, + * 32 and 64 bit integers and double precision floating point numbers + * use their "natural" size. Strings (including object path and + * signature strings) are stored with a nul terminator, and as such + * use the length of the string plus 1 byte. + * + * + * Maybe types use no space at all to represent the null value and + * use the same amount of space (sometimes plus one byte) as the + * equivalent non-maybe-typed value to represent the non-null case. + * + * + * Arrays use the amount of space required to store each of their + * members, concatenated. Additionally, if the items stored in an + * array are not of a fixed-size (ie: strings, other arrays, etc) + * then an additional framing offset is stored for each item. The + * size of this offset is either 1, 2 or 4 bytes depending on the + * overall size of the container. Additionally, extra padding bytes + * are added as required for alignment of child values. + * + * + * Tuples (including dictionary entries) use the amount of space + * required to store each of their members, concatenated, plus one + * framing offset (as per arrays) for each non-fixed-sized item in + * the tuple, except for the last one. Additionally, extra padding + * bytes are added as required for alignment of child values. + * + * + * Variants use the same amount of space as the item inside of the + * variant, plus 1 byte, plus the length of the type string for the + * item inside the variant. + * + * + * As an example, consider a dictionary mapping strings to variants. + * In the case that the dictionary is empty, 0 bytes are required for + * the serialisation. + * + * + * If we add an item "width" that maps to the int32 value of 500 then + * we will use 4 byte to store the int32 (so 6 for the variant + * containing it) and 6 bytes for the string. The variant must be + * aligned to 8 after the 6 bytes of the string, so that's 2 extra + * bytes. 6 (string) + 2 (padding) + 6 (variant) is 14 bytes used + * for the dictionary entry. An additional 1 byte is added to the + * array as a framing offset making a total of 15 bytes. + * + * + * If we add another entry, "title" that maps to a nullable string + * that happens to have a value of null, then we use 0 bytes for the + * null value (and 3 bytes for the variant to contain it along with + * its type string) plus 6 bytes for the string. Again, we need 2 + * padding bytes. That makes a total of 6 + 2 + 3 = 11 bytes. + * + * + * We now require extra padding between the two items in the array. + * After the 14 bytes of the first item, that's 2 bytes required. We + * now require 2 framing offsets for an extra two bytes. 14 + 2 + 11 + * + 2 = 29 bytes to encode the entire two-item dictionary. + * + * + * + * Type Information Cache + * + * For each GVariant type that currently exists in the program a type + * information structure is kept in the type information cache. The + * type information structure is required for rapid deserialisation. + * + * + * Continuing with the above example, if a #GVariant exists with the + * type "a{sv}" then a type information struct will exist for + * "a{sv}", "{sv}", "s", and "v". Multiple uses of the same type + * will share the same type information. Additionally, all + * single-digit types are stored in read-only static memory and do + * not contribute to the writable memory footprint of a program using + * #GVariant. + * + * + * Aside from the type information structures stored in read-only + * memory, there are two forms of type information. One is used for + * container types where there is a single element type: arrays and + * maybe types. The other is used for container types where there + * are multiple element types: tuples and dictionary entries. + * + * + * Array type info structures are 6 * sizeof (void *), plus the + * memory required to store the type string itself. This means that + * on 32bit systems, the cache entry for "a{sv}" would require 30 + * bytes of memory (plus malloc overhead). + * + * + * Tuple type info structures are 6 * sizeof (void *), plus 4 * + * sizeof (void *) for each item in the tuple, plus the memory + * required to store the type string itself. A 2-item tuple, for + * example, would have a type information structure that consumed + * writable memory in the size of 14 * sizeof (void *) (plus type + * string) This means that on 32bit systems, the cache entry for + * "{sv}" would require 61 bytes of memory (plus malloc overhead). + * + * + * This means that in total, for our "a{sv}" example, 91 bytes of + * type information would be allocated. + * + * + * The type information cache, additionally, uses a #GHashTable to + * store and lookup the cached items and stores a pointer to this + * hash table in static storage. The hash table is freed when there + * are zero items in the type cache. + * + * + * Although these sizes may seem large it is important to remember + * that a program will probably only have a very small number of + * different types of values in it and that only one type information + * structure is required for many different values of the same type. + * + * + * + * Buffer Management Memory + * + * #GVariant uses an internal buffer management structure to deal + * with the various different possible sources of serialised data + * that it uses. The buffer is responsible for ensuring that the + * correct call is made when the data is no longer in use by + * #GVariant. This may involve a g_free() or a g_slice_free() or + * even g_mapped_file_unref(). + * + * + * One buffer management structure is used for each chunk of + * serialised data. The size of the buffer management structure is 4 + * * (void *). On 32bit systems, that's 16 bytes. + * + * + * + * GVariant structure + * + * The size of a #GVariant structure is 6 * (void *). On 32 bit + * systems, that's 24 bytes. + * + * + * #GVariant structures only exist if they are explicitly created + * with API calls. For example, if a #GVariant is constructed out of + * serialised data for the example given above (with the dictionary) + * then although there are 9 individual values that comprise the + * entire dictionary (two keys, two values, two variants containing + * the values, two dictionary entries, plus the dictionary itself), + * only 1 #GVariant instance exists -- the one referring to the + * dictionary. + * + * + * If calls are made to start accessing the other values then + * #GVariant instances will exist for those values only for as long + * as they are in use (ie: until you call g_variant_unref()). The + * type information is shared. The serialised data and the buffer + * management structure for that serialised data is shared by the + * child. + * + * + * + * Summary + * + * To put the entire example together, for our dictionary mapping + * strings to variants (with two entries, as given above), we are + * using 91 bytes of memory for type information, 29 byes of memory + * for the serialised data, 16 bytes for buffer management and 24 + * bytes for the #GVariant instance, or a total of 160 bytes, plus + * malloc overhead. If we were to use g_variant_get_child_value() to + * access the two dictionary entries, we would use an additional 48 + * bytes. If we were to have other dictionaries of the same type, we + * would use more memory for the serialised data and buffer + * management for those dictionaries, but the type information would + * be shared. + * + * + * + */ + +/* definition of GVariant structure is in gvariant-core.c */ + +/* this is a g_return_val_if_fail() for making + * sure a (GVariant *) has the required type. + */ +#define TYPE_CHECK(value, TYPE, val) \ + if G_UNLIKELY (!g_variant_is_of_type (value, TYPE)) { \ + g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, \ + "g_variant_is_of_type (" #value \ + ", " #TYPE ")"); \ + return val; \ + } + +/* Numeric Type Constructor/Getters {{{1 */ +/* < private > + * g_variant_new_from_trusted: + * @type: the #GVariantType + * @data: the data to use + * @size: the size of @data + * + * Constructs a new trusted #GVariant instance from the provided data. + * This is used to implement g_variant_new_* for all the basic types. + * + * Returns: a new floating #GVariant + */ +static GVariant * +g_variant_new_from_trusted (const GVariantType *type, + gconstpointer data, + gsize size) +{ + GVariant *value; + GBytes *bytes; + + bytes = g_bytes_new (data, size); + value = g_variant_new_from_bytes (type, bytes, TRUE); + g_bytes_unref (bytes); + + return value; +} + +/** + * g_variant_new_boolean: + * @value: a #gboolean value + * + * Creates a new boolean #GVariant instance -- either %TRUE or %FALSE. + * + * Returns: (transfer none): a floating reference to a new boolean #GVariant instance + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_boolean (gboolean value) +{ + guchar v = value; + + return g_variant_new_from_trusted (G_VARIANT_TYPE_BOOLEAN, &v, 1); +} + +/** + * g_variant_get_boolean: + * @value: a boolean #GVariant instance + * + * Returns the boolean value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_BOOLEAN. + * + * Returns: %TRUE or %FALSE + * + * Since: 2.24 + **/ +gboolean +g_variant_get_boolean (GVariant *value) +{ + const guchar *data; + + TYPE_CHECK (value, G_VARIANT_TYPE_BOOLEAN, FALSE); + + data = g_variant_get_data (value); + + return data != NULL ? *data != 0 : FALSE; +} + +/* the constructors and accessors for byte, int{16,32,64}, handles and + * doubles all look pretty much exactly the same, so we reduce + * copy/pasting here. + */ +#define NUMERIC_TYPE(TYPE, type, ctype) \ + GVariant *g_variant_new_##type (ctype value) { \ + return g_variant_new_from_trusted (G_VARIANT_TYPE_##TYPE, \ + &value, sizeof value); \ + } \ + ctype g_variant_get_##type (GVariant *value) { \ + const ctype *data; \ + TYPE_CHECK (value, G_VARIANT_TYPE_ ## TYPE, 0); \ + data = g_variant_get_data (value); \ + return data != NULL ? *data : 0; \ + } + + +/** + * g_variant_new_byte: + * @value: a #guint8 value + * + * Creates a new byte #GVariant instance. + * + * Returns: (transfer none): a floating reference to a new byte #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_byte: + * @value: a byte #GVariant instance + * + * Returns the byte value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_BYTE. + * + * Returns: a #guchar + * + * Since: 2.24 + **/ +NUMERIC_TYPE (BYTE, byte, guchar) + +/** + * g_variant_new_int16: + * @value: a #gint16 value + * + * Creates a new int16 #GVariant instance. + * + * Returns: (transfer none): a floating reference to a new int16 #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_int16: + * @value: a int16 #GVariant instance + * + * Returns the 16-bit signed integer value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_INT16. + * + * Returns: a #gint16 + * + * Since: 2.24 + **/ +NUMERIC_TYPE (INT16, int16, gint16) + +/** + * g_variant_new_uint16: + * @value: a #guint16 value + * + * Creates a new uint16 #GVariant instance. + * + * Returns: (transfer none): a floating reference to a new uint16 #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_uint16: + * @value: a uint16 #GVariant instance + * + * Returns the 16-bit unsigned integer value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_UINT16. + * + * Returns: a #guint16 + * + * Since: 2.24 + **/ +NUMERIC_TYPE (UINT16, uint16, guint16) + +/** + * g_variant_new_int32: + * @value: a #gint32 value + * + * Creates a new int32 #GVariant instance. + * + * Returns: (transfer none): a floating reference to a new int32 #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_int32: + * @value: a int32 #GVariant instance + * + * Returns the 32-bit signed integer value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_INT32. + * + * Returns: a #gint32 + * + * Since: 2.24 + **/ +NUMERIC_TYPE (INT32, int32, gint32) + +/** + * g_variant_new_uint32: + * @value: a #guint32 value + * + * Creates a new uint32 #GVariant instance. + * + * Returns: (transfer none): a floating reference to a new uint32 #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_uint32: + * @value: a uint32 #GVariant instance + * + * Returns the 32-bit unsigned integer value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_UINT32. + * + * Returns: a #guint32 + * + * Since: 2.24 + **/ +NUMERIC_TYPE (UINT32, uint32, guint32) + +/** + * g_variant_new_int64: + * @value: a #gint64 value + * + * Creates a new int64 #GVariant instance. + * + * Returns: (transfer none): a floating reference to a new int64 #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_int64: + * @value: a int64 #GVariant instance + * + * Returns the 64-bit signed integer value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_INT64. + * + * Returns: a #gint64 + * + * Since: 2.24 + **/ +NUMERIC_TYPE (INT64, int64, gint64) + +/** + * g_variant_new_uint64: + * @value: a #guint64 value + * + * Creates a new uint64 #GVariant instance. + * + * Returns: (transfer none): a floating reference to a new uint64 #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_uint64: + * @value: a uint64 #GVariant instance + * + * Returns the 64-bit unsigned integer value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_UINT64. + * + * Returns: a #guint64 + * + * Since: 2.24 + **/ +NUMERIC_TYPE (UINT64, uint64, guint64) + +/** + * g_variant_new_handle: + * @value: a #gint32 value + * + * Creates a new handle #GVariant instance. + * + * By convention, handles are indexes into an array of file descriptors + * that are sent alongside a D-Bus message. If you're not interacting + * with D-Bus, you probably don't need them. + * + * Returns: (transfer none): a floating reference to a new handle #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_handle: + * @value: a handle #GVariant instance + * + * Returns the 32-bit signed integer value of @value. + * + * It is an error to call this function with a @value of any type other + * than %G_VARIANT_TYPE_HANDLE. + * + * By convention, handles are indexes into an array of file descriptors + * that are sent alongside a D-Bus message. If you're not interacting + * with D-Bus, you probably don't need them. + * + * Returns: a #gint32 + * + * Since: 2.24 + **/ +NUMERIC_TYPE (HANDLE, handle, gint32) + +/** + * g_variant_new_double: + * @value: a #gdouble floating point value + * + * Creates a new double #GVariant instance. + * + * Returns: (transfer none): a floating reference to a new double #GVariant instance + * + * Since: 2.24 + **/ +/** + * g_variant_get_double: + * @value: a double #GVariant instance + * + * Returns the double precision floating point value of @value. + * + * It is an error to call this function with a @value of any type + * other than %G_VARIANT_TYPE_DOUBLE. + * + * Returns: a #gdouble + * + * Since: 2.24 + **/ +NUMERIC_TYPE (DOUBLE, double, gdouble) + +/* Container type Constructor / Deconstructors {{{1 */ +/** + * g_variant_new_maybe: + * @child_type: (allow-none): the #GVariantType of the child, or %NULL + * @child: (allow-none): the child value, or %NULL + * + * Depending on if @child is %NULL, either wraps @child inside of a + * maybe container or creates a Nothing instance for the given @type. + * + * At least one of @child_type and @child must be non-%NULL. + * If @child_type is non-%NULL then it must be a definite type. + * If they are both non-%NULL then @child_type must be the type + * of @child. + * + * If @child is a floating reference (see g_variant_ref_sink()), the new + * instance takes ownership of @child. + * + * Returns: (transfer none): a floating reference to a new #GVariant maybe instance + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_maybe (const GVariantType *child_type, + GVariant *child) +{ + GVariantType *maybe_type; + GVariant *value; + + g_return_val_if_fail (child_type == NULL || g_variant_type_is_definite + (child_type), 0); + g_return_val_if_fail (child_type != NULL || child != NULL, NULL); + g_return_val_if_fail (child_type == NULL || child == NULL || + g_variant_is_of_type (child, child_type), + NULL); + + if (child_type == NULL) + child_type = g_variant_get_type (child); + + maybe_type = g_variant_type_new_maybe (child_type); + + if (child != NULL) + { + GVariant **children; + gboolean trusted; + + children = g_new (GVariant *, 1); + children[0] = g_variant_ref_sink (child); + trusted = g_variant_is_trusted (children[0]); + + value = g_variant_new_from_children (maybe_type, children, 1, trusted); + } + else + value = g_variant_new_from_children (maybe_type, NULL, 0, TRUE); + + g_variant_type_free (maybe_type); + + return value; +} + +/** + * g_variant_get_maybe: + * @value: a maybe-typed value + * + * Given a maybe-typed #GVariant instance, extract its value. If the + * value is Nothing, then this function returns %NULL. + * + * Returns: (allow-none) (transfer full): the contents of @value, or %NULL + * + * Since: 2.24 + **/ +GVariant * +g_variant_get_maybe (GVariant *value) +{ + TYPE_CHECK (value, G_VARIANT_TYPE_MAYBE, NULL); + + if (g_variant_n_children (value)) + return g_variant_get_child_value (value, 0); + + return NULL; +} + +/** + * g_variant_new_variant: (constructor) + * @value: a #GVariant instance + * + * Boxes @value. The result is a #GVariant instance representing a + * variant containing the original value. + * + * If @child is a floating reference (see g_variant_ref_sink()), the new + * instance takes ownership of @child. + * + * Returns: (transfer none): a floating reference to a new variant #GVariant instance + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_variant (GVariant *value) +{ + g_return_val_if_fail (value != NULL, NULL); + + g_variant_ref_sink (value); + + return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT, + g_memdup (&value, sizeof value), + 1, g_variant_is_trusted (value)); +} + +/** + * g_variant_get_variant: + * @value: a variant #GVariant instance + * + * Unboxes @value. The result is the #GVariant instance that was + * contained in @value. + * + * Returns: (transfer full): the item contained in the variant + * + * Since: 2.24 + **/ +GVariant * +g_variant_get_variant (GVariant *value) +{ + TYPE_CHECK (value, G_VARIANT_TYPE_VARIANT, NULL); + + return g_variant_get_child_value (value, 0); +} + +/** + * g_variant_new_array: + * @child_type: (allow-none): the element type of the new array + * @children: (allow-none) (array length=n_children): an array of + * #GVariant pointers, the children + * @n_children: the length of @children + * + * Creates a new #GVariant array from @children. + * + * @child_type must be non-%NULL if @n_children is zero. Otherwise, the + * child type is determined by inspecting the first element of the + * @children array. If @child_type is non-%NULL then it must be a + * definite type. + * + * The items of the array are taken from the @children array. No entry + * in the @children array may be %NULL. + * + * All items in the array must have the same type, which must be the + * same as @child_type, if given. + * + * If the @children are floating references (see g_variant_ref_sink()), the + * new instance takes ownership of them as if via g_variant_ref_sink(). + * + * Returns: (transfer none): a floating reference to a new #GVariant array + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_array (const GVariantType *child_type, + GVariant * const *children, + gsize n_children) +{ + GVariantType *array_type; + GVariant **my_children; + gboolean trusted; + GVariant *value; + gsize i; + + g_return_val_if_fail (n_children > 0 || child_type != NULL, NULL); + g_return_val_if_fail (n_children == 0 || children != NULL, NULL); + g_return_val_if_fail (child_type == NULL || + g_variant_type_is_definite (child_type), NULL); + + my_children = g_new (GVariant *, n_children); + trusted = TRUE; + + if (child_type == NULL) + child_type = g_variant_get_type (children[0]); + array_type = g_variant_type_new_array (child_type); + + for (i = 0; i < n_children; i++) + { + TYPE_CHECK (children[i], child_type, NULL); + my_children[i] = g_variant_ref_sink (children[i]); + trusted &= g_variant_is_trusted (children[i]); + } + + value = g_variant_new_from_children (array_type, my_children, + n_children, trusted); + g_variant_type_free (array_type); + + return value; +} + +/*< private > + * g_variant_make_tuple_type: + * @children: (array length=n_children): an array of GVariant * + * @n_children: the length of @children + * + * Return the type of a tuple containing @children as its items. + **/ +static GVariantType * +g_variant_make_tuple_type (GVariant * const *children, + gsize n_children) +{ + const GVariantType **types; + GVariantType *type; + gsize i; + + types = g_new (const GVariantType *, n_children); + + for (i = 0; i < n_children; i++) + types[i] = g_variant_get_type (children[i]); + + type = g_variant_type_new_tuple (types, n_children); + g_free (types); + + return type; +} + +/** + * g_variant_new_tuple: + * @children: (array length=n_children): the items to make the tuple out of + * @n_children: the length of @children + * + * Creates a new tuple #GVariant out of the items in @children. The + * type is determined from the types of @children. No entry in the + * @children array may be %NULL. + * + * If @n_children is 0 then the unit tuple is constructed. + * + * If the @children are floating references (see g_variant_ref_sink()), the + * new instance takes ownership of them as if via g_variant_ref_sink(). + * + * Returns: (transfer none): a floating reference to a new #GVariant tuple + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_tuple (GVariant * const *children, + gsize n_children) +{ + GVariantType *tuple_type; + GVariant **my_children; + gboolean trusted; + GVariant *value; + gsize i; + + g_return_val_if_fail (n_children == 0 || children != NULL, NULL); + + my_children = g_new (GVariant *, n_children); + trusted = TRUE; + + for (i = 0; i < n_children; i++) + { + my_children[i] = g_variant_ref_sink (children[i]); + trusted &= g_variant_is_trusted (children[i]); + } + + tuple_type = g_variant_make_tuple_type (children, n_children); + value = g_variant_new_from_children (tuple_type, my_children, + n_children, trusted); + g_variant_type_free (tuple_type); + + return value; +} + +/*< private > + * g_variant_make_dict_entry_type: + * @key: a #GVariant, the key + * @val: a #GVariant, the value + * + * Return the type of a dictionary entry containing @key and @val as its + * children. + **/ +static GVariantType * +g_variant_make_dict_entry_type (GVariant *key, + GVariant *val) +{ + return g_variant_type_new_dict_entry (g_variant_get_type (key), + g_variant_get_type (val)); +} + +/** + * g_variant_new_dict_entry: (constructor) + * @key: a basic #GVariant, the key + * @value: a #GVariant, the value + * + * Creates a new dictionary entry #GVariant. @key and @value must be + * non-%NULL. @key must be a value of a basic type (ie: not a container). + * + * If the @key or @value are floating references (see g_variant_ref_sink()), + * the new instance takes ownership of them as if via g_variant_ref_sink(). + * + * Returns: (transfer none): a floating reference to a new dictionary entry #GVariant + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_dict_entry (GVariant *key, + GVariant *value) +{ + GVariantType *dict_type; + GVariant **children; + gboolean trusted; + + g_return_val_if_fail (key != NULL && value != NULL, NULL); + g_return_val_if_fail (!g_variant_is_container (key), NULL); + + children = g_new (GVariant *, 2); + children[0] = g_variant_ref_sink (key); + children[1] = g_variant_ref_sink (value); + trusted = g_variant_is_trusted (key) && g_variant_is_trusted (value); + + dict_type = g_variant_make_dict_entry_type (key, value); + value = g_variant_new_from_children (dict_type, children, 2, trusted); + g_variant_type_free (dict_type); + + return value; +} + +/** + * g_variant_lookup: (skip) + * @dictionary: a dictionary #GVariant + * @key: the key to lookup in the dictionary + * @format_string: a GVariant format string + * @...: the arguments to unpack the value into + * + * Looks up a value in a dictionary #GVariant. + * + * This function is a wrapper around g_variant_lookup_value() and + * g_variant_get(). In the case that %NULL would have been returned, + * this function returns %FALSE. Otherwise, it unpacks the returned + * value and returns %TRUE. + * + * See g_variant_get() for information about @format_string. + * + * Returns: %TRUE if a value was unpacked + * + * Since: 2.28 + */ +gboolean +g_variant_lookup (GVariant *dictionary, + const gchar *key, + const gchar *format_string, + ...) +{ + GVariantType *type; + GVariant *value; + + /* flatten */ + g_variant_get_data (dictionary); + + type = g_variant_format_string_scan_type (format_string, NULL, NULL); + value = g_variant_lookup_value (dictionary, key, type); + g_variant_type_free (type); + + if (value) + { + va_list ap; + + va_start (ap, format_string); + g_variant_get_va (value, format_string, NULL, &ap); + g_variant_unref (value); + va_end (ap); + + return TRUE; + } + + else + return FALSE; +} + +/** + * g_variant_lookup_value: + * @dictionary: a dictionary #GVariant + * @key: the key to lookup in the dictionary + * @expected_type: (allow-none): a #GVariantType, or %NULL + * + * Looks up a value in a dictionary #GVariant. + * + * This function works with dictionaries of the type + * a{s*} (and equally well with type + * a{o*}, but we only further discuss the string case + * for sake of clarity). + * + * In the event that @dictionary has the type a{sv}, + * the @expected_type string specifies what type of value is expected to + * be inside of the variant. If the value inside the variant has a + * different type then %NULL is returned. In the event that @dictionary + * has a value type other than v then @expected_type + * must directly match the key type and it is used to unpack the value + * directly or an error occurs. + * + * In either case, if @key is not found in @dictionary, %NULL is + * returned. + * + * If the key is found and the value has the correct type, it is + * returned. If @expected_type was specified then any non-%NULL return + * value will have this type. + * + * Returns: (transfer full): the value of the dictionary key, or %NULL + * + * Since: 2.28 + */ +GVariant * +g_variant_lookup_value (GVariant *dictionary, + const gchar *key, + const GVariantType *expected_type) +{ + GVariantIter iter; + GVariant *entry; + GVariant *value; + + g_return_val_if_fail (g_variant_is_of_type (dictionary, + G_VARIANT_TYPE ("a{s*}")) || + g_variant_is_of_type (dictionary, + G_VARIANT_TYPE ("a{o*}")), + NULL); + + g_variant_iter_init (&iter, dictionary); + + while ((entry = g_variant_iter_next_value (&iter))) + { + GVariant *entry_key; + gboolean matches; + + entry_key = g_variant_get_child_value (entry, 0); + matches = strcmp (g_variant_get_string (entry_key, NULL), key) == 0; + g_variant_unref (entry_key); + + if (matches) + break; + + g_variant_unref (entry); + } + + if (entry == NULL) + return NULL; + + value = g_variant_get_child_value (entry, 1); + g_variant_unref (entry); + + if (g_variant_is_of_type (value, G_VARIANT_TYPE_VARIANT)) + { + GVariant *tmp; + + tmp = g_variant_get_variant (value); + g_variant_unref (value); + + if (expected_type && !g_variant_is_of_type (tmp, expected_type)) + { + g_variant_unref (tmp); + tmp = NULL; + } + + value = tmp; + } + + g_return_val_if_fail (expected_type == NULL || value == NULL || + g_variant_is_of_type (value, expected_type), NULL); + + return value; +} + +/** + * g_variant_get_fixed_array: + * @value: a #GVariant array with fixed-sized elements + * @n_elements: (out): a pointer to the location to store the number of items + * @element_size: the size of each element + * + * Provides access to the serialised data for an array of fixed-sized + * items. + * + * @value must be an array with fixed-sized elements. Numeric types are + * fixed-size, as are tuples containing only other fixed-sized types. + * + * @element_size must be the size of a single element in the array, + * as given by the section on + * Serialised Data + * Memory. + * + * In particular, arrays of these fixed-sized types can be interpreted + * as an array of the given C type, with @element_size set to + * sizeof the appropriate type: + * + * + * + * element type C type + * + * %G_VARIANT_TYPE_INT16 (etc.) + * #gint16 (etc.) + * %G_VARIANT_TYPE_BOOLEAN + * #guchar (not #gboolean!) + * %G_VARIANT_TYPE_BYTE #guchar + * %G_VARIANT_TYPE_HANDLE #guint32 + * %G_VARIANT_TYPE_DOUBLE #gdouble + * + * + * + * + * For example, if calling this function for an array of 32 bit integers, + * you might say sizeof (gint32). This value isn't used + * except for the purpose of a double-check that the form of the + * serialised data matches the caller's expectation. + * + * @n_elements, which must be non-%NULL is set equal to the number of + * items in the array. + * + * Returns: (array length=n_elements) (transfer none): a pointer to + * the fixed array + * + * Since: 2.24 + **/ +gconstpointer +g_variant_get_fixed_array (GVariant *value, + gsize *n_elements, + gsize element_size) +{ + GVariantTypeInfo *array_info; + gsize array_element_size; + gconstpointer data; + gsize size; + + TYPE_CHECK (value, G_VARIANT_TYPE_ARRAY, NULL); + + g_return_val_if_fail (n_elements != NULL, NULL); + g_return_val_if_fail (element_size > 0, NULL); + + array_info = g_variant_get_type_info (value); + g_variant_type_info_query_element (array_info, NULL, &array_element_size); + + g_return_val_if_fail (array_element_size, NULL); + + if G_UNLIKELY (array_element_size != element_size) + { + if (array_element_size) + g_critical ("g_variant_get_fixed_array: assertion " + "`g_variant_array_has_fixed_size (value, element_size)' " + "failed: array size %"G_GSIZE_FORMAT" does not match " + "given element_size %"G_GSIZE_FORMAT".", + array_element_size, element_size); + else + g_critical ("g_variant_get_fixed_array: assertion " + "`g_variant_array_has_fixed_size (value, element_size)' " + "failed: array does not have fixed size."); + } + + data = g_variant_get_data (value); + size = g_variant_get_size (value); + + if (size % element_size) + *n_elements = 0; + else + *n_elements = size / element_size; + + if (*n_elements) + return data; + + return NULL; +} + +/** + * g_variant_new_fixed_array: + * @element_type: the #GVariantType of each element + * @elements: a pointer to the fixed array of contiguous elements + * @n_elements: the number of elements + * @element_size: the size of each element + * + * Provides access to the serialised data for an array of fixed-sized + * items. + * + * @value must be an array with fixed-sized elements. Numeric types are + * fixed-size as are tuples containing only other fixed-sized types. + * + * @element_size must be the size of a single element in the array. For + * example, if calling this function for an array of 32 bit integers, + * you might say sizeof (gint32). This value isn't used + * except for the purpose of a double-check that the form of the + * serialised data matches the caller's expectation. + * + * @n_elements, which must be non-%NULL is set equal to the number of + * items in the array. + * + * Returns: (transfer none): a floating reference to a new array #GVariant instance + * + * Since: 2.32 + **/ +GVariant * +g_variant_new_fixed_array (const GVariantType *element_type, + gconstpointer elements, + gsize n_elements, + gsize element_size) +{ + GVariantType *array_type; + gsize array_element_size; + GVariantTypeInfo *array_info; + GVariant *value; + gpointer data; + + g_return_val_if_fail (g_variant_type_is_definite (element_type), NULL); + g_return_val_if_fail (element_size > 0, NULL); + + array_type = g_variant_type_new_array (element_type); + array_info = g_variant_type_info_get (array_type); + g_variant_type_info_query_element (array_info, NULL, &array_element_size); + if G_UNLIKELY (array_element_size != element_size) + { + if (array_element_size) + g_critical ("g_variant_new_fixed_array: array size %" G_GSIZE_FORMAT + " does not match given element_size %" G_GSIZE_FORMAT ".", + array_element_size, element_size); + else + g_critical ("g_variant_get_fixed_array: array does not have fixed size."); + return NULL; + } + + data = g_memdup (elements, n_elements * element_size); + value = g_variant_new_from_data (array_type, data, + n_elements * element_size, + FALSE, g_free, data); + + g_variant_type_free (array_type); + g_variant_type_info_unref (array_info); + + return value; +} + +/* String type constructor/getters/validation {{{1 */ +/** + * g_variant_new_string: + * @string: a normal utf8 nul-terminated string + * + * Creates a string #GVariant with the contents of @string. + * + * @string must be valid utf8. + * + * Returns: (transfer none): a floating reference to a new string #GVariant instance + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_string (const gchar *string) +{ + g_return_val_if_fail (string != NULL, NULL); + g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL); + + return g_variant_new_from_trusted (G_VARIANT_TYPE_STRING, + string, strlen (string) + 1); +} + +/** + * g_variant_new_object_path: + * @object_path: a normal C nul-terminated string + * + * Creates a D-Bus object path #GVariant with the contents of @string. + * @string must be a valid D-Bus object path. Use + * g_variant_is_object_path() if you're not sure. + * + * Returns: (transfer none): a floating reference to a new object path #GVariant instance + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_object_path (const gchar *object_path) +{ + g_return_val_if_fail (g_variant_is_object_path (object_path), NULL); + + return g_variant_new_from_trusted (G_VARIANT_TYPE_OBJECT_PATH, + object_path, strlen (object_path) + 1); +} + +/** + * g_variant_is_object_path: + * @string: a normal C nul-terminated string + * + * Determines if a given string is a valid D-Bus object path. You + * should ensure that a string is a valid D-Bus object path before + * passing it to g_variant_new_object_path(). + * + * A valid object path starts with '/' followed by zero or more + * sequences of characters separated by '/' characters. Each sequence + * must contain only the characters "[A-Z][a-z][0-9]_". No sequence + * (including the one following the final '/' character) may be empty. + * + * Returns: %TRUE if @string is a D-Bus object path + * + * Since: 2.24 + **/ +gboolean +g_variant_is_object_path (const gchar *string) +{ + g_return_val_if_fail (string != NULL, FALSE); + + return g_variant_serialiser_is_object_path (string, strlen (string) + 1); +} + +/** + * g_variant_new_signature: + * @signature: a normal C nul-terminated string + * + * Creates a D-Bus type signature #GVariant with the contents of + * @string. @string must be a valid D-Bus type signature. Use + * g_variant_is_signature() if you're not sure. + * + * Returns: (transfer none): a floating reference to a new signature #GVariant instance + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_signature (const gchar *signature) +{ + g_return_val_if_fail (g_variant_is_signature (signature), NULL); + + return g_variant_new_from_trusted (G_VARIANT_TYPE_SIGNATURE, + signature, strlen (signature) + 1); +} + +/** + * g_variant_is_signature: + * @string: a normal C nul-terminated string + * + * Determines if a given string is a valid D-Bus type signature. You + * should ensure that a string is a valid D-Bus type signature before + * passing it to g_variant_new_signature(). + * + * D-Bus type signatures consist of zero or more definite #GVariantType + * strings in sequence. + * + * Returns: %TRUE if @string is a D-Bus type signature + * + * Since: 2.24 + **/ +gboolean +g_variant_is_signature (const gchar *string) +{ + g_return_val_if_fail (string != NULL, FALSE); + + return g_variant_serialiser_is_signature (string, strlen (string) + 1); +} + +/** + * g_variant_get_string: + * @value: a string #GVariant instance + * @length: (allow-none) (default 0) (out): a pointer to a #gsize, + * to store the length + * + * Returns the string value of a #GVariant instance with a string + * type. This includes the types %G_VARIANT_TYPE_STRING, + * %G_VARIANT_TYPE_OBJECT_PATH and %G_VARIANT_TYPE_SIGNATURE. + * + * The string will always be utf8 encoded. + * + * If @length is non-%NULL then the length of the string (in bytes) is + * returned there. For trusted values, this information is already + * known. For untrusted values, a strlen() will be performed. + * + * It is an error to call this function with a @value of any type + * other than those three. + * + * The return value remains valid as long as @value exists. + * + * Returns: (transfer none): the constant string, utf8 encoded + * + * Since: 2.24 + **/ +const gchar * +g_variant_get_string (GVariant *value, + gsize *length) +{ + gconstpointer data; + gsize size; + + g_return_val_if_fail (value != NULL, NULL); + g_return_val_if_fail ( + g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) || + g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH) || + g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE), NULL); + + data = g_variant_get_data (value); + size = g_variant_get_size (value); + + if (!g_variant_is_trusted (value)) + { + switch (g_variant_classify (value)) + { + case G_VARIANT_CLASS_STRING: + if (g_variant_serialiser_is_string (data, size)) + break; + + data = ""; + size = 1; + break; + + case G_VARIANT_CLASS_OBJECT_PATH: + if (g_variant_serialiser_is_object_path (data, size)) + break; + + data = "/"; + size = 2; + break; + + case G_VARIANT_CLASS_SIGNATURE: + if (g_variant_serialiser_is_signature (data, size)) + break; + + data = ""; + size = 1; + break; + + default: + g_assert_not_reached (); + } + } + + if (length) + *length = size - 1; + + return data; +} + +/** + * g_variant_dup_string: + * @value: a string #GVariant instance + * @length: (out): a pointer to a #gsize, to store the length + * + * Similar to g_variant_get_string() except that instead of returning + * a constant string, the string is duplicated. + * + * The string will always be utf8 encoded. + * + * The return value must be freed using g_free(). + * + * Returns: (transfer full): a newly allocated string, utf8 encoded + * + * Since: 2.24 + **/ +gchar * +g_variant_dup_string (GVariant *value, + gsize *length) +{ + return g_strdup (g_variant_get_string (value, length)); +} + +/** + * g_variant_new_strv: + * @strv: (array length=length) (element-type utf8): an array of strings + * @length: the length of @strv, or -1 + * + * Constructs an array of strings #GVariant from the given array of + * strings. + * + * If @length is -1 then @strv is %NULL-terminated. + * + * Returns: (transfer none): a new floating #GVariant instance + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_strv (const gchar * const *strv, + gssize length) +{ + GVariant **strings; + gsize i; + + g_return_val_if_fail (length == 0 || strv != NULL, NULL); + + if (length < 0) + length = g_strv_length ((gchar **) strv); + + strings = g_new (GVariant *, length); + for (i = 0; i < length; i++) + strings[i] = g_variant_ref_sink (g_variant_new_string (strv[i])); + + return g_variant_new_from_children (G_VARIANT_TYPE_STRING_ARRAY, + strings, length, TRUE); +} + +/** + * g_variant_get_strv: + * @value: an array of strings #GVariant + * @length: (out) (allow-none): the length of the result, or %NULL + * + * Gets the contents of an array of strings #GVariant. This call + * makes a shallow copy; the return result should be released with + * g_free(), but the individual strings must not be modified. + * + * If @length is non-%NULL then the number of elements in the result + * is stored there. In any case, the resulting array will be + * %NULL-terminated. + * + * For an empty array, @length will be set to 0 and a pointer to a + * %NULL pointer will be returned. + * + * Returns: (array length=length zero-terminated=1) (transfer container): an array of constant strings + * + * Since: 2.24 + **/ +const gchar ** +g_variant_get_strv (GVariant *value, + gsize *length) +{ + const gchar **strv; + gsize n; + gsize i; + + TYPE_CHECK (value, G_VARIANT_TYPE_STRING_ARRAY, NULL); + + g_variant_get_data (value); + n = g_variant_n_children (value); + strv = g_new (const gchar *, n + 1); + + for (i = 0; i < n; i++) + { + GVariant *string; + + string = g_variant_get_child_value (value, i); + strv[i] = g_variant_get_string (string, NULL); + g_variant_unref (string); + } + strv[i] = NULL; + + if (length) + *length = n; + + return strv; +} + +/** + * g_variant_dup_strv: + * @value: an array of strings #GVariant + * @length: (out) (allow-none): the length of the result, or %NULL + * + * Gets the contents of an array of strings #GVariant. This call + * makes a deep copy; the return result should be released with + * g_strfreev(). + * + * If @length is non-%NULL then the number of elements in the result + * is stored there. In any case, the resulting array will be + * %NULL-terminated. + * + * For an empty array, @length will be set to 0 and a pointer to a + * %NULL pointer will be returned. + * + * Returns: (array length=length zero-terminated=1) (transfer full): an array of strings + * + * Since: 2.24 + **/ +gchar ** +g_variant_dup_strv (GVariant *value, + gsize *length) +{ + gchar **strv; + gsize n; + gsize i; + + TYPE_CHECK (value, G_VARIANT_TYPE_STRING_ARRAY, NULL); + + n = g_variant_n_children (value); + strv = g_new (gchar *, n + 1); + + for (i = 0; i < n; i++) + { + GVariant *string; + + string = g_variant_get_child_value (value, i); + strv[i] = g_variant_dup_string (string, NULL); + g_variant_unref (string); + } + strv[i] = NULL; + + if (length) + *length = n; + + return strv; +} + +/** + * g_variant_new_objv: + * @strv: (array length=length) (element-type utf8): an array of strings + * @length: the length of @strv, or -1 + * + * Constructs an array of object paths #GVariant from the given array of + * strings. + * + * Each string must be a valid #GVariant object path; see + * g_variant_is_object_path(). + * + * If @length is -1 then @strv is %NULL-terminated. + * + * Returns: (transfer none): a new floating #GVariant instance + * + * Since: 2.30 + **/ +GVariant * +g_variant_new_objv (const gchar * const *strv, + gssize length) +{ + GVariant **strings; + gsize i; + + g_return_val_if_fail (length == 0 || strv != NULL, NULL); + + if (length < 0) + length = g_strv_length ((gchar **) strv); + + strings = g_new (GVariant *, length); + for (i = 0; i < length; i++) + strings[i] = g_variant_ref_sink (g_variant_new_object_path (strv[i])); + + return g_variant_new_from_children (G_VARIANT_TYPE_OBJECT_PATH_ARRAY, + strings, length, TRUE); +} + +/** + * g_variant_get_objv: + * @value: an array of object paths #GVariant + * @length: (out) (allow-none): the length of the result, or %NULL + * + * Gets the contents of an array of object paths #GVariant. This call + * makes a shallow copy; the return result should be released with + * g_free(), but the individual strings must not be modified. + * + * If @length is non-%NULL then the number of elements in the result + * is stored there. In any case, the resulting array will be + * %NULL-terminated. + * + * For an empty array, @length will be set to 0 and a pointer to a + * %NULL pointer will be returned. + * + * Returns: (array length=length zero-terminated=1) (transfer container): an array of constant strings + * + * Since: 2.30 + **/ +const gchar ** +g_variant_get_objv (GVariant *value, + gsize *length) +{ + const gchar **strv; + gsize n; + gsize i; + + TYPE_CHECK (value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY, NULL); + + g_variant_get_data (value); + n = g_variant_n_children (value); + strv = g_new (const gchar *, n + 1); + + for (i = 0; i < n; i++) + { + GVariant *string; + + string = g_variant_get_child_value (value, i); + strv[i] = g_variant_get_string (string, NULL); + g_variant_unref (string); + } + strv[i] = NULL; + + if (length) + *length = n; + + return strv; +} + +/** + * g_variant_dup_objv: + * @value: an array of object paths #GVariant + * @length: (out) (allow-none): the length of the result, or %NULL + * + * Gets the contents of an array of object paths #GVariant. This call + * makes a deep copy; the return result should be released with + * g_strfreev(). + * + * If @length is non-%NULL then the number of elements in the result + * is stored there. In any case, the resulting array will be + * %NULL-terminated. + * + * For an empty array, @length will be set to 0 and a pointer to a + * %NULL pointer will be returned. + * + * Returns: (array length=length zero-terminated=1) (transfer full): an array of strings + * + * Since: 2.30 + **/ +gchar ** +g_variant_dup_objv (GVariant *value, + gsize *length) +{ + gchar **strv; + gsize n; + gsize i; + + TYPE_CHECK (value, G_VARIANT_TYPE_OBJECT_PATH_ARRAY, NULL); + + n = g_variant_n_children (value); + strv = g_new (gchar *, n + 1); + + for (i = 0; i < n; i++) + { + GVariant *string; + + string = g_variant_get_child_value (value, i); + strv[i] = g_variant_dup_string (string, NULL); + g_variant_unref (string); + } + strv[i] = NULL; + + if (length) + *length = n; + + return strv; +} + + +/** + * g_variant_new_bytestring: + * @string: (array zero-terminated=1) (element-type guint8): a normal + * nul-terminated string in no particular encoding + * + * Creates an array-of-bytes #GVariant with the contents of @string. + * This function is just like g_variant_new_string() except that the + * string need not be valid utf8. + * + * The nul terminator character at the end of the string is stored in + * the array. + * + * Returns: (transfer none): a floating reference to a new bytestring #GVariant instance + * + * Since: 2.26 + **/ +GVariant * +g_variant_new_bytestring (const gchar *string) +{ + g_return_val_if_fail (string != NULL, NULL); + + return g_variant_new_from_trusted (G_VARIANT_TYPE_BYTESTRING, + string, strlen (string) + 1); +} + +/** + * g_variant_get_bytestring: + * @value: an array-of-bytes #GVariant instance + * + * Returns the string value of a #GVariant instance with an + * array-of-bytes type. The string has no particular encoding. + * + * If the array does not end with a nul terminator character, the empty + * string is returned. For this reason, you can always trust that a + * non-%NULL nul-terminated string will be returned by this function. + * + * If the array contains a nul terminator character somewhere other than + * the last byte then the returned string is the string, up to the first + * such nul character. + * + * It is an error to call this function with a @value that is not an + * array of bytes. + * + * The return value remains valid as long as @value exists. + * + * Returns: (transfer none) (array zero-terminated=1) (element-type guint8): + * the constant string + * + * Since: 2.26 + **/ +const gchar * +g_variant_get_bytestring (GVariant *value) +{ + const gchar *string; + gsize size; + + TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING, NULL); + + /* Won't be NULL since this is an array type */ + string = g_variant_get_data (value); + size = g_variant_get_size (value); + + if (size && string[size - 1] == '\0') + return string; + else + return ""; +} + +/** + * g_variant_dup_bytestring: + * @value: an array-of-bytes #GVariant instance + * @length: (out) (allow-none) (default NULL): a pointer to a #gsize, to store + * the length (not including the nul terminator) + * + * Similar to g_variant_get_bytestring() except that instead of + * returning a constant string, the string is duplicated. + * + * The return value must be freed using g_free(). + * + * Returns: (transfer full) (array zero-terminated=1 length=length) + * (element-type guint8): a newly allocated string + * + * Since: 2.26 + **/ +gchar * +g_variant_dup_bytestring (GVariant *value, + gsize *length) +{ + const gchar *original = g_variant_get_bytestring (value); + gsize size; + + /* don't crash in case get_bytestring() had an assert failure */ + if (original == NULL) + return NULL; + + size = strlen (original); + + if (length) + *length = size; + + return g_memdup (original, size + 1); +} + +/** + * g_variant_new_bytestring_array: + * @strv: (array length=length): an array of strings + * @length: the length of @strv, or -1 + * + * Constructs an array of bytestring #GVariant from the given array of + * strings. + * + * If @length is -1 then @strv is %NULL-terminated. + * + * Returns: (transfer none): a new floating #GVariant instance + * + * Since: 2.26 + **/ +GVariant * +g_variant_new_bytestring_array (const gchar * const *strv, + gssize length) +{ + GVariant **strings; + gsize i; + + g_return_val_if_fail (length == 0 || strv != NULL, NULL); + + if (length < 0) + length = g_strv_length ((gchar **) strv); + + strings = g_new (GVariant *, length); + for (i = 0; i < length; i++) + strings[i] = g_variant_ref_sink (g_variant_new_bytestring (strv[i])); + + return g_variant_new_from_children (G_VARIANT_TYPE_BYTESTRING_ARRAY, + strings, length, TRUE); +} + +/** + * g_variant_get_bytestring_array: + * @value: an array of array of bytes #GVariant ('aay') + * @length: (out) (allow-none): the length of the result, or %NULL + * + * Gets the contents of an array of array of bytes #GVariant. This call + * makes a shallow copy; the return result should be released with + * g_free(), but the individual strings must not be modified. + * + * If @length is non-%NULL then the number of elements in the result is + * stored there. In any case, the resulting array will be + * %NULL-terminated. + * + * For an empty array, @length will be set to 0 and a pointer to a + * %NULL pointer will be returned. + * + * Returns: (array length=length) (transfer container): an array of constant strings + * + * Since: 2.26 + **/ +const gchar ** +g_variant_get_bytestring_array (GVariant *value, + gsize *length) +{ + const gchar **strv; + gsize n; + gsize i; + + TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL); + + g_variant_get_data (value); + n = g_variant_n_children (value); + strv = g_new (const gchar *, n + 1); + + for (i = 0; i < n; i++) + { + GVariant *string; + + string = g_variant_get_child_value (value, i); + strv[i] = g_variant_get_bytestring (string); + g_variant_unref (string); + } + strv[i] = NULL; + + if (length) + *length = n; + + return strv; +} + +/** + * g_variant_dup_bytestring_array: + * @value: an array of array of bytes #GVariant ('aay') + * @length: (out) (allow-none): the length of the result, or %NULL + * + * Gets the contents of an array of array of bytes #GVariant. This call + * makes a deep copy; the return result should be released with + * g_strfreev(). + * + * If @length is non-%NULL then the number of elements in the result is + * stored there. In any case, the resulting array will be + * %NULL-terminated. + * + * For an empty array, @length will be set to 0 and a pointer to a + * %NULL pointer will be returned. + * + * Returns: (array length=length) (transfer full): an array of strings + * + * Since: 2.26 + **/ +gchar ** +g_variant_dup_bytestring_array (GVariant *value, + gsize *length) +{ + gchar **strv; + gsize n; + gsize i; + + TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL); + + g_variant_get_data (value); + n = g_variant_n_children (value); + strv = g_new (gchar *, n + 1); + + for (i = 0; i < n; i++) + { + GVariant *string; + + string = g_variant_get_child_value (value, i); + strv[i] = g_variant_dup_bytestring (string, NULL); + g_variant_unref (string); + } + strv[i] = NULL; + + if (length) + *length = n; + + return strv; +} + +/* Type checking and querying {{{1 */ +/** + * g_variant_get_type: + * @value: a #GVariant + * + * Determines the type of @value. + * + * The return value is valid for the lifetime of @value and must not + * be freed. + * + * Returns: a #GVariantType + * + * Since: 2.24 + **/ +const GVariantType * +g_variant_get_type (GVariant *value) +{ + GVariantTypeInfo *type_info; + + g_return_val_if_fail (value != NULL, NULL); + + type_info = g_variant_get_type_info (value); + + return (GVariantType *) g_variant_type_info_get_type_string (type_info); +} + +/** + * g_variant_get_type_string: + * @value: a #GVariant + * + * Returns the type string of @value. Unlike the result of calling + * g_variant_type_peek_string(), this string is nul-terminated. This + * string belongs to #GVariant and must not be freed. + * + * Returns: the type string for the type of @value + * + * Since: 2.24 + **/ +const gchar * +g_variant_get_type_string (GVariant *value) +{ + GVariantTypeInfo *type_info; + + g_return_val_if_fail (value != NULL, NULL); + + type_info = g_variant_get_type_info (value); + + return g_variant_type_info_get_type_string (type_info); +} + +/** + * g_variant_is_of_type: + * @value: a #GVariant instance + * @type: a #GVariantType + * + * Checks if a value has a type matching the provided type. + * + * Returns: %TRUE if the type of @value matches @type + * + * Since: 2.24 + **/ +gboolean +g_variant_is_of_type (GVariant *value, + const GVariantType *type) +{ + return g_variant_type_is_subtype_of (g_variant_get_type (value), type); +} + +/** + * g_variant_is_container: + * @value: a #GVariant instance + * + * Checks if @value is a container. + * + * Returns: %TRUE if @value is a container + * + * Since: 2.24 + */ +gboolean +g_variant_is_container (GVariant *value) +{ + return g_variant_type_is_container (g_variant_get_type (value)); +} + + +/** + * g_variant_classify: + * @value: a #GVariant + * + * Classifies @value according to its top-level type. + * + * Returns: the #GVariantClass of @value + * + * Since: 2.24 + **/ +/** + * GVariantClass: + * @G_VARIANT_CLASS_BOOLEAN: The #GVariant is a boolean. + * @G_VARIANT_CLASS_BYTE: The #GVariant is a byte. + * @G_VARIANT_CLASS_INT16: The #GVariant is a signed 16 bit integer. + * @G_VARIANT_CLASS_UINT16: The #GVariant is an unsigned 16 bit integer. + * @G_VARIANT_CLASS_INT32: The #GVariant is a signed 32 bit integer. + * @G_VARIANT_CLASS_UINT32: The #GVariant is an unsigned 32 bit integer. + * @G_VARIANT_CLASS_INT64: The #GVariant is a signed 64 bit integer. + * @G_VARIANT_CLASS_UINT64: The #GVariant is an unsigned 64 bit integer. + * @G_VARIANT_CLASS_HANDLE: The #GVariant is a file handle index. + * @G_VARIANT_CLASS_DOUBLE: The #GVariant is a double precision floating + * point value. + * @G_VARIANT_CLASS_STRING: The #GVariant is a normal string. + * @G_VARIANT_CLASS_OBJECT_PATH: The #GVariant is a D-Bus object path + * string. + * @G_VARIANT_CLASS_SIGNATURE: The #GVariant is a D-Bus signature string. + * @G_VARIANT_CLASS_VARIANT: The #GVariant is a variant. + * @G_VARIANT_CLASS_MAYBE: The #GVariant is a maybe-typed value. + * @G_VARIANT_CLASS_ARRAY: The #GVariant is an array. + * @G_VARIANT_CLASS_TUPLE: The #GVariant is a tuple. + * @G_VARIANT_CLASS_DICT_ENTRY: The #GVariant is a dictionary entry. + * + * The range of possible top-level types of #GVariant instances. + * + * Since: 2.24 + **/ +GVariantClass +g_variant_classify (GVariant *value) +{ + g_return_val_if_fail (value != NULL, 0); + + return *g_variant_get_type_string (value); +} + +/* Pretty printer {{{1 */ +/* This function is not introspectable because if @string is NULL, + @returns is (transfer full), otherwise it is (transfer none), which + is not supported by GObjectIntrospection */ +/** + * g_variant_print_string: (skip) + * @value: a #GVariant + * @string: (allow-none) (default NULL): a #GString, or %NULL + * @type_annotate: %TRUE if type information should be included in + * the output + * + * Behaves as g_variant_print(), but operates on a #GString. + * + * If @string is non-%NULL then it is appended to and returned. Else, + * a new empty #GString is allocated and it is returned. + * + * Returns: a #GString containing the string + * + * Since: 2.24 + **/ +GString * +g_variant_print_string (GVariant *value, + GString *string, + gboolean type_annotate) +{ + if G_UNLIKELY (string == NULL) + string = g_string_new (NULL); + + switch (g_variant_classify (value)) + { + case G_VARIANT_CLASS_MAYBE: + if (type_annotate) + g_string_append_printf (string, "@%s ", + g_variant_get_type_string (value)); + + if (g_variant_n_children (value)) + { + gchar *printed_child; + GVariant *element; + + /* Nested maybes: + * + * Consider the case of the type "mmi". In this case we could + * write "just just 4", but "4" alone is totally unambiguous, + * so we try to drop "just" where possible. + * + * We have to be careful not to always drop "just", though, + * since "nothing" needs to be distinguishable from "just + * nothing". The case where we need to ensure we keep the + * "just" is actually exactly the case where we have a nested + * Nothing. + * + * Instead of searching for that nested Nothing, we just print + * the contained value into a separate string and see if we + * end up with "nothing" at the end of it. If so, we need to + * add "just" at our level. + */ + element = g_variant_get_child_value (value, 0); + printed_child = g_variant_print (element, FALSE); + g_variant_unref (element); + + if (g_str_has_suffix (printed_child, "nothing")) + g_string_append (string, "just "); + g_string_append (string, printed_child); + g_free (printed_child); + } + else + g_string_append (string, "nothing"); + + break; + + case G_VARIANT_CLASS_ARRAY: + /* it's an array so the first character of the type string is 'a' + * + * if the first two characters are 'ay' then it's a bytestring. + * under certain conditions we print those as strings. + */ + if (g_variant_get_type_string (value)[1] == 'y') + { + const gchar *str; + gsize size; + gsize i; + + /* first determine if it is a byte string. + * that's when there's a single nul character: at the end. + */ + str = g_variant_get_data (value); + size = g_variant_get_size (value); + + for (i = 0; i < size; i++) + if (str[i] == '\0') + break; + + /* first nul byte is the last byte -> it's a byte string. */ + if (i == size - 1) + { + gchar *escaped = g_strescape (str, NULL); + + /* use double quotes only if a ' is in the string */ + if (strchr (str, '\'')) + g_string_append_printf (string, "b\"%s\"", escaped); + else + g_string_append_printf (string, "b'%s'", escaped); + + g_free (escaped); + break; + } + + else + /* fall through and handle normally... */; + } + + /* + * if the first two characters are 'a{' then it's an array of + * dictionary entries (ie: a dictionary) so we print that + * differently. + */ + if (g_variant_get_type_string (value)[1] == '{') + /* dictionary */ + { + const gchar *comma = ""; + gsize n, i; + + if ((n = g_variant_n_children (value)) == 0) + { + if (type_annotate) + g_string_append_printf (string, "@%s ", + g_variant_get_type_string (value)); + g_string_append (string, "{}"); + break; + } + + g_string_append_c (string, '{'); + for (i = 0; i < n; i++) + { + GVariant *entry, *key, *val; + + g_string_append (string, comma); + comma = ", "; + + entry = g_variant_get_child_value (value, i); + key = g_variant_get_child_value (entry, 0); + val = g_variant_get_child_value (entry, 1); + g_variant_unref (entry); + + g_variant_print_string (key, string, type_annotate); + g_variant_unref (key); + g_string_append (string, ": "); + g_variant_print_string (val, string, type_annotate); + g_variant_unref (val); + type_annotate = FALSE; + } + g_string_append_c (string, '}'); + } + else + /* normal (non-dictionary) array */ + { + const gchar *comma = ""; + gsize n, i; + + if ((n = g_variant_n_children (value)) == 0) + { + if (type_annotate) + g_string_append_printf (string, "@%s ", + g_variant_get_type_string (value)); + g_string_append (string, "[]"); + break; + } + + g_string_append_c (string, '['); + for (i = 0; i < n; i++) + { + GVariant *element; + + g_string_append (string, comma); + comma = ", "; + + element = g_variant_get_child_value (value, i); + + g_variant_print_string (element, string, type_annotate); + g_variant_unref (element); + type_annotate = FALSE; + } + g_string_append_c (string, ']'); + } + + break; + + case G_VARIANT_CLASS_TUPLE: + { + gsize n, i; + + n = g_variant_n_children (value); + + g_string_append_c (string, '('); + for (i = 0; i < n; i++) + { + GVariant *element; + + element = g_variant_get_child_value (value, i); + g_variant_print_string (element, string, type_annotate); + g_string_append (string, ", "); + g_variant_unref (element); + } + + /* for >1 item: remove final ", " + * for 1 item: remove final " ", but leave the "," + * for 0 items: there is only "(", so remove nothing + */ + g_string_truncate (string, string->len - (n > 0) - (n > 1)); + g_string_append_c (string, ')'); + } + break; + + case G_VARIANT_CLASS_DICT_ENTRY: + { + GVariant *element; + + g_string_append_c (string, '{'); + + element = g_variant_get_child_value (value, 0); + g_variant_print_string (element, string, type_annotate); + g_variant_unref (element); + + g_string_append (string, ", "); + + element = g_variant_get_child_value (value, 1); + g_variant_print_string (element, string, type_annotate); + g_variant_unref (element); + + g_string_append_c (string, '}'); + } + break; + + case G_VARIANT_CLASS_VARIANT: + { + GVariant *child = g_variant_get_variant (value); + + /* Always annotate types in nested variants, because they are + * (by nature) of variable type. + */ + g_string_append_c (string, '<'); + g_variant_print_string (child, string, TRUE); + g_string_append_c (string, '>'); + + g_variant_unref (child); + } + break; + + case G_VARIANT_CLASS_BOOLEAN: + if (g_variant_get_boolean (value)) + g_string_append (string, "true"); + else + g_string_append (string, "false"); + break; + + case G_VARIANT_CLASS_STRING: + { + const gchar *str = g_variant_get_string (value, NULL); + gunichar quote = strchr (str, '\'') ? '"' : '\''; + + g_string_append_c (string, quote); + + while (*str) + { + gunichar c = g_utf8_get_char (str); + + if (c == quote || c == '\\') + g_string_append_c (string, '\\'); + + if (g_unichar_isprint (c)) + g_string_append_unichar (string, c); + + else + { + g_string_append_c (string, '\\'); + if (c < 0x10000) + switch (c) + { + case '\a': + g_string_append_c (string, 'a'); + break; + + case '\b': + g_string_append_c (string, 'b'); + break; + + case '\f': + g_string_append_c (string, 'f'); + break; + + case '\n': + g_string_append_c (string, 'n'); + break; + + case '\r': + g_string_append_c (string, 'r'); + break; + + case '\t': + g_string_append_c (string, 't'); + break; + + case '\v': + g_string_append_c (string, 'v'); + break; + + default: + g_string_append_printf (string, "u%04x", c); + break; + } + else + g_string_append_printf (string, "U%08x", c); + } + + str = g_utf8_next_char (str); + } + + g_string_append_c (string, quote); + } + break; + + case G_VARIANT_CLASS_BYTE: + if (type_annotate) + g_string_append (string, "byte "); + g_string_append_printf (string, "0x%02x", + g_variant_get_byte (value)); + break; + + case G_VARIANT_CLASS_INT16: + if (type_annotate) + g_string_append (string, "int16 "); + g_string_append_printf (string, "%"G_GINT16_FORMAT, + g_variant_get_int16 (value)); + break; + + case G_VARIANT_CLASS_UINT16: + if (type_annotate) + g_string_append (string, "uint16 "); + g_string_append_printf (string, "%"G_GUINT16_FORMAT, + g_variant_get_uint16 (value)); + break; + + case G_VARIANT_CLASS_INT32: + /* Never annotate this type because it is the default for numbers + * (and this is a *pretty* printer) + */ + g_string_append_printf (string, "%"G_GINT32_FORMAT, + g_variant_get_int32 (value)); + break; + + case G_VARIANT_CLASS_HANDLE: + if (type_annotate) + g_string_append (string, "handle "); + g_string_append_printf (string, "%"G_GINT32_FORMAT, + g_variant_get_handle (value)); + break; + + case G_VARIANT_CLASS_UINT32: + if (type_annotate) + g_string_append (string, "uint32 "); + g_string_append_printf (string, "%"G_GUINT32_FORMAT, + g_variant_get_uint32 (value)); + break; + + case G_VARIANT_CLASS_INT64: + if (type_annotate) + g_string_append (string, "int64 "); + g_string_append_printf (string, "%"G_GINT64_FORMAT, + g_variant_get_int64 (value)); + break; + + case G_VARIANT_CLASS_UINT64: + if (type_annotate) + g_string_append (string, "uint64 "); + g_string_append_printf (string, "%"G_GUINT64_FORMAT, + g_variant_get_uint64 (value)); + break; + + case G_VARIANT_CLASS_DOUBLE: + { + gchar buffer[100]; + gint i; + + g_ascii_dtostr (buffer, sizeof buffer, g_variant_get_double (value)); + + for (i = 0; buffer[i]; i++) + if (buffer[i] == '.' || buffer[i] == 'e' || + buffer[i] == 'n' || buffer[i] == 'N') + break; + + /* if there is no '.' or 'e' in the float then add one */ + if (buffer[i] == '\0') + { + buffer[i++] = '.'; + buffer[i++] = '0'; + buffer[i++] = '\0'; + } + + g_string_append (string, buffer); + } + break; + + case G_VARIANT_CLASS_OBJECT_PATH: + if (type_annotate) + g_string_append (string, "objectpath "); + g_string_append_printf (string, "\'%s\'", + g_variant_get_string (value, NULL)); + break; + + case G_VARIANT_CLASS_SIGNATURE: + if (type_annotate) + g_string_append (string, "signature "); + g_string_append_printf (string, "\'%s\'", + g_variant_get_string (value, NULL)); + break; + + default: + g_assert_not_reached (); + } + + return string; +} + +/** + * g_variant_print: + * @value: a #GVariant + * @type_annotate: %TRUE if type information should be included in + * the output + * + * Pretty-prints @value in the format understood by g_variant_parse(). + * + * The format is described here. + * + * If @type_annotate is %TRUE, then type information is included in + * the output. + * + * Returns: (transfer full): a newly-allocated string holding the result. + * + * Since: 2.24 + */ +gchar * +g_variant_print (GVariant *value, + gboolean type_annotate) +{ + return g_string_free (g_variant_print_string (value, NULL, type_annotate), + FALSE); +}; + +/* Hash, Equal, Compare {{{1 */ +/** + * g_variant_hash: + * @value: (type GVariant): a basic #GVariant value as a #gconstpointer + * + * Generates a hash value for a #GVariant instance. + * + * The output of this function is guaranteed to be the same for a given + * value only per-process. It may change between different processor + * architectures or even different versions of GLib. Do not use this + * function as a basis for building protocols or file formats. + * + * The type of @value is #gconstpointer only to allow use of this + * function with #GHashTable. @value must be a #GVariant. + * + * Returns: a hash value corresponding to @value + * + * Since: 2.24 + **/ +guint +g_variant_hash (gconstpointer value_) +{ + GVariant *value = (GVariant *) value_; + + switch (g_variant_classify (value)) + { + case G_VARIANT_CLASS_STRING: + case G_VARIANT_CLASS_OBJECT_PATH: + case G_VARIANT_CLASS_SIGNATURE: + return g_str_hash (g_variant_get_string (value, NULL)); + + case G_VARIANT_CLASS_BOOLEAN: + /* this is a very odd thing to hash... */ + return g_variant_get_boolean (value); + + case G_VARIANT_CLASS_BYTE: + return g_variant_get_byte (value); + + case G_VARIANT_CLASS_INT16: + case G_VARIANT_CLASS_UINT16: + { + const guint16 *ptr; + + ptr = g_variant_get_data (value); + + if (ptr) + return *ptr; + else + return 0; + } + + case G_VARIANT_CLASS_INT32: + case G_VARIANT_CLASS_UINT32: + case G_VARIANT_CLASS_HANDLE: + { + const guint *ptr; + + ptr = g_variant_get_data (value); + + if (ptr) + return *ptr; + else + return 0; + } + + case G_VARIANT_CLASS_INT64: + case G_VARIANT_CLASS_UINT64: + case G_VARIANT_CLASS_DOUBLE: + /* need a separate case for these guys because otherwise + * performance could be quite bad on big endian systems + */ + { + const guint *ptr; + + ptr = g_variant_get_data (value); + + if (ptr) + return ptr[0] + ptr[1]; + else + return 0; + } + + default: + g_return_val_if_fail (!g_variant_is_container (value), 0); + g_assert_not_reached (); + } +} + +/** + * g_variant_equal: + * @one: (type GVariant): a #GVariant instance + * @two: (type GVariant): a #GVariant instance + * + * Checks if @one and @two have the same type and value. + * + * The types of @one and @two are #gconstpointer only to allow use of + * this function with #GHashTable. They must each be a #GVariant. + * + * Returns: %TRUE if @one and @two are equal + * + * Since: 2.24 + **/ +gboolean +g_variant_equal (gconstpointer one, + gconstpointer two) +{ + gboolean equal; + + g_return_val_if_fail (one != NULL && two != NULL, FALSE); + + if (g_variant_get_type_info ((GVariant *) one) != + g_variant_get_type_info ((GVariant *) two)) + return FALSE; + + /* if both values are trusted to be in their canonical serialised form + * then a simple memcmp() of their serialised data will answer the + * question. + * + * if not, then this might generate a false negative (since it is + * possible for two different byte sequences to represent the same + * value). for now we solve this by pretty-printing both values and + * comparing the result. + */ + if (g_variant_is_trusted ((GVariant *) one) && + g_variant_is_trusted ((GVariant *) two)) + { + gconstpointer data_one, data_two; + gsize size_one, size_two; + + size_one = g_variant_get_size ((GVariant *) one); + size_two = g_variant_get_size ((GVariant *) two); + + if (size_one != size_two) + return FALSE; + + data_one = g_variant_get_data ((GVariant *) one); + data_two = g_variant_get_data ((GVariant *) two); + + equal = memcmp (data_one, data_two, size_one) == 0; + } + else + { + gchar *strone, *strtwo; + + strone = g_variant_print ((GVariant *) one, FALSE); + strtwo = g_variant_print ((GVariant *) two, FALSE); + equal = strcmp (strone, strtwo) == 0; + g_free (strone); + g_free (strtwo); + } + + return equal; +} + +/** + * g_variant_compare: + * @one: (type GVariant): a basic-typed #GVariant instance + * @two: (type GVariant): a #GVariant instance of the same type + * + * Compares @one and @two. + * + * The types of @one and @two are #gconstpointer only to allow use of + * this function with #GTree, #GPtrArray, etc. They must each be a + * #GVariant. + * + * Comparison is only defined for basic types (ie: booleans, numbers, + * strings). For booleans, %FALSE is less than %TRUE. Numbers are + * ordered in the usual way. Strings are in ASCII lexographical order. + * + * It is a programmer error to attempt to compare container values or + * two values that have types that are not exactly equal. For example, + * you cannot compare a 32-bit signed integer with a 32-bit unsigned + * integer. Also note that this function is not particularly + * well-behaved when it comes to comparison of doubles; in particular, + * the handling of incomparable values (ie: NaN) is undefined. + * + * If you only require an equality comparison, g_variant_equal() is more + * general. + * + * Returns: negative value if a < b; + * zero if a = b; + * positive value if a > b. + * + * Since: 2.26 + **/ +gint +g_variant_compare (gconstpointer one, + gconstpointer two) +{ + GVariant *a = (GVariant *) one; + GVariant *b = (GVariant *) two; + + g_return_val_if_fail (g_variant_classify (a) == g_variant_classify (b), 0); + + switch (g_variant_classify (a)) + { + case G_VARIANT_CLASS_BYTE: + return ((gint) g_variant_get_byte (a)) - + ((gint) g_variant_get_byte (b)); + + case G_VARIANT_CLASS_INT16: + return ((gint) g_variant_get_int16 (a)) - + ((gint) g_variant_get_int16 (b)); + + case G_VARIANT_CLASS_UINT16: + return ((gint) g_variant_get_uint16 (a)) - + ((gint) g_variant_get_uint16 (b)); + + case G_VARIANT_CLASS_INT32: + { + gint32 a_val = g_variant_get_int32 (a); + gint32 b_val = g_variant_get_int32 (b); + + return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1; + } + + case G_VARIANT_CLASS_UINT32: + { + guint32 a_val = g_variant_get_uint32 (a); + guint32 b_val = g_variant_get_uint32 (b); + + return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1; + } + + case G_VARIANT_CLASS_INT64: + { + gint64 a_val = g_variant_get_int64 (a); + gint64 b_val = g_variant_get_int64 (b); + + return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1; + } + + case G_VARIANT_CLASS_UINT64: + { + guint64 a_val = g_variant_get_uint64 (a); + guint64 b_val = g_variant_get_uint64 (b); + + return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1; + } + + case G_VARIANT_CLASS_DOUBLE: + { + gdouble a_val = g_variant_get_double (a); + gdouble b_val = g_variant_get_double (b); + + return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1; + } + + case G_VARIANT_CLASS_STRING: + case G_VARIANT_CLASS_OBJECT_PATH: + case G_VARIANT_CLASS_SIGNATURE: + return strcmp (g_variant_get_string (a, NULL), + g_variant_get_string (b, NULL)); + + default: + g_return_val_if_fail (!g_variant_is_container (a), 0); + g_assert_not_reached (); + } +} + +/* GVariantIter {{{1 */ +/** + * GVariantIter: (skip) + * + * #GVariantIter is an opaque data structure and can only be accessed + * using the following functions. + **/ +struct stack_iter +{ + GVariant *value; + gssize n, i; + + const gchar *loop_format; + + gsize padding[3]; + gsize magic; +}; + +G_STATIC_ASSERT (sizeof (struct stack_iter) <= sizeof (GVariantIter)); + +struct heap_iter +{ + struct stack_iter iter; + + GVariant *value_ref; + gsize magic; +}; + +#define GVSI(i) ((struct stack_iter *) (i)) +#define GVHI(i) ((struct heap_iter *) (i)) +#define GVSI_MAGIC ((gsize) 3579507750u) +#define GVHI_MAGIC ((gsize) 1450270775u) +#define is_valid_iter(i) (i != NULL && \ + GVSI(i)->magic == GVSI_MAGIC) +#define is_valid_heap_iter(i) (GVHI(i)->magic == GVHI_MAGIC && \ + is_valid_iter(i)) + +/** + * g_variant_iter_new: + * @value: a container #GVariant + * + * Creates a heap-allocated #GVariantIter for iterating over the items + * in @value. + * + * Use g_variant_iter_free() to free the return value when you no longer + * need it. + * + * A reference is taken to @value and will be released only when + * g_variant_iter_free() is called. + * + * Returns: (transfer full): a new heap-allocated #GVariantIter + * + * Since: 2.24 + **/ +GVariantIter * +g_variant_iter_new (GVariant *value) +{ + GVariantIter *iter; + + iter = (GVariantIter *) g_slice_new (struct heap_iter); + GVHI(iter)->value_ref = g_variant_ref (value); + GVHI(iter)->magic = GVHI_MAGIC; + + g_variant_iter_init (iter, value); + + return iter; +} + +/** + * g_variant_iter_init: (skip) + * @iter: a pointer to a #GVariantIter + * @value: a container #GVariant + * + * Initialises (without allocating) a #GVariantIter. @iter may be + * completely uninitialised prior to this call; its old value is + * ignored. + * + * The iterator remains valid for as long as @value exists, and need not + * be freed in any way. + * + * Returns: the number of items in @value + * + * Since: 2.24 + **/ +gsize +g_variant_iter_init (GVariantIter *iter, + GVariant *value) +{ + GVSI(iter)->magic = GVSI_MAGIC; + GVSI(iter)->value = value; + GVSI(iter)->n = g_variant_n_children (value); + GVSI(iter)->i = -1; + GVSI(iter)->loop_format = NULL; + + return GVSI(iter)->n; +} + +/** + * g_variant_iter_copy: + * @iter: a #GVariantIter + * + * Creates a new heap-allocated #GVariantIter to iterate over the + * container that was being iterated over by @iter. Iteration begins on + * the new iterator from the current position of the old iterator but + * the two copies are independent past that point. + * + * Use g_variant_iter_free() to free the return value when you no longer + * need it. + * + * A reference is taken to the container that @iter is iterating over + * and will be releated only when g_variant_iter_free() is called. + * + * Returns: (transfer full): a new heap-allocated #GVariantIter + * + * Since: 2.24 + **/ +GVariantIter * +g_variant_iter_copy (GVariantIter *iter) +{ + GVariantIter *copy; + + g_return_val_if_fail (is_valid_iter (iter), 0); + + copy = g_variant_iter_new (GVSI(iter)->value); + GVSI(copy)->i = GVSI(iter)->i; + + return copy; +} + +/** + * g_variant_iter_n_children: + * @iter: a #GVariantIter + * + * Queries the number of child items in the container that we are + * iterating over. This is the total number of items -- not the number + * of items remaining. + * + * This function might be useful for preallocation of arrays. + * + * Returns: the number of children in the container + * + * Since: 2.24 + **/ +gsize +g_variant_iter_n_children (GVariantIter *iter) +{ + g_return_val_if_fail (is_valid_iter (iter), 0); + + return GVSI(iter)->n; +} + +/** + * g_variant_iter_free: + * @iter: (transfer full): a heap-allocated #GVariantIter + * + * Frees a heap-allocated #GVariantIter. Only call this function on + * iterators that were returned by g_variant_iter_new() or + * g_variant_iter_copy(). + * + * Since: 2.24 + **/ +void +g_variant_iter_free (GVariantIter *iter) +{ + g_return_if_fail (is_valid_heap_iter (iter)); + + g_variant_unref (GVHI(iter)->value_ref); + GVHI(iter)->magic = 0; + + g_slice_free (struct heap_iter, GVHI(iter)); +} + +/** + * g_variant_iter_next_value: + * @iter: a #GVariantIter + * + * Gets the next item in the container. If no more items remain then + * %NULL is returned. + * + * Use g_variant_unref() to drop your reference on the return value when + * you no longer need it. + * + * + * Iterating with g_variant_iter_next_value() + * + * /* recursively iterate a container */ + * void + * iterate_container_recursive (GVariant *container) + * { + * GVariantIter iter; + * GVariant *child; + * + * g_variant_iter_init (&iter, container); + * while ((child = g_variant_iter_next_value (&iter))) + * { + * g_print ("type '%s'\n", g_variant_get_type_string (child)); + * + * if (g_variant_is_container (child)) + * iterate_container_recursive (child); + * + * g_variant_unref (child); + * } + * } + * + * + * + * Returns: (allow-none) (transfer full): a #GVariant, or %NULL + * + * Since: 2.24 + **/ +GVariant * +g_variant_iter_next_value (GVariantIter *iter) +{ + g_return_val_if_fail (is_valid_iter (iter), FALSE); + + if G_UNLIKELY (GVSI(iter)->i >= GVSI(iter)->n) + { + g_critical ("g_variant_iter_next_value: must not be called again " + "after NULL has already been returned."); + return NULL; + } + + GVSI(iter)->i++; + + if (GVSI(iter)->i < GVSI(iter)->n) + return g_variant_get_child_value (GVSI(iter)->value, GVSI(iter)->i); + + return NULL; +} + +/* GVariantBuilder {{{1 */ +/** + * GVariantBuilder: + * + * A utility type for constructing container-type #GVariant instances. + * + * This is an opaque structure and may only be accessed using the + * following functions. + * + * #GVariantBuilder is not threadsafe in any way. Do not attempt to + * access it from more than one thread. + **/ + +struct stack_builder +{ + GVariantBuilder *parent; + GVariantType *type; + + /* type constraint explicitly specified by 'type'. + * for tuple types, this moves along as we add more items. + */ + const GVariantType *expected_type; + + /* type constraint implied by previous array item. + */ + const GVariantType *prev_item_type; + + /* constraints on the number of children. max = -1 for unlimited. */ + gsize min_items; + gsize max_items; + + /* dynamically-growing pointer array */ + GVariant **children; + gsize allocated_children; + gsize offset; + + /* set to '1' if all items in the container will have the same type + * (ie: maybe, array, variant) '0' if not (ie: tuple, dict entry) + */ + guint uniform_item_types : 1; + + /* set to '1' initially and changed to '0' if an untrusted value is + * added + */ + guint trusted : 1; + + gsize magic; +}; + +G_STATIC_ASSERT (sizeof (struct stack_builder) <= sizeof (GVariantBuilder)); + +struct heap_builder +{ + GVariantBuilder builder; + gsize magic; + + gint ref_count; +}; + +#define GVSB(b) ((struct stack_builder *) (b)) +#define GVHB(b) ((struct heap_builder *) (b)) +#define GVSB_MAGIC ((gsize) 1033660112u) +#define GVHB_MAGIC ((gsize) 3087242682u) +#define is_valid_builder(b) (b != NULL && \ + GVSB(b)->magic == GVSB_MAGIC) +#define is_valid_heap_builder(b) (GVHB(b)->magic == GVHB_MAGIC) + +/** + * g_variant_builder_new: + * @type: a container type + * + * Allocates and initialises a new #GVariantBuilder. + * + * You should call g_variant_builder_unref() on the return value when it + * is no longer needed. The memory will not be automatically freed by + * any other call. + * + * In most cases it is easier to place a #GVariantBuilder directly on + * the stack of the calling function and initialise it with + * g_variant_builder_init(). + * + * Returns: (transfer full): a #GVariantBuilder + * + * Since: 2.24 + **/ +GVariantBuilder * +g_variant_builder_new (const GVariantType *type) +{ + GVariantBuilder *builder; + + builder = (GVariantBuilder *) g_slice_new (struct heap_builder); + g_variant_builder_init (builder, type); + GVHB(builder)->magic = GVHB_MAGIC; + GVHB(builder)->ref_count = 1; + + return builder; +} + +/** + * g_variant_builder_unref: + * @builder: (transfer full): a #GVariantBuilder allocated by g_variant_builder_new() + * + * Decreases the reference count on @builder. + * + * In the event that there are no more references, releases all memory + * associated with the #GVariantBuilder. + * + * Don't call this on stack-allocated #GVariantBuilder instances or bad + * things will happen. + * + * Since: 2.24 + **/ +void +g_variant_builder_unref (GVariantBuilder *builder) +{ + g_return_if_fail (is_valid_heap_builder (builder)); + + if (--GVHB(builder)->ref_count) + return; + + g_variant_builder_clear (builder); + GVHB(builder)->magic = 0; + + g_slice_free (struct heap_builder, GVHB(builder)); +} + +/** + * g_variant_builder_ref: + * @builder: a #GVariantBuilder allocated by g_variant_builder_new() + * + * Increases the reference count on @builder. + * + * Don't call this on stack-allocated #GVariantBuilder instances or bad + * things will happen. + * + * Returns: (transfer full): a new reference to @builder + * + * Since: 2.24 + **/ +GVariantBuilder * +g_variant_builder_ref (GVariantBuilder *builder) +{ + g_return_val_if_fail (is_valid_heap_builder (builder), NULL); + + GVHB(builder)->ref_count++; + + return builder; +} + +/** + * g_variant_builder_clear: (skip) + * @builder: a #GVariantBuilder + * + * Releases all memory associated with a #GVariantBuilder without + * freeing the #GVariantBuilder structure itself. + * + * It typically only makes sense to do this on a stack-allocated + * #GVariantBuilder if you want to abort building the value part-way + * through. This function need not be called if you call + * g_variant_builder_end() and it also doesn't need to be called on + * builders allocated with g_variant_builder_new (see + * g_variant_builder_unref() for that). + * + * This function leaves the #GVariantBuilder structure set to all-zeros. + * It is valid to call this function on either an initialised + * #GVariantBuilder or one that is set to all-zeros but it is not valid + * to call this function on uninitialised memory. + * + * Since: 2.24 + **/ +void +g_variant_builder_clear (GVariantBuilder *builder) +{ + gsize i; + + if (GVSB(builder)->magic == 0) + /* all-zeros case */ + return; + + g_return_if_fail (is_valid_builder (builder)); + + g_variant_type_free (GVSB(builder)->type); + + for (i = 0; i < GVSB(builder)->offset; i++) + g_variant_unref (GVSB(builder)->children[i]); + + g_free (GVSB(builder)->children); + + if (GVSB(builder)->parent) + { + g_variant_builder_clear (GVSB(builder)->parent); + g_slice_free (GVariantBuilder, GVSB(builder)->parent); + } + + memset (builder, 0, sizeof (GVariantBuilder)); +} + +/** + * g_variant_builder_init: (skip) + * @builder: a #GVariantBuilder + * @type: a container type + * + * Initialises a #GVariantBuilder structure. + * + * @type must be non-%NULL. It specifies the type of container to + * construct. It can be an indefinite type such as + * %G_VARIANT_TYPE_ARRAY or a definite type such as "as" or "(ii)". + * Maybe, array, tuple, dictionary entry and variant-typed values may be + * constructed. + * + * After the builder is initialised, values are added using + * g_variant_builder_add_value() or g_variant_builder_add(). + * + * After all the child values are added, g_variant_builder_end() frees + * the memory associated with the builder and returns the #GVariant that + * was created. + * + * This function completely ignores the previous contents of @builder. + * On one hand this means that it is valid to pass in completely + * uninitialised memory. On the other hand, this means that if you are + * initialising over top of an existing #GVariantBuilder you need to + * first call g_variant_builder_clear() in order to avoid leaking + * memory. + * + * You must not call g_variant_builder_ref() or + * g_variant_builder_unref() on a #GVariantBuilder that was initialised + * with this function. If you ever pass a reference to a + * #GVariantBuilder outside of the control of your own code then you + * should assume that the person receiving that reference may try to use + * reference counting; you should use g_variant_builder_new() instead of + * this function. + * + * Since: 2.24 + **/ +void +g_variant_builder_init (GVariantBuilder *builder, + const GVariantType *type) +{ + g_return_if_fail (type != NULL); + g_return_if_fail (g_variant_type_is_container (type)); + + memset (builder, 0, sizeof (GVariantBuilder)); + + GVSB(builder)->type = g_variant_type_copy (type); + GVSB(builder)->magic = GVSB_MAGIC; + GVSB(builder)->trusted = TRUE; + + switch (*(const gchar *) type) + { + case G_VARIANT_CLASS_VARIANT: + GVSB(builder)->uniform_item_types = TRUE; + GVSB(builder)->allocated_children = 1; + GVSB(builder)->expected_type = NULL; + GVSB(builder)->min_items = 1; + GVSB(builder)->max_items = 1; + break; + + case G_VARIANT_CLASS_ARRAY: + GVSB(builder)->uniform_item_types = TRUE; + GVSB(builder)->allocated_children = 8; + GVSB(builder)->expected_type = + g_variant_type_element (GVSB(builder)->type); + GVSB(builder)->min_items = 0; + GVSB(builder)->max_items = -1; + break; + + case G_VARIANT_CLASS_MAYBE: + GVSB(builder)->uniform_item_types = TRUE; + GVSB(builder)->allocated_children = 1; + GVSB(builder)->expected_type = + g_variant_type_element (GVSB(builder)->type); + GVSB(builder)->min_items = 0; + GVSB(builder)->max_items = 1; + break; + + case G_VARIANT_CLASS_DICT_ENTRY: + GVSB(builder)->uniform_item_types = FALSE; + GVSB(builder)->allocated_children = 2; + GVSB(builder)->expected_type = + g_variant_type_key (GVSB(builder)->type); + GVSB(builder)->min_items = 2; + GVSB(builder)->max_items = 2; + break; + + case 'r': /* G_VARIANT_TYPE_TUPLE was given */ + GVSB(builder)->uniform_item_types = FALSE; + GVSB(builder)->allocated_children = 8; + GVSB(builder)->expected_type = NULL; + GVSB(builder)->min_items = 0; + GVSB(builder)->max_items = -1; + break; + + case G_VARIANT_CLASS_TUPLE: /* a definite tuple type was given */ + GVSB(builder)->allocated_children = g_variant_type_n_items (type); + GVSB(builder)->expected_type = + g_variant_type_first (GVSB(builder)->type); + GVSB(builder)->min_items = GVSB(builder)->allocated_children; + GVSB(builder)->max_items = GVSB(builder)->allocated_children; + GVSB(builder)->uniform_item_types = FALSE; + break; + + default: + g_assert_not_reached (); + } + + GVSB(builder)->children = g_new (GVariant *, + GVSB(builder)->allocated_children); +} + +static void +g_variant_builder_make_room (struct stack_builder *builder) +{ + if (builder->offset == builder->allocated_children) + { + builder->allocated_children *= 2; + builder->children = g_renew (GVariant *, builder->children, + builder->allocated_children); + } +} + +/** + * g_variant_builder_add_value: + * @builder: a #GVariantBuilder + * @value: a #GVariant + * + * Adds @value to @builder. + * + * It is an error to call this function in any way that would create an + * inconsistent value to be constructed. Some examples of this are + * putting different types of items into an array, putting the wrong + * types or number of items in a tuple, putting more than one value into + * a variant, etc. + * + * If @value is a floating reference (see g_variant_ref_sink()), + * the @builder instance takes ownership of @value. + * + * Since: 2.24 + **/ +void +g_variant_builder_add_value (GVariantBuilder *builder, + GVariant *value) +{ + g_return_if_fail (is_valid_builder (builder)); + g_return_if_fail (GVSB(builder)->offset < GVSB(builder)->max_items); + g_return_if_fail (!GVSB(builder)->expected_type || + g_variant_is_of_type (value, + GVSB(builder)->expected_type)); + g_return_if_fail (!GVSB(builder)->prev_item_type || + g_variant_is_of_type (value, + GVSB(builder)->prev_item_type)); + + GVSB(builder)->trusted &= g_variant_is_trusted (value); + + if (!GVSB(builder)->uniform_item_types) + { + /* advance our expected type pointers */ + if (GVSB(builder)->expected_type) + GVSB(builder)->expected_type = + g_variant_type_next (GVSB(builder)->expected_type); + + if (GVSB(builder)->prev_item_type) + GVSB(builder)->prev_item_type = + g_variant_type_next (GVSB(builder)->prev_item_type); + } + else + GVSB(builder)->prev_item_type = g_variant_get_type (value); + + g_variant_builder_make_room (GVSB(builder)); + + GVSB(builder)->children[GVSB(builder)->offset++] = + g_variant_ref_sink (value); +} + +/** + * g_variant_builder_open: + * @builder: a #GVariantBuilder + * @type: a #GVariantType + * + * Opens a subcontainer inside the given @builder. When done adding + * items to the subcontainer, g_variant_builder_close() must be called. + * + * It is an error to call this function in any way that would cause an + * inconsistent value to be constructed (ie: adding too many values or + * a value of an incorrect type). + * + * Since: 2.24 + **/ +void +g_variant_builder_open (GVariantBuilder *builder, + const GVariantType *type) +{ + GVariantBuilder *parent; + + g_return_if_fail (is_valid_builder (builder)); + g_return_if_fail (GVSB(builder)->offset < GVSB(builder)->max_items); + g_return_if_fail (!GVSB(builder)->expected_type || + g_variant_type_is_subtype_of (type, + GVSB(builder)->expected_type)); + g_return_if_fail (!GVSB(builder)->prev_item_type || + g_variant_type_is_subtype_of (GVSB(builder)->prev_item_type, + type)); + + parent = g_slice_dup (GVariantBuilder, builder); + g_variant_builder_init (builder, type); + GVSB(builder)->parent = parent; + + /* push the prev_item_type down into the subcontainer */ + if (GVSB(parent)->prev_item_type) + { + if (!GVSB(builder)->uniform_item_types) + /* tuples and dict entries */ + GVSB(builder)->prev_item_type = + g_variant_type_first (GVSB(parent)->prev_item_type); + + else if (!g_variant_type_is_variant (GVSB(builder)->type)) + /* maybes and arrays */ + GVSB(builder)->prev_item_type = + g_variant_type_element (GVSB(parent)->prev_item_type); + } +} + +/** + * g_variant_builder_close: + * @builder: a #GVariantBuilder + * + * Closes the subcontainer inside the given @builder that was opened by + * the most recent call to g_variant_builder_open(). + * + * It is an error to call this function in any way that would create an + * inconsistent value to be constructed (ie: too few values added to the + * subcontainer). + * + * Since: 2.24 + **/ +void +g_variant_builder_close (GVariantBuilder *builder) +{ + GVariantBuilder *parent; + + g_return_if_fail (is_valid_builder (builder)); + g_return_if_fail (GVSB(builder)->parent != NULL); + + parent = GVSB(builder)->parent; + GVSB(builder)->parent = NULL; + + g_variant_builder_add_value (parent, g_variant_builder_end (builder)); + *builder = *parent; + + g_slice_free (GVariantBuilder, parent); +} + +/*< private > + * g_variant_make_maybe_type: + * @element: a #GVariant + * + * Return the type of a maybe containing @element. + */ +static GVariantType * +g_variant_make_maybe_type (GVariant *element) +{ + return g_variant_type_new_maybe (g_variant_get_type (element)); +} + +/*< private > + * g_variant_make_array_type: + * @element: a #GVariant + * + * Return the type of an array containing @element. + */ +static GVariantType * +g_variant_make_array_type (GVariant *element) +{ + return g_variant_type_new_array (g_variant_get_type (element)); +} + +/** + * g_variant_builder_end: + * @builder: a #GVariantBuilder + * + * Ends the builder process and returns the constructed value. + * + * It is not permissible to use @builder in any way after this call + * except for reference counting operations (in the case of a + * heap-allocated #GVariantBuilder) or by reinitialising it with + * g_variant_builder_init() (in the case of stack-allocated). + * + * It is an error to call this function in any way that would create an + * inconsistent value to be constructed (ie: insufficient number of + * items added to a container with a specific number of children + * required). It is also an error to call this function if the builder + * was created with an indefinite array or maybe type and no children + * have been added; in this case it is impossible to infer the type of + * the empty array. + * + * Returns: (transfer none): a new, floating, #GVariant + * + * Since: 2.24 + **/ +GVariant * +g_variant_builder_end (GVariantBuilder *builder) +{ + GVariantType *my_type; + GVariant *value; + + g_return_val_if_fail (is_valid_builder (builder), NULL); + g_return_val_if_fail (GVSB(builder)->offset >= GVSB(builder)->min_items, + NULL); + g_return_val_if_fail (!GVSB(builder)->uniform_item_types || + GVSB(builder)->prev_item_type != NULL || + g_variant_type_is_definite (GVSB(builder)->type), + NULL); + + if (g_variant_type_is_definite (GVSB(builder)->type)) + my_type = g_variant_type_copy (GVSB(builder)->type); + + else if (g_variant_type_is_maybe (GVSB(builder)->type)) + my_type = g_variant_make_maybe_type (GVSB(builder)->children[0]); + + else if (g_variant_type_is_array (GVSB(builder)->type)) + my_type = g_variant_make_array_type (GVSB(builder)->children[0]); + + else if (g_variant_type_is_tuple (GVSB(builder)->type)) + my_type = g_variant_make_tuple_type (GVSB(builder)->children, + GVSB(builder)->offset); + + else if (g_variant_type_is_dict_entry (GVSB(builder)->type)) + my_type = g_variant_make_dict_entry_type (GVSB(builder)->children[0], + GVSB(builder)->children[1]); + else + g_assert_not_reached (); + + value = g_variant_new_from_children (my_type, + g_renew (GVariant *, + GVSB(builder)->children, + GVSB(builder)->offset), + GVSB(builder)->offset, + GVSB(builder)->trusted); + GVSB(builder)->children = NULL; + GVSB(builder)->offset = 0; + + g_variant_builder_clear (builder); + g_variant_type_free (my_type); + + return value; +} + +/* Format strings {{{1 */ +/*< private > + * g_variant_format_string_scan: + * @string: a string that may be prefixed with a format string + * @limit: (allow-none) (default NULL): a pointer to the end of @string, + * or %NULL + * @endptr: (allow-none) (default NULL): location to store the end pointer, + * or %NULL + * + * Checks the string pointed to by @string for starting with a properly + * formed #GVariant varargs format string. If no valid format string is + * found then %FALSE is returned. + * + * If @string does start with a valid format string then %TRUE is + * returned. If @endptr is non-%NULL then it is updated to point to the + * first character after the format string. + * + * If @limit is non-%NULL then @limit (and any charater after it) will + * not be accessed and the effect is otherwise equivalent to if the + * character at @limit were nul. + * + * See the section on GVariant + * Format Strings. + * + * Returns: %TRUE if there was a valid format string + * + * Since: 2.24 + */ +gboolean +g_variant_format_string_scan (const gchar *string, + const gchar *limit, + const gchar **endptr) +{ +#define next_char() (string == limit ? '\0' : *string++) +#define peek_char() (string == limit ? '\0' : *string) + char c; + + switch (next_char()) + { + case 'b': case 'y': case 'n': case 'q': case 'i': case 'u': + case 'x': case 't': case 'h': case 'd': case 's': case 'o': + case 'g': case 'v': case '*': case '?': case 'r': + break; + + case 'm': + return g_variant_format_string_scan (string, limit, endptr); + + case 'a': + case '@': + return g_variant_type_string_scan (string, limit, endptr); + + case '(': + while (peek_char() != ')') + if (!g_variant_format_string_scan (string, limit, &string)) + return FALSE; + + next_char(); /* consume ')' */ + break; + + case '{': + c = next_char(); + + if (c == '&') + { + c = next_char (); + + if (c != 's' && c != 'o' && c != 'g') + return FALSE; + } + else + { + if (c == '@') + c = next_char (); + + /* ISO/IEC 9899:1999 (C99) §7.21.5.2: + * The terminating null character is considered to be + * part of the string. + */ + if (c != '\0' && strchr ("bynqiuxthdsog?", c) == NULL) + return FALSE; + } + + if (!g_variant_format_string_scan (string, limit, &string)) + return FALSE; + + if (next_char() != '}') + return FALSE; + + break; + + case '^': + if ((c = next_char()) == 'a') + { + if ((c = next_char()) == '&') + { + if ((c = next_char()) == 'a') + { + if ((c = next_char()) == 'y') + break; /* '^a&ay' */ + } + + else if (c == 's' || c == 'o') + break; /* '^a&s', '^a&o' */ + } + + else if (c == 'a') + { + if ((c = next_char()) == 'y') + break; /* '^aay' */ + } + + else if (c == 's' || c == 'o') + break; /* '^as', '^ao' */ + + else if (c == 'y') + break; /* '^ay' */ + } + else if (c == '&') + { + if ((c = next_char()) == 'a') + { + if ((c = next_char()) == 'y') + break; /* '^&ay' */ + } + } + + return FALSE; + + case '&': + c = next_char(); + + if (c != 's' && c != 'o' && c != 'g') + return FALSE; + + break; + + default: + return FALSE; + } + + if (endptr != NULL) + *endptr = string; + +#undef next_char +#undef peek_char + + return TRUE; +} + +/*< private > + * g_variant_format_string_scan_type: + * @string: a string that may be prefixed with a format string + * @limit: (allow-none) (default NULL): a pointer to the end of @string, + * or %NULL + * @endptr: (allow-none) (default NULL): location to store the end pointer, + * or %NULL + * + * If @string starts with a valid format string then this function will + * return the type that the format string corresponds to. Otherwise + * this function returns %NULL. + * + * Use g_variant_type_free() to free the return value when you no longer + * need it. + * + * This function is otherwise exactly like + * g_variant_format_string_scan(). + * + * Returns: (allow-none): a #GVariantType if there was a valid format string + * + * Since: 2.24 + */ +GVariantType * +g_variant_format_string_scan_type (const gchar *string, + const gchar *limit, + const gchar **endptr) +{ + const gchar *my_end; + gchar *dest; + gchar *new; + + if (endptr == NULL) + endptr = &my_end; + + if (!g_variant_format_string_scan (string, limit, endptr)) + return NULL; + + dest = new = g_malloc (*endptr - string + 1); + while (string != *endptr) + { + if (*string != '@' && *string != '&' && *string != '^') + *dest++ = *string; + string++; + } + *dest = '\0'; + + return (GVariantType *) G_VARIANT_TYPE (new); +} + +static gboolean +valid_format_string (const gchar *format_string, + gboolean single, + GVariant *value) +{ + const gchar *endptr; + GVariantType *type; + + type = g_variant_format_string_scan_type (format_string, NULL, &endptr); + + if G_UNLIKELY (type == NULL || (single && *endptr != '\0')) + { + if (single) + g_critical ("`%s' is not a valid GVariant format string", + format_string); + else + g_critical ("`%s' does not have a valid GVariant format " + "string as a prefix", format_string); + + if (type != NULL) + g_variant_type_free (type); + + return FALSE; + } + + if G_UNLIKELY (value && !g_variant_is_of_type (value, type)) + { + gchar *fragment; + gchar *typestr; + + fragment = g_strndup (format_string, endptr - format_string); + typestr = g_variant_type_dup_string (type); + + g_critical ("the GVariant format string `%s' has a type of " + "`%s' but the given value has a type of `%s'", + fragment, typestr, g_variant_get_type_string (value)); + + g_variant_type_free (type); + + return FALSE; + } + + g_variant_type_free (type); + + return TRUE; +} + +/* Variable Arguments {{{1 */ +/* We consider 2 main classes of format strings: + * + * - recursive format strings + * these are ones that result in recursion and the collection of + * possibly more than one argument. Maybe types, tuples, + * dictionary entries. + * + * - leaf format string + * these result in the collection of a single argument. + * + * Leaf format strings are further subdivided into two categories: + * + * - single non-null pointer ("nnp") + * these either collect or return a single non-null pointer. + * + * - other + * these collect or return something else (bool, number, etc). + * + * Based on the above, the varargs handling code is split into 4 main parts: + * + * - nnp handling code + * - leaf handling code (which may invoke nnp code) + * - generic handling code (may be recursive, may invoke leaf code) + * - user-facing API (which invokes the generic code) + * + * Each section implements some of the following functions: + * + * - skip: + * collect the arguments for the format string as if + * g_variant_new() had been called, but do nothing with them. used + * for skipping over arguments when constructing a Nothing maybe + * type. + * + * - new: + * create a GVariant * + * + * - get: + * unpack a GVariant * + * + * - free (nnp only): + * free a previously allocated item + */ + +static gboolean +g_variant_format_string_is_leaf (const gchar *str) +{ + return str[0] != 'm' && str[0] != '(' && str[0] != '{'; +} + +static gboolean +g_variant_format_string_is_nnp (const gchar *str) +{ + return str[0] == 'a' || str[0] == 's' || str[0] == 'o' || str[0] == 'g' || + str[0] == '^' || str[0] == '@' || str[0] == '*' || str[0] == '?' || + str[0] == 'r' || str[0] == 'v' || str[0] == '&'; +} + +/* Single non-null pointer ("nnp") {{{2 */ +static void +g_variant_valist_free_nnp (const gchar *str, + gpointer ptr) +{ + switch (*str) + { + case 'a': + g_variant_iter_free (ptr); + break; + + case '^': + if (str[2] != '&') /* '^as', '^ao' */ + g_strfreev (ptr); + else /* '^a&s', '^a&o' */ + g_free (ptr); + break; + + case 's': + case 'o': + case 'g': + g_free (ptr); + break; + + case '@': + case '*': + case '?': + case 'v': + g_variant_unref (ptr); + break; + + case '&': + break; + + default: + g_assert_not_reached (); + } +} + +static gchar +g_variant_scan_convenience (const gchar **str, + gboolean *constant, + guint *arrays) +{ + *constant = FALSE; + *arrays = 0; + + for (;;) + { + char c = *(*str)++; + + if (c == '&') + *constant = TRUE; + + else if (c == 'a') + (*arrays)++; + + else + return c; + } +} + +static GVariant * +g_variant_valist_new_nnp (const gchar **str, + gpointer ptr) +{ + if (**str == '&') + (*str)++; + + switch (*(*str)++) + { + case 'a': + if (ptr != NULL) + { + const GVariantType *type; + GVariant *value; + + value = g_variant_builder_end (ptr); + type = g_variant_get_type (value); + + if G_UNLIKELY (!g_variant_type_is_array (type)) + g_error ("g_variant_new: expected array GVariantBuilder but " + "the built value has type `%s'", + g_variant_get_type_string (value)); + + type = g_variant_type_element (type); + + if G_UNLIKELY (!g_variant_type_is_subtype_of (type, (GVariantType *) *str)) + g_error ("g_variant_new: expected GVariantBuilder array element " + "type `%s' but the built value has element type `%s'", + g_variant_type_dup_string ((GVariantType *) *str), + g_variant_get_type_string (value) + 1); + + g_variant_type_string_scan (*str, NULL, str); + + return value; + } + else + + /* special case: NULL pointer for empty array */ + { + const GVariantType *type = (GVariantType *) *str; + + g_variant_type_string_scan (*str, NULL, str); + + if G_UNLIKELY (!g_variant_type_is_definite (type)) + g_error ("g_variant_new: NULL pointer given with indefinite " + "array type; unable to determine which type of empty " + "array to construct."); + + return g_variant_new_array (type, NULL, 0); + } + + case 's': + { + GVariant *value; + + value = g_variant_new_string (ptr); + + if (value == NULL) + value = g_variant_new_string ("[Invalid UTF-8]"); + + return value; + } + + case 'o': + return g_variant_new_object_path (ptr); + + case 'g': + return g_variant_new_signature (ptr); + + case '^': + { + gboolean constant; + guint arrays; + gchar type; + + type = g_variant_scan_convenience (str, &constant, &arrays); + + if (type == 's') + return g_variant_new_strv (ptr, -1); + + if (type == 'o') + return g_variant_new_objv (ptr, -1); + + if (arrays > 1) + return g_variant_new_bytestring_array (ptr, -1); + + return g_variant_new_bytestring (ptr); + } + + case '@': + if G_UNLIKELY (!g_variant_is_of_type (ptr, (GVariantType *) *str)) + g_error ("g_variant_new: expected GVariant of type `%s' but " + "received value has type `%s'", + g_variant_type_dup_string ((GVariantType *) *str), + g_variant_get_type_string (ptr)); + + g_variant_type_string_scan (*str, NULL, str); + + return ptr; + + case '*': + return ptr; + + case '?': + if G_UNLIKELY (!g_variant_type_is_basic (g_variant_get_type (ptr))) + g_error ("g_variant_new: format string `?' expects basic-typed " + "GVariant, but received value has type `%s'", + g_variant_get_type_string (ptr)); + + return ptr; + + case 'r': + if G_UNLIKELY (!g_variant_type_is_tuple (g_variant_get_type (ptr))) + g_error ("g_variant_new: format string `r` expects tuple-typed " + "GVariant, but received value has type `%s'", + g_variant_get_type_string (ptr)); + + return ptr; + + case 'v': + return g_variant_new_variant (ptr); + + default: + g_assert_not_reached (); + } +} + +static gpointer +g_variant_valist_get_nnp (const gchar **str, + GVariant *value) +{ + switch (*(*str)++) + { + case 'a': + g_variant_type_string_scan (*str, NULL, str); + return g_variant_iter_new (value); + + case '&': + (*str)++; + return (gchar *) g_variant_get_string (value, NULL); + + case 's': + case 'o': + case 'g': + return g_variant_dup_string (value, NULL); + + case '^': + { + gboolean constant; + guint arrays; + gchar type; + + type = g_variant_scan_convenience (str, &constant, &arrays); + + if (type == 's') + { + if (constant) + return g_variant_get_strv (value, NULL); + else + return g_variant_dup_strv (value, NULL); + } + + else if (type == 'o') + { + if (constant) + return g_variant_get_objv (value, NULL); + else + return g_variant_dup_objv (value, NULL); + } + + else if (arrays > 1) + { + if (constant) + return g_variant_get_bytestring_array (value, NULL); + else + return g_variant_dup_bytestring_array (value, NULL); + } + + else + { + if (constant) + return (gchar *) g_variant_get_bytestring (value); + else + return g_variant_dup_bytestring (value, NULL); + } + } + + case '@': + g_variant_type_string_scan (*str, NULL, str); + /* fall through */ + + case '*': + case '?': + case 'r': + return g_variant_ref (value); + + case 'v': + return g_variant_get_variant (value); + + default: + g_assert_not_reached (); + } +} + +/* Leaves {{{2 */ +static void +g_variant_valist_skip_leaf (const gchar **str, + va_list *app) +{ + if (g_variant_format_string_is_nnp (*str)) + { + g_variant_format_string_scan (*str, NULL, str); + va_arg (*app, gpointer); + return; + } + + switch (*(*str)++) + { + case 'b': + case 'y': + case 'n': + case 'q': + case 'i': + case 'u': + case 'h': + va_arg (*app, int); + return; + + case 'x': + case 't': + va_arg (*app, guint64); + return; + + case 'd': + va_arg (*app, gdouble); + return; + + default: + g_assert_not_reached (); + } +} + +static GVariant * +g_variant_valist_new_leaf (const gchar **str, + va_list *app) +{ + if (g_variant_format_string_is_nnp (*str)) + return g_variant_valist_new_nnp (str, va_arg (*app, gpointer)); + + switch (*(*str)++) + { + case 'b': + return g_variant_new_boolean (va_arg (*app, gboolean)); + + case 'y': + return g_variant_new_byte (va_arg (*app, guint)); + + case 'n': + return g_variant_new_int16 (va_arg (*app, gint)); + + case 'q': + return g_variant_new_uint16 (va_arg (*app, guint)); + + case 'i': + return g_variant_new_int32 (va_arg (*app, gint)); + + case 'u': + return g_variant_new_uint32 (va_arg (*app, guint)); + + case 'x': + return g_variant_new_int64 (va_arg (*app, gint64)); + + case 't': + return g_variant_new_uint64 (va_arg (*app, guint64)); + + case 'h': + return g_variant_new_handle (va_arg (*app, gint)); + + case 'd': + return g_variant_new_double (va_arg (*app, gdouble)); + + default: + g_assert_not_reached (); + } +} + +/* The code below assumes this */ +G_STATIC_ASSERT (sizeof (gboolean) == sizeof (guint32)); +G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64)); + +static void +g_variant_valist_get_leaf (const gchar **str, + GVariant *value, + gboolean free, + va_list *app) +{ + gpointer ptr = va_arg (*app, gpointer); + + if (ptr == NULL) + { + g_variant_format_string_scan (*str, NULL, str); + return; + } + + if (g_variant_format_string_is_nnp (*str)) + { + gpointer *nnp = (gpointer *) ptr; + + if (free && *nnp != NULL) + g_variant_valist_free_nnp (*str, *nnp); + + *nnp = NULL; + + if (value != NULL) + *nnp = g_variant_valist_get_nnp (str, value); + else + g_variant_format_string_scan (*str, NULL, str); + + return; + } + + if (value != NULL) + { + switch (*(*str)++) + { + case 'b': + *(gboolean *) ptr = g_variant_get_boolean (value); + return; + + case 'y': + *(guchar *) ptr = g_variant_get_byte (value); + return; + + case 'n': + *(gint16 *) ptr = g_variant_get_int16 (value); + return; + + case 'q': + *(guint16 *) ptr = g_variant_get_uint16 (value); + return; + + case 'i': + *(gint32 *) ptr = g_variant_get_int32 (value); + return; + + case 'u': + *(guint32 *) ptr = g_variant_get_uint32 (value); + return; + + case 'x': + *(gint64 *) ptr = g_variant_get_int64 (value); + return; + + case 't': + *(guint64 *) ptr = g_variant_get_uint64 (value); + return; + + case 'h': + *(gint32 *) ptr = g_variant_get_handle (value); + return; + + case 'd': + *(gdouble *) ptr = g_variant_get_double (value); + return; + } + } + else + { + switch (*(*str)++) + { + case 'y': + *(guchar *) ptr = 0; + return; + + case 'n': + case 'q': + *(guint16 *) ptr = 0; + return; + + case 'i': + case 'u': + case 'h': + case 'b': + *(guint32 *) ptr = 0; + return; + + case 'x': + case 't': + case 'd': + *(guint64 *) ptr = 0; + return; + } + } + + g_assert_not_reached (); +} + +/* Generic (recursive) {{{2 */ +static void +g_variant_valist_skip (const gchar **str, + va_list *app) +{ + if (g_variant_format_string_is_leaf (*str)) + g_variant_valist_skip_leaf (str, app); + + else if (**str == 'm') /* maybe */ + { + (*str)++; + + if (!g_variant_format_string_is_nnp (*str)) + va_arg (*app, gboolean); + + g_variant_valist_skip (str, app); + } + else /* tuple, dictionary entry */ + { + g_assert (**str == '(' || **str == '{'); + (*str)++; + while (**str != ')' && **str != '}') + g_variant_valist_skip (str, app); + (*str)++; + } +} + +static GVariant * +g_variant_valist_new (const gchar **str, + va_list *app) +{ + if (g_variant_format_string_is_leaf (*str)) + return g_variant_valist_new_leaf (str, app); + + if (**str == 'm') /* maybe */ + { + GVariantType *type = NULL; + GVariant *value = NULL; + + (*str)++; + + if (g_variant_format_string_is_nnp (*str)) + { + gpointer nnp = va_arg (*app, gpointer); + + if (nnp != NULL) + value = g_variant_valist_new_nnp (str, nnp); + else + type = g_variant_format_string_scan_type (*str, NULL, str); + } + else + { + gboolean just = va_arg (*app, gboolean); + + if (just) + value = g_variant_valist_new (str, app); + else + { + type = g_variant_format_string_scan_type (*str, NULL, NULL); + g_variant_valist_skip (str, app); + } + } + + value = g_variant_new_maybe (type, value); + + if (type != NULL) + g_variant_type_free (type); + + return value; + } + else /* tuple, dictionary entry */ + { + GVariantBuilder b; + + if (**str == '(') + g_variant_builder_init (&b, G_VARIANT_TYPE_TUPLE); + else + { + g_assert (**str == '{'); + g_variant_builder_init (&b, G_VARIANT_TYPE_DICT_ENTRY); + } + + (*str)++; /* '(' */ + while (**str != ')' && **str != '}') + g_variant_builder_add_value (&b, g_variant_valist_new (str, app)); + (*str)++; /* ')' */ + + return g_variant_builder_end (&b); + } +} + +static void +g_variant_valist_get (const gchar **str, + GVariant *value, + gboolean free, + va_list *app) +{ + if (g_variant_format_string_is_leaf (*str)) + g_variant_valist_get_leaf (str, value, free, app); + + else if (**str == 'm') + { + (*str)++; + + if (value != NULL) + value = g_variant_get_maybe (value); + + if (!g_variant_format_string_is_nnp (*str)) + { + gboolean *ptr = va_arg (*app, gboolean *); + + if (ptr != NULL) + *ptr = value != NULL; + } + + g_variant_valist_get (str, value, free, app); + + if (value != NULL) + g_variant_unref (value); + } + + else /* tuple, dictionary entry */ + { + gint index = 0; + + g_assert (**str == '(' || **str == '{'); + + (*str)++; + while (**str != ')' && **str != '}') + { + if (value != NULL) + { + GVariant *child = g_variant_get_child_value (value, index++); + g_variant_valist_get (str, child, free, app); + g_variant_unref (child); + } + else + g_variant_valist_get (str, NULL, free, app); + } + (*str)++; + } +} + +/* User-facing API {{{2 */ +/** + * g_variant_new: (skip) + * @format_string: a #GVariant format string + * @...: arguments, as per @format_string + * + * Creates a new #GVariant instance. + * + * Think of this function as an analogue to g_strdup_printf(). + * + * The type of the created instance and the arguments that are + * expected by this function are determined by @format_string. See the + * section on GVariant Format + * Strings. Please note that the syntax of the format string is + * very likely to be extended in the future. + * + * The first character of the format string must not be '*' '?' '@' or + * 'r'; in essence, a new #GVariant must always be constructed by this + * function (and not merely passed through it unmodified). + * + * Returns: a new floating #GVariant instance + * + * Since: 2.24 + **/ +GVariant * +g_variant_new (const gchar *format_string, + ...) +{ + GVariant *value; + va_list ap; + + g_return_val_if_fail (valid_format_string (format_string, TRUE, NULL) && + format_string[0] != '?' && format_string[0] != '@' && + format_string[0] != '*' && format_string[0] != 'r', + NULL); + + va_start (ap, format_string); + value = g_variant_new_va (format_string, NULL, &ap); + va_end (ap); + + return value; +} + +/** + * g_variant_new_va: (skip) + * @format_string: a string that is prefixed with a format string + * @endptr: (allow-none) (default NULL): location to store the end pointer, + * or %NULL + * @app: a pointer to a #va_list + * + * This function is intended to be used by libraries based on + * #GVariant that want to provide g_variant_new()-like functionality + * to their users. + * + * The API is more general than g_variant_new() to allow a wider range + * of possible uses. + * + * @format_string must still point to a valid format string, but it only + * needs to be nul-terminated if @endptr is %NULL. If @endptr is + * non-%NULL then it is updated to point to the first character past the + * end of the format string. + * + * @app is a pointer to a #va_list. The arguments, according to + * @format_string, are collected from this #va_list and the list is left + * pointing to the argument following the last. + * + * These two generalisations allow mixing of multiple calls to + * g_variant_new_va() and g_variant_get_va() within a single actual + * varargs call by the user. + * + * The return value will be floating if it was a newly created GVariant + * instance (for example, if the format string was "(ii)"). In the case + * that the format_string was '*', '?', 'r', or a format starting with + * '@' then the collected #GVariant pointer will be returned unmodified, + * without adding any additional references. + * + * In order to behave correctly in all cases it is necessary for the + * calling function to g_variant_ref_sink() the return result before + * returning control to the user that originally provided the pointer. + * At this point, the caller will have their own full reference to the + * result. This can also be done by adding the result to a container, + * or by passing it to another g_variant_new() call. + * + * Returns: a new, usually floating, #GVariant + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_va (const gchar *format_string, + const gchar **endptr, + va_list *app) +{ + GVariant *value; + + g_return_val_if_fail (valid_format_string (format_string, !endptr, NULL), + NULL); + g_return_val_if_fail (app != NULL, NULL); + + value = g_variant_valist_new (&format_string, app); + + if (endptr != NULL) + *endptr = format_string; + + return value; +} + +/** + * g_variant_get: (skip) + * @value: a #GVariant instance + * @format_string: a #GVariant format string + * @...: arguments, as per @format_string + * + * Deconstructs a #GVariant instance. + * + * Think of this function as an analogue to scanf(). + * + * The arguments that are expected by this function are entirely + * determined by @format_string. @format_string also restricts the + * permissible types of @value. It is an error to give a value with + * an incompatible type. See the section on GVariant Format Strings. + * Please note that the syntax of the format string is very likely to be + * extended in the future. + * + * Since: 2.24 + **/ +void +g_variant_get (GVariant *value, + const gchar *format_string, + ...) +{ + va_list ap; + + g_return_if_fail (valid_format_string (format_string, TRUE, value)); + + /* if any direct-pointer-access formats are in use, flatten first */ + if (strchr (format_string, '&')) + g_variant_get_data (value); + + va_start (ap, format_string); + g_variant_get_va (value, format_string, NULL, &ap); + va_end (ap); +} + +/** + * g_variant_get_va: (skip) + * @value: a #GVariant + * @format_string: a string that is prefixed with a format string + * @endptr: (allow-none) (default NULL): location to store the end pointer, + * or %NULL + * @app: a pointer to a #va_list + * + * This function is intended to be used by libraries based on #GVariant + * that want to provide g_variant_get()-like functionality to their + * users. + * + * The API is more general than g_variant_get() to allow a wider range + * of possible uses. + * + * @format_string must still point to a valid format string, but it only + * need to be nul-terminated if @endptr is %NULL. If @endptr is + * non-%NULL then it is updated to point to the first character past the + * end of the format string. + * + * @app is a pointer to a #va_list. The arguments, according to + * @format_string, are collected from this #va_list and the list is left + * pointing to the argument following the last. + * + * These two generalisations allow mixing of multiple calls to + * g_variant_new_va() and g_variant_get_va() within a single actual + * varargs call by the user. + * + * Since: 2.24 + **/ +void +g_variant_get_va (GVariant *value, + const gchar *format_string, + const gchar **endptr, + va_list *app) +{ + g_return_if_fail (valid_format_string (format_string, !endptr, value)); + g_return_if_fail (value != NULL); + g_return_if_fail (app != NULL); + + /* if any direct-pointer-access formats are in use, flatten first */ + if (strchr (format_string, '&')) + g_variant_get_data (value); + + g_variant_valist_get (&format_string, value, FALSE, app); + + if (endptr != NULL) + *endptr = format_string; +} + +/* Varargs-enabled Utility Functions {{{1 */ + +/** + * g_variant_builder_add: (skp) + * @builder: a #GVariantBuilder + * @format_string: a #GVariant varargs format string + * @...: arguments, as per @format_string + * + * Adds to a #GVariantBuilder. + * + * This call is a convenience wrapper that is exactly equivalent to + * calling g_variant_new() followed by g_variant_builder_add_value(). + * + * This function might be used as follows: + * + * + * GVariant * + * make_pointless_dictionary (void) + * { + * GVariantBuilder *builder; + * int i; + * + * builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY); + * for (i = 0; i < 16; i++) + * { + * gchar buf[3]; + * + * sprintf (buf, "%d", i); + * g_variant_builder_add (builder, "{is}", i, buf); + * } + * + * return g_variant_builder_end (builder); + * } + * + * + * Since: 2.24 + **/ +void +g_variant_builder_add (GVariantBuilder *builder, + const gchar *format_string, + ...) +{ + GVariant *variant; + va_list ap; + + va_start (ap, format_string); + variant = g_variant_new_va (format_string, NULL, &ap); + va_end (ap); + + g_variant_builder_add_value (builder, variant); +} + +/** + * g_variant_get_child: (skip) + * @value: a container #GVariant + * @index_: the index of the child to deconstruct + * @format_string: a #GVariant format string + * @...: arguments, as per @format_string + * + * Reads a child item out of a container #GVariant instance and + * deconstructs it according to @format_string. This call is + * essentially a combination of g_variant_get_child_value() and + * g_variant_get(). + * + * Since: 2.24 + **/ +void +g_variant_get_child (GVariant *value, + gsize index_, + const gchar *format_string, + ...) +{ + GVariant *child; + va_list ap; + + child = g_variant_get_child_value (value, index_); + g_return_if_fail (valid_format_string (format_string, TRUE, child)); + + va_start (ap, format_string); + g_variant_get_va (child, format_string, NULL, &ap); + va_end (ap); + + g_variant_unref (child); +} + +/** + * g_variant_iter_next: (skip) + * @iter: a #GVariantIter + * @format_string: a GVariant format string + * @...: the arguments to unpack the value into + * + * Gets the next item in the container and unpacks it into the variable + * argument list according to @format_string, returning %TRUE. + * + * If no more items remain then %FALSE is returned. + * + * All of the pointers given on the variable arguments list of this + * function are assumed to point at uninitialised memory. It is the + * responsibility of the caller to free all of the values returned by + * the unpacking process. + * + * See the section on GVariant + * Format Strings. + * + * + * Memory management with g_variant_iter_next() + * + * /* Iterates a dictionary of type 'a{sv}' */ + * void + * iterate_dictionary (GVariant *dictionary) + * { + * GVariantIter iter; + * GVariant *value; + * gchar *key; + * + * g_variant_iter_init (&iter, dictionary); + * while (g_variant_iter_next (&iter, "{sv}", &key, &value)) + * { + * g_print ("Item '%s' has type '%s'\n", key, + * g_variant_get_type_string (value)); + * + * /* must free data for ourselves */ + * g_variant_unref (value); + * g_free (key); + * } + * } + * + * + * + * For a solution that is likely to be more convenient to C programmers + * when dealing with loops, see g_variant_iter_loop(). + * + * Returns: %TRUE if a value was unpacked, or %FALSE if there as no value + * + * Since: 2.24 + **/ +gboolean +g_variant_iter_next (GVariantIter *iter, + const gchar *format_string, + ...) +{ + GVariant *value; + + value = g_variant_iter_next_value (iter); + + g_return_val_if_fail (valid_format_string (format_string, TRUE, value), + FALSE); + + if (value != NULL) + { + va_list ap; + + va_start (ap, format_string); + g_variant_valist_get (&format_string, value, FALSE, &ap); + va_end (ap); + + g_variant_unref (value); + } + + return value != NULL; +} + +/** + * g_variant_iter_loop: (skip) + * @iter: a #GVariantIter + * @format_string: a GVariant format string + * @...: the arguments to unpack the value into + * + * Gets the next item in the container and unpacks it into the variable + * argument list according to @format_string, returning %TRUE. + * + * If no more items remain then %FALSE is returned. + * + * On the first call to this function, the pointers appearing on the + * variable argument list are assumed to point at uninitialised memory. + * On the second and later calls, it is assumed that the same pointers + * will be given and that they will point to the memory as set by the + * previous call to this function. This allows the previous values to + * be freed, as appropriate. + * + * This function is intended to be used with a while loop as + * demonstrated in the following example. This function can only be + * used when iterating over an array. It is only valid to call this + * function with a string constant for the format string and the same + * string constant must be used each time. Mixing calls to this + * function and g_variant_iter_next() or g_variant_iter_next_value() on + * the same iterator causes undefined behavior. + * + * If you break out of a such a while loop using g_variant_iter_loop() then + * you must free or unreference all the unpacked values as you would with + * g_variant_get(). Failure to do so will cause a memory leak. + * + * See the section on GVariant + * Format Strings. + * + * + * Memory management with g_variant_iter_loop() + * + * /* Iterates a dictionary of type 'a{sv}' */ + * void + * iterate_dictionary (GVariant *dictionary) + * { + * GVariantIter iter; + * GVariant *value; + * gchar *key; + * + * g_variant_iter_init (&iter, dictionary); + * while (g_variant_iter_loop (&iter, "{sv}", &key, &value)) + * { + * g_print ("Item '%s' has type '%s'\n", key, + * g_variant_get_type_string (value)); + * + * /* no need to free 'key' and 'value' here */ + * /* unless breaking out of this loop */ + * } + * } + * + * + * + * For most cases you should use g_variant_iter_next(). + * + * This function is really only useful when unpacking into #GVariant or + * #GVariantIter in order to allow you to skip the call to + * g_variant_unref() or g_variant_iter_free(). + * + * For example, if you are only looping over simple integer and string + * types, g_variant_iter_next() is definitely preferred. For string + * types, use the '&' prefix to avoid allocating any memory at all (and + * thereby avoiding the need to free anything as well). + * + * Returns: %TRUE if a value was unpacked, or %FALSE if there was no + * value + * + * Since: 2.24 + **/ +gboolean +g_variant_iter_loop (GVariantIter *iter, + const gchar *format_string, + ...) +{ + gboolean first_time = GVSI(iter)->loop_format == NULL; + GVariant *value; + va_list ap; + + g_return_val_if_fail (first_time || + format_string == GVSI(iter)->loop_format, + FALSE); + + if (first_time) + { + TYPE_CHECK (GVSI(iter)->value, G_VARIANT_TYPE_ARRAY, FALSE); + GVSI(iter)->loop_format = format_string; + + if (strchr (format_string, '&')) + g_variant_get_data (GVSI(iter)->value); + } + + value = g_variant_iter_next_value (iter); + + g_return_val_if_fail (!first_time || + valid_format_string (format_string, TRUE, value), + FALSE); + + va_start (ap, format_string); + g_variant_valist_get (&format_string, value, !first_time, &ap); + va_end (ap); + + if (value != NULL) + g_variant_unref (value); + + return value != NULL; +} + +/* Serialised data {{{1 */ +static GVariant * +g_variant_deep_copy (GVariant *value) +{ + switch (g_variant_classify (value)) + { + case G_VARIANT_CLASS_MAYBE: + case G_VARIANT_CLASS_ARRAY: + case G_VARIANT_CLASS_TUPLE: + case G_VARIANT_CLASS_DICT_ENTRY: + case G_VARIANT_CLASS_VARIANT: + { + GVariantBuilder builder; + GVariantIter iter; + GVariant *child; + + g_variant_builder_init (&builder, g_variant_get_type (value)); + g_variant_iter_init (&iter, value); + + while ((child = g_variant_iter_next_value (&iter))) + { + g_variant_builder_add_value (&builder, g_variant_deep_copy (child)); + g_variant_unref (child); + } + + return g_variant_builder_end (&builder); + } + + case G_VARIANT_CLASS_BOOLEAN: + return g_variant_new_boolean (g_variant_get_boolean (value)); + + case G_VARIANT_CLASS_BYTE: + return g_variant_new_byte (g_variant_get_byte (value)); + + case G_VARIANT_CLASS_INT16: + return g_variant_new_int16 (g_variant_get_int16 (value)); + + case G_VARIANT_CLASS_UINT16: + return g_variant_new_uint16 (g_variant_get_uint16 (value)); + + case G_VARIANT_CLASS_INT32: + return g_variant_new_int32 (g_variant_get_int32 (value)); + + case G_VARIANT_CLASS_UINT32: + return g_variant_new_uint32 (g_variant_get_uint32 (value)); + + case G_VARIANT_CLASS_INT64: + return g_variant_new_int64 (g_variant_get_int64 (value)); + + case G_VARIANT_CLASS_UINT64: + return g_variant_new_uint64 (g_variant_get_uint64 (value)); + + case G_VARIANT_CLASS_HANDLE: + return g_variant_new_handle (g_variant_get_handle (value)); + + case G_VARIANT_CLASS_DOUBLE: + return g_variant_new_double (g_variant_get_double (value)); + + case G_VARIANT_CLASS_STRING: + return g_variant_new_string (g_variant_get_string (value, NULL)); + + case G_VARIANT_CLASS_OBJECT_PATH: + return g_variant_new_object_path (g_variant_get_string (value, NULL)); + + case G_VARIANT_CLASS_SIGNATURE: + return g_variant_new_signature (g_variant_get_string (value, NULL)); + } + + g_assert_not_reached (); +} + +/** + * g_variant_get_normal_form: + * @value: a #GVariant + * + * Gets a #GVariant instance that has the same value as @value and is + * trusted to be in normal form. + * + * If @value is already trusted to be in normal form then a new + * reference to @value is returned. + * + * If @value is not already trusted, then it is scanned to check if it + * is in normal form. If it is found to be in normal form then it is + * marked as trusted and a new reference to it is returned. + * + * If @value is found not to be in normal form then a new trusted + * #GVariant is created with the same value as @value. + * + * It makes sense to call this function if you've received #GVariant + * data from untrusted sources and you want to ensure your serialised + * output is definitely in normal form. + * + * Returns: (transfer full): a trusted #GVariant + * + * Since: 2.24 + **/ +GVariant * +g_variant_get_normal_form (GVariant *value) +{ + GVariant *trusted; + + if (g_variant_is_normal_form (value)) + return g_variant_ref (value); + + trusted = g_variant_deep_copy (value); + g_assert (g_variant_is_trusted (trusted)); + + return g_variant_ref_sink (trusted); +} + +/** + * g_variant_byteswap: + * @value: a #GVariant + * + * Performs a byteswapping operation on the contents of @value. The + * result is that all multi-byte numeric data contained in @value is + * byteswapped. That includes 16, 32, and 64bit signed and unsigned + * integers as well as file handles and double precision floating point + * values. + * + * This function is an identity mapping on any value that does not + * contain multi-byte numeric data. That include strings, booleans, + * bytes and containers containing only these things (recursively). + * + * The returned value is always in normal form and is marked as trusted. + * + * Returns: (transfer full): the byteswapped form of @value + * + * Since: 2.24 + **/ +GVariant * +g_variant_byteswap (GVariant *value) +{ + GVariantTypeInfo *type_info; + guint alignment; + GVariant *new; + + type_info = g_variant_get_type_info (value); + + g_variant_type_info_query (type_info, &alignment, NULL); + + if (alignment) + /* (potentially) contains multi-byte numeric data */ + { + GVariantSerialised serialised; + GVariant *trusted; + GBytes *bytes; + + trusted = g_variant_get_normal_form (value); + serialised.type_info = g_variant_get_type_info (trusted); + serialised.size = g_variant_get_size (trusted); + serialised.data = g_malloc (serialised.size); + g_variant_store (trusted, serialised.data); + g_variant_unref (trusted); + + g_variant_serialised_byteswap (serialised); + + bytes = g_bytes_new_take (serialised.data, serialised.size); + new = g_variant_new_from_bytes (g_variant_get_type (value), bytes, TRUE); + g_bytes_unref (bytes); + } + else + /* contains no multi-byte data */ + new = value; + + return g_variant_ref_sink (new); +} + +/** + * g_variant_new_from_data: + * @type: a definite #GVariantType + * @data: (array length=size) (element-type guint8): the serialised data + * @size: the size of @data + * @trusted: %TRUE if @data is definitely in normal form + * @notify: (scope async): function to call when @data is no longer needed + * @user_data: data for @notify + * + * Creates a new #GVariant instance from serialised data. + * + * @type is the type of #GVariant instance that will be constructed. + * The interpretation of @data depends on knowing the type. + * + * @data is not modified by this function and must remain valid with an + * unchanging value until such a time as @notify is called with + * @user_data. If the contents of @data change before that time then + * the result is undefined. + * + * If @data is trusted to be serialised data in normal form then + * @trusted should be %TRUE. This applies to serialised data created + * within this process or read from a trusted location on the disk (such + * as a file installed in /usr/lib alongside your application). You + * should set trusted to %FALSE if @data is read from the network, a + * file in the user's home directory, etc. + * + * If @data was not stored in this machine's native endianness, any multi-byte + * numeric values in the returned variant will also be in non-native + * endianness. g_variant_byteswap() can be used to recover the original values. + * + * @notify will be called with @user_data when @data is no longer + * needed. The exact time of this call is unspecified and might even be + * before this function returns. + * + * Returns: (transfer none): a new floating #GVariant of type @type + * + * Since: 2.24 + **/ +GVariant * +g_variant_new_from_data (const GVariantType *type, + gconstpointer data, + gsize size, + gboolean trusted, + GDestroyNotify notify, + gpointer user_data) +{ + GVariant *value; + GBytes *bytes; + + g_return_val_if_fail (g_variant_type_is_definite (type), NULL); + g_return_val_if_fail (data != NULL || size == 0, NULL); + + if (notify) + bytes = g_bytes_new_with_free_func (data, size, notify, user_data); + else + bytes = g_bytes_new_static (data, size); + + value = g_variant_new_from_bytes (type, bytes, trusted); + g_bytes_unref (bytes); + + return value; +} + +/* Epilogue {{{1 */ +/* vim:set foldmethod=marker: */ diff --git a/glib/glib/gvariant.h b/glib/glib/gvariant.h new file mode 100644 index 0000000..9abcc0b --- /dev/null +++ b/glib/glib/gvariant.h @@ -0,0 +1,282 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_VARIANT_H__ +#define __G_VARIANT_H__ + +#include +#include + +G_BEGIN_DECLS + +typedef struct _GVariant GVariant; + +typedef enum +{ + G_VARIANT_CLASS_BOOLEAN = 'b', + G_VARIANT_CLASS_BYTE = 'y', + G_VARIANT_CLASS_INT16 = 'n', + G_VARIANT_CLASS_UINT16 = 'q', + G_VARIANT_CLASS_INT32 = 'i', + G_VARIANT_CLASS_UINT32 = 'u', + G_VARIANT_CLASS_INT64 = 'x', + G_VARIANT_CLASS_UINT64 = 't', + G_VARIANT_CLASS_HANDLE = 'h', + G_VARIANT_CLASS_DOUBLE = 'd', + G_VARIANT_CLASS_STRING = 's', + G_VARIANT_CLASS_OBJECT_PATH = 'o', + G_VARIANT_CLASS_SIGNATURE = 'g', + G_VARIANT_CLASS_VARIANT = 'v', + G_VARIANT_CLASS_MAYBE = 'm', + G_VARIANT_CLASS_ARRAY = 'a', + G_VARIANT_CLASS_TUPLE = '(', + G_VARIANT_CLASS_DICT_ENTRY = '{' +} GVariantClass; + +void g_variant_unref (GVariant *value); +GVariant * g_variant_ref (GVariant *value); +GVariant * g_variant_ref_sink (GVariant *value); +gboolean g_variant_is_floating (GVariant *value); +GVariant * g_variant_take_ref (GVariant *value); + +const GVariantType * g_variant_get_type (GVariant *value); +const gchar * g_variant_get_type_string (GVariant *value); +gboolean g_variant_is_of_type (GVariant *value, + const GVariantType *type); +gboolean g_variant_is_container (GVariant *value); +GVariantClass g_variant_classify (GVariant *value); +GVariant * g_variant_new_boolean (gboolean value); +GVariant * g_variant_new_byte (guchar value); +GVariant * g_variant_new_int16 (gint16 value); +GVariant * g_variant_new_uint16 (guint16 value); +GVariant * g_variant_new_int32 (gint32 value); +GVariant * g_variant_new_uint32 (guint32 value); +GVariant * g_variant_new_int64 (gint64 value); +GVariant * g_variant_new_uint64 (guint64 value); +GVariant * g_variant_new_handle (gint32 value); +GVariant * g_variant_new_double (gdouble value); +GVariant * g_variant_new_string (const gchar *string); +GVariant * g_variant_new_object_path (const gchar *object_path); +gboolean g_variant_is_object_path (const gchar *string); +GVariant * g_variant_new_signature (const gchar *signature); +gboolean g_variant_is_signature (const gchar *string); +GVariant * g_variant_new_variant (GVariant *value); +GVariant * g_variant_new_strv (const gchar * const *strv, + gssize length); +GVariant * g_variant_new_objv (const gchar * const *strv, + gssize length); +GVariant * g_variant_new_bytestring (const gchar *string); +GVariant * g_variant_new_bytestring_array (const gchar * const *strv, + gssize length); +GVariant * g_variant_new_fixed_array (const GVariantType *element_type, + gconstpointer elements, + gsize n_elements, + gsize element_size); +gboolean g_variant_get_boolean (GVariant *value); +guchar g_variant_get_byte (GVariant *value); +gint16 g_variant_get_int16 (GVariant *value); +guint16 g_variant_get_uint16 (GVariant *value); +gint32 g_variant_get_int32 (GVariant *value); +guint32 g_variant_get_uint32 (GVariant *value); +gint64 g_variant_get_int64 (GVariant *value); +guint64 g_variant_get_uint64 (GVariant *value); +gint32 g_variant_get_handle (GVariant *value); +gdouble g_variant_get_double (GVariant *value); +GVariant * g_variant_get_variant (GVariant *value); +const gchar * g_variant_get_string (GVariant *value, + gsize *length); +gchar * g_variant_dup_string (GVariant *value, + gsize *length); +const gchar ** g_variant_get_strv (GVariant *value, + gsize *length); +gchar ** g_variant_dup_strv (GVariant *value, + gsize *length); +const gchar ** g_variant_get_objv (GVariant *value, + gsize *length); +gchar ** g_variant_dup_objv (GVariant *value, + gsize *length); +const gchar * g_variant_get_bytestring (GVariant *value); +gchar * g_variant_dup_bytestring (GVariant *value, + gsize *length); +const gchar ** g_variant_get_bytestring_array (GVariant *value, + gsize *length); +gchar ** g_variant_dup_bytestring_array (GVariant *value, + gsize *length); + +GVariant * g_variant_new_maybe (const GVariantType *child_type, + GVariant *child); +GVariant * g_variant_new_array (const GVariantType *child_type, + GVariant * const *children, + gsize n_children); +GVariant * g_variant_new_tuple (GVariant * const *children, + gsize n_children); +GVariant * g_variant_new_dict_entry (GVariant *key, + GVariant *value); + +GVariant * g_variant_get_maybe (GVariant *value); +gsize g_variant_n_children (GVariant *value); +void g_variant_get_child (GVariant *value, + gsize index_, + const gchar *format_string, + ...); +GVariant * g_variant_get_child_value (GVariant *value, + gsize index_); +gboolean g_variant_lookup (GVariant *dictionary, + const gchar *key, + const gchar *format_string, + ...); +GVariant * g_variant_lookup_value (GVariant *dictionary, + const gchar *key, + const GVariantType *expected_type); +gconstpointer g_variant_get_fixed_array (GVariant *value, + gsize *n_elements, + gsize element_size); + +gsize g_variant_get_size (GVariant *value); +gconstpointer g_variant_get_data (GVariant *value); +void g_variant_store (GVariant *value, + gpointer data); + +gchar * g_variant_print (GVariant *value, + gboolean type_annotate); +GString * g_variant_print_string (GVariant *value, + GString *string, + gboolean type_annotate); + +guint g_variant_hash (gconstpointer value); +gboolean g_variant_equal (gconstpointer one, + gconstpointer two); + +GVariant * g_variant_get_normal_form (GVariant *value); +gboolean g_variant_is_normal_form (GVariant *value); +GVariant * g_variant_byteswap (GVariant *value); +GVariant * g_variant_new_from_data (const GVariantType *type, + gconstpointer data, + gsize size, + gboolean trusted, + GDestroyNotify notify, + gpointer user_data); + +typedef struct _GVariantIter GVariantIter; +struct _GVariantIter { + /*< private >*/ + gsize x[16]; +}; + +GVariantIter * g_variant_iter_new (GVariant *value); +gsize g_variant_iter_init (GVariantIter *iter, + GVariant *value); +GVariantIter * g_variant_iter_copy (GVariantIter *iter); +gsize g_variant_iter_n_children (GVariantIter *iter); +void g_variant_iter_free (GVariantIter *iter); +GVariant * g_variant_iter_next_value (GVariantIter *iter); +gboolean g_variant_iter_next (GVariantIter *iter, + const gchar *format_string, + ...); +gboolean g_variant_iter_loop (GVariantIter *iter, + const gchar *format_string, + ...); + + +typedef struct _GVariantBuilder GVariantBuilder; +struct _GVariantBuilder { + /*< private >*/ + gsize x[16]; +}; + +typedef enum +{ + G_VARIANT_PARSE_ERROR_FAILED, + G_VARIANT_PARSE_ERROR_BASIC_TYPE_EXPECTED, + G_VARIANT_PARSE_ERROR_CANNOT_INFER_TYPE, + G_VARIANT_PARSE_ERROR_DEFINITE_TYPE_EXPECTED, + G_VARIANT_PARSE_ERROR_INPUT_NOT_AT_END, + G_VARIANT_PARSE_ERROR_INVALID_CHARACTER, + G_VARIANT_PARSE_ERROR_INVALID_FORMAT_STRING, + G_VARIANT_PARSE_ERROR_INVALID_OBJECT_PATH, + G_VARIANT_PARSE_ERROR_INVALID_SIGNATURE, + G_VARIANT_PARSE_ERROR_INVALID_TYPE_STRING, + G_VARIANT_PARSE_ERROR_NO_COMMON_TYPE, + G_VARIANT_PARSE_ERROR_NUMBER_OUT_OF_RANGE, + G_VARIANT_PARSE_ERROR_NUMBER_TOO_BIG, + G_VARIANT_PARSE_ERROR_TYPE_ERROR, + G_VARIANT_PARSE_ERROR_UNEXPECTED_TOKEN, + G_VARIANT_PARSE_ERROR_UNKNOWN_KEYWORD, + G_VARIANT_PARSE_ERROR_UNTERMINATED_STRING_CONSTANT, + G_VARIANT_PARSE_ERROR_VALUE_EXPECTED +} GVariantParseError; +#define G_VARIANT_PARSE_ERROR (g_variant_parser_get_error_quark ()) + +GQuark g_variant_parser_get_error_quark (void); + +GVariantBuilder * g_variant_builder_new (const GVariantType *type); +void g_variant_builder_unref (GVariantBuilder *builder); +GVariantBuilder * g_variant_builder_ref (GVariantBuilder *builder); +void g_variant_builder_init (GVariantBuilder *builder, + const GVariantType *type); +GVariant * g_variant_builder_end (GVariantBuilder *builder); +void g_variant_builder_clear (GVariantBuilder *builder); +void g_variant_builder_open (GVariantBuilder *builder, + const GVariantType *type); +void g_variant_builder_close (GVariantBuilder *builder); +void g_variant_builder_add_value (GVariantBuilder *builder, + GVariant *value); +void g_variant_builder_add (GVariantBuilder *builder, + const gchar *format_string, + ...); +void g_variant_builder_add_parsed (GVariantBuilder *builder, + const gchar *format, + ...); + +GVariant * g_variant_new (const gchar *format_string, + ...); +void g_variant_get (GVariant *value, + const gchar *format_string, + ...); +GVariant * g_variant_new_va (const gchar *format_string, + const gchar **endptr, + va_list *app); +void g_variant_get_va (GVariant *value, + const gchar *format_string, + const gchar **endptr, + va_list *app); + + +GVariant * g_variant_parse (const GVariantType *type, + const gchar *text, + const gchar *limit, + const gchar **endptr, + GError **error); +GVariant * g_variant_new_parsed (const gchar *format, + ...); +GVariant * g_variant_new_parsed_va (const gchar *format, + va_list *app); + +gint g_variant_compare (gconstpointer one, + gconstpointer two); +G_END_DECLS + +#endif /* __G_VARIANT_H__ */ diff --git a/glib/glib/gvarianttype.c b/glib/glib/gvarianttype.c new file mode 100644 index 0000000..a242a38 --- /dev/null +++ b/glib/glib/gvarianttype.c @@ -0,0 +1,1523 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gvarianttype.h" + +#include +#include + +#include + + +/** + * SECTION:gvarianttype + * @title: GVariantType + * @short_description: introduction to the GVariant type system + * @see_also: #GVariantType, #GVariant + * + * This section introduces the GVariant type system. It is based, in + * large part, on the D-Bus type system, with two major changes and some minor + * lifting of restrictions. The DBus + * specification, therefore, provides a significant amount of + * information that is useful when working with GVariant. + * + * The first major change with respect to the D-Bus type system is the + * introduction of maybe (or "nullable") types. Any type in GVariant can be + * converted to a maybe type, in which case, "nothing" (or "null") becomes a + * valid value. Maybe types have been added by introducing the + * character "m" to type strings. + * + * The second major change is that the GVariant type system supports the + * concept of "indefinite types" -- types that are less specific than + * the normal types found in D-Bus. For example, it is possible to speak + * of "an array of any type" in GVariant, where the D-Bus type system + * would require you to speak of "an array of integers" or "an array of + * strings". Indefinite types have been added by introducing the + * characters "*", "?" and + * "r" to type strings. + * + * Finally, all arbitrary restrictions relating to the complexity of + * types are lifted along with the restriction that dictionary entries + * may only appear nested inside of arrays. + * + * Just as in D-Bus, GVariant types are described with strings ("type + * strings"). Subject to the differences mentioned above, these strings + * are of the same form as those found in DBus. Note, however: D-Bus + * always works in terms of messages and therefore individual type + * strings appear nowhere in its interface. Instead, "signatures" + * are a concatenation of the strings of the type of each argument in a + * message. GVariant deals with single values directly so GVariant type + * strings always describe the type of exactly one value. This means + * that a D-Bus signature string is generally not a valid GVariant type + * string -- except in the case that it is the signature of a message + * containing exactly one argument. + * + * An indefinite type is similar in spirit to what may be called an + * abstract type in other type systems. No value can exist that has an + * indefinite type as its type, but values can exist that have types + * that are subtypes of indefinite types. That is to say, + * g_variant_get_type() will never return an indefinite type, but + * calling g_variant_is_of_type() with an indefinite type may return + * %TRUE. For example, you cannot have a value that represents "an + * array of no particular type", but you can have an "array of integers" + * which certainly matches the type of "an array of no particular type", + * since "array of integers" is a subtype of "array of no particular + * type". + * + * This is similar to how instances of abstract classes may not + * directly exist in other type systems, but instances of their + * non-abstract subtypes may. For example, in GTK, no object that has + * the type of #GtkBin can exist (since #GtkBin is an abstract class), + * but a #GtkWindow can certainly be instantiated, and you would say + * that the #GtkWindow is a #GtkBin (since #GtkWindow is a subclass of + * #GtkBin). + * + * A detailed description of GVariant type strings is given here: + * + * + * GVariant Type Strings + * + * A GVariant type string can be any of the following: + * + * + * + * + * any basic type string (listed below) + * + * + * + * + * "v", "r" or + * "*" + * + * + * + * + * one of the characters 'a' or + * 'm', followed by another type string + * + * + * + * + * the character '(', followed by a concatenation + * of zero or more other type strings, followed by the character + * ')' + * + * + * + * + * the character '{', followed by a basic type + * string (see below), followed by another type string, followed by + * the character '}' + * + * + * + * + * A basic type string describes a basic type (as per + * g_variant_type_is_basic()) and is always a single + * character in length. The valid basic type strings are + * "b", "y", + * "n", "q", + * "i", "u", + * "x", "t", + * "h", "d", + * "s", "o", + * "g" and "?". + * + * + * The above definition is recursive to arbitrary depth. + * "aaaaai" and "(ui(nq((y)))s)" + * are both valid type strings, as is + * "a(aa(ui)(qna{ya(yd)}))". + * + * + * The meaning of each of the characters is as follows: + * + * + * + * + * + * + * + * Character + * + * + * + * + * Meaning + * + * + * + * + * + * + * b + * + * + * + * + * the type string of %G_VARIANT_TYPE_BOOLEAN; a boolean value. + * + * + * + * + * + * + * y + * + * + * + * + * the type string of %G_VARIANT_TYPE_BYTE; a byte. + * + * + * + * + * + * + * n + * + * + * + * + * the type string of %G_VARIANT_TYPE_INT16; a signed 16 bit + * integer. + * + * + * + * + * + * + * q + * + * + * + * + * the type string of %G_VARIANT_TYPE_UINT16; an unsigned 16 bit + * integer. + * + * + * + * + * + * + * i + * + * + * + * + * the type string of %G_VARIANT_TYPE_INT32; a signed 32 bit + * integer. + * + * + * + * + * + * + * u + * + * + * + * + * the type string of %G_VARIANT_TYPE_UINT32; an unsigned 32 bit + * integer. + * + * + * + * + * + * + * x + * + * + * + * + * the type string of %G_VARIANT_TYPE_INT64; a signed 64 bit + * integer. + * + * + * + * + * + * + * t + * + * + * + * + * the type string of %G_VARIANT_TYPE_UINT64; an unsigned 64 bit + * integer. + * + * + * + * + * + * + * h + * + * + * + * + * the type string of %G_VARIANT_TYPE_HANDLE; a signed 32 bit + * value that, by convention, is used as an index into an array + * of file descriptors that are sent alongside a D-Bus message. + * + * + * + * + * + * + * d + * + * + * + * + * the type string of %G_VARIANT_TYPE_DOUBLE; a double precision + * floating point value. + * + * + * + * + * + * + * s + * + * + * + * + * the type string of %G_VARIANT_TYPE_STRING; a string. + * + * + * + * + * + * + * o + * + * + * + * + * the type string of %G_VARIANT_TYPE_OBJECT_PATH; a string in + * the form of a D-Bus object path. + * + * + * + * + * + * + * g + * + * + * + * + * the type string of %G_VARIANT_TYPE_STRING; a string in the + * form of a D-Bus type signature. + * + * + * + * + * + * + * ? + * + * + * + * + * the type string of %G_VARIANT_TYPE_BASIC; an indefinite type + * that is a supertype of any of the basic types. + * + * + * + * + * + * + * v + * + * + * + * + * the type string of %G_VARIANT_TYPE_VARIANT; a container type + * that contain any other type of value. + * + * + * + * + * + * + * a + * + * + * + * + * used as a prefix on another type string to mean an array of + * that type; the type string "ai", for + * example, is the type of an array of 32 bit signed integers. + * + * + * + * + * + * + * m + * + * + * + * + * used as a prefix on another type string to mean a "maybe", or + * "nullable", version of that type; the type string + * "ms", for example, is the type of a value + * that maybe contains a string, or maybe contains nothing. + * + * + * + * + * + * + * () + * + * + * + * + * used to enclose zero or more other concatenated type strings + * to create a tuple type; the type string + * "(is)", for example, is the type of a pair + * of an integer and a string. + * + * + * + * + * + * + * r + * + * + * + * + * the type string of %G_VARIANT_TYPE_TUPLE; an indefinite type + * that is a supertype of any tuple type, regardless of the + * number of items. + * + * + * + * + * + * + * {} + * + * + * + * + * used to enclose a basic type string concatenated with another + * type string to create a dictionary entry type, which usually + * appears inside of an array to form a dictionary; the type + * string "a{sd}", for example, is the type of + * a dictionary that maps strings to double precision floating + * point values. + * + * + * The first type (the basic type) is the key type and the second + * type is the value type. The reason that the first type is + * restricted to being a basic type is so that it can easily be + * hashed. + * + * + * + * + * + * + * * + * + * + * + * + * the type string of %G_VARIANT_TYPE_ANY; the indefinite type + * that is a supertype of all types. Note that, as with all type + * strings, this character represents exactly one type. It + * cannot be used inside of tuples to mean "any number of items". + * + * + * + * + * + * + * + * Any type string of a container that contains an indefinite type is, + * itself, an indefinite type. For example, the type string + * "a*" (corresponding to %G_VARIANT_TYPE_ARRAY) is + * an indefinite type that is a supertype of every array type. + * "(*s)" is a supertype of all tuples that + * contain exactly two items where the second item is a string. + * + * + * "a{?*}" is an indefinite type that is a + * supertype of all arrays containing dictionary entries where the key + * is any basic type and the value is any type at all. This is, by + * definition, a dictionary, so this type string corresponds to + * %G_VARIANT_TYPE_DICTIONARY. Note that, due to the restriction that + * the key of a dictionary entry must be a basic type, + * "{**}" is not a valid type string. + * + * + */ + + +static gboolean +g_variant_type_check (const GVariantType *type) +{ + const gchar *type_string; + + if (type == NULL) + return FALSE; + + type_string = (const gchar *) type; +#ifndef G_DISABLE_CHECKS + return g_variant_type_string_scan (type_string, NULL, NULL); +#else + return TRUE; +#endif +} + +/** + * g_variant_type_string_scan: + * @string: a pointer to any string + * @limit: (allow-none): the end of @string, or %NULL + * @endptr: (out) (allow-none): location to store the end pointer, or %NULL + * + * Scan for a single complete and valid GVariant type string in @string. + * The memory pointed to by @limit (or bytes beyond it) is never + * accessed. + * + * If a valid type string is found, @endptr is updated to point to the + * first character past the end of the string that was found and %TRUE + * is returned. + * + * If there is no valid type string starting at @string, or if the type + * string does not end before @limit then %FALSE is returned. + * + * For the simple case of checking if a string is a valid type string, + * see g_variant_type_string_is_valid(). + * + * Returns: %TRUE if a valid type string was found + * + * Since: 2.24 + **/ +gboolean +g_variant_type_string_scan (const gchar *string, + const gchar *limit, + const gchar **endptr) +{ + g_return_val_if_fail (string != NULL, FALSE); + + if (string == limit || *string == '\0') + return FALSE; + + switch (*string++) + { + case '(': + while (string == limit || *string != ')') + if (!g_variant_type_string_scan (string, limit, &string)) + return FALSE; + + string++; + break; + + case '{': + if (string == limit || *string == '\0' || /* { */ + !strchr ("bynqihuxtdsog?", *string++) || /* key */ + !g_variant_type_string_scan (string, limit, &string) || /* value */ + string == limit || *string++ != '}') /* } */ + return FALSE; + + break; + + case 'm': case 'a': + return g_variant_type_string_scan (string, limit, endptr); + + case 'b': case 'y': case 'n': case 'q': case 'i': case 'u': + case 'x': case 't': case 'd': case 's': case 'o': case 'g': + case 'v': case 'r': case '*': case '?': case 'h': + break; + + default: + return FALSE; + } + + if (endptr != NULL) + *endptr = string; + + return TRUE; +} + +/** + * g_variant_type_string_is_valid: + * @type_string: a pointer to any string + * + * Checks if @type_string is a valid GVariant type string. This call is + * equivalent to calling g_variant_type_string_scan() and confirming + * that the following character is a nul terminator. + * + * Returns: %TRUE if @type_string is exactly one valid type string + * + * Since 2.24 + **/ +gboolean +g_variant_type_string_is_valid (const gchar *type_string) +{ + const gchar *endptr; + + g_return_val_if_fail (type_string != NULL, FALSE); + + if (!g_variant_type_string_scan (type_string, NULL, &endptr)) + return FALSE; + + return *endptr == '\0'; +} + +/** + * g_variant_type_free: + * @type: a #GVariantType, or %NULL + * + * Frees a #GVariantType that was allocated with + * g_variant_type_copy(), g_variant_type_new() or one of the container + * type constructor functions. + * + * In the case that @type is %NULL, this function does nothing. + * + * Since 2.24 + **/ +void +g_variant_type_free (GVariantType *type) +{ + g_return_if_fail (type == NULL || g_variant_type_check (type)); + + g_free (type); +} + +/** + * g_variant_type_copy: + * @type: a #GVariantType + * + * Makes a copy of a #GVariantType. It is appropriate to call + * g_variant_type_free() on the return value. @type may not be %NULL. + * + * Returns: (transfer full): a new #GVariantType + * + * Since 2.24 + **/ +GVariantType * +g_variant_type_copy (const GVariantType *type) +{ + gsize length; + gchar *new; + + g_return_val_if_fail (g_variant_type_check (type), NULL); + + length = g_variant_type_get_string_length (type); + new = g_malloc (length + 1); + + memcpy (new, type, length); + new[length] = '\0'; + + return (GVariantType *) new; +} + +/** + * g_variant_type_new: + * @type_string: a valid GVariant type string + * + * Creates a new #GVariantType corresponding to the type string given + * by @type_string. It is appropriate to call g_variant_type_free() on + * the return value. + * + * It is a programmer error to call this function with an invalid type + * string. Use g_variant_type_string_is_valid() if you are unsure. + * + * Returns: (transfer full): a new #GVariantType + * + * Since: 2.24 + */ +GVariantType * +g_variant_type_new (const gchar *type_string) +{ + g_return_val_if_fail (type_string != NULL, NULL); + + return g_variant_type_copy (G_VARIANT_TYPE (type_string)); +} + +/** + * g_variant_type_get_string_length: + * @type: a #GVariantType + * + * Returns the length of the type string corresponding to the given + * @type. This function must be used to determine the valid extent of + * the memory region returned by g_variant_type_peek_string(). + * + * Returns: the length of the corresponding type string + * + * Since 2.24 + **/ +gsize +g_variant_type_get_string_length (const GVariantType *type) +{ + const gchar *type_string = (const gchar *) type; + gint brackets = 0; + gsize index = 0; + + g_return_val_if_fail (g_variant_type_check (type), 0); + + do + { + while (type_string[index] == 'a' || type_string[index] == 'm') + index++; + + if (type_string[index] == '(' || type_string[index] == '{') + brackets++; + + else if (type_string[index] == ')' || type_string[index] == '}') + brackets--; + + index++; + } + while (brackets); + + return index; +} + +/* + This function is not introspectable, it returns something that + is not an array and neither a string +*/ +/** + * g_variant_type_peek_string: (skip) + * @type: a #GVariantType + * + * Returns the type string corresponding to the given @type. The + * result is not nul-terminated; in order to determine its length you + * must call g_variant_type_get_string_length(). + * + * To get a nul-terminated string, see g_variant_type_dup_string(). + * + * Returns: the corresponding type string (not nul-terminated) + * + * Since 2.24 + **/ +const gchar * +g_variant_type_peek_string (const GVariantType *type) +{ + g_return_val_if_fail (g_variant_type_check (type), NULL); + + return (const gchar *) type; +} + +/** + * g_variant_type_dup_string: + * @type: a #GVariantType + * + * Returns a newly-allocated copy of the type string corresponding to + * @type. The returned string is nul-terminated. It is appropriate to + * call g_free() on the return value. + * + * Returns: (transfer full): the corresponding type string + * + * Since 2.24 + **/ +gchar * +g_variant_type_dup_string (const GVariantType *type) +{ + g_return_val_if_fail (g_variant_type_check (type), NULL); + + return g_strndup (g_variant_type_peek_string (type), + g_variant_type_get_string_length (type)); +} + +/** + * g_variant_type_is_definite: + * @type: a #GVariantType + * + * Determines if the given @type is definite (ie: not indefinite). + * + * A type is definite if its type string does not contain any indefinite + * type characters ('*', '?', or 'r'). + * + * A #GVariant instance may not have an indefinite type, so calling + * this function on the result of g_variant_get_type() will always + * result in %TRUE being returned. Calling this function on an + * indefinite type like %G_VARIANT_TYPE_ARRAY, however, will result in + * %FALSE being returned. + * + * Returns: %TRUE if @type is definite + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_definite (const GVariantType *type) +{ + const gchar *type_string; + gsize type_length; + gsize i; + + g_return_val_if_fail (g_variant_type_check (type), FALSE); + + type_length = g_variant_type_get_string_length (type); + type_string = g_variant_type_peek_string (type); + + for (i = 0; i < type_length; i++) + if (type_string[i] == '*' || + type_string[i] == '?' || + type_string[i] == 'r') + return FALSE; + + return TRUE; +} + +/** + * g_variant_type_is_container: + * @type: a #GVariantType + * + * Determines if the given @type is a container type. + * + * Container types are any array, maybe, tuple, or dictionary + * entry types plus the variant type. + * + * This function returns %TRUE for any indefinite type for which every + * definite subtype is a container -- %G_VARIANT_TYPE_ARRAY, for + * example. + * + * Returns: %TRUE if @type is a container type + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_container (const GVariantType *type) +{ + gchar first_char; + + g_return_val_if_fail (g_variant_type_check (type), FALSE); + + first_char = g_variant_type_peek_string (type)[0]; + switch (first_char) + { + case 'a': + case 'm': + case 'r': + case '(': + case '{': + case 'v': + return TRUE; + + default: + return FALSE; + } +} + +/** + * g_variant_type_is_basic: + * @type: a #GVariantType + * + * Determines if the given @type is a basic type. + * + * Basic types are booleans, bytes, integers, doubles, strings, object + * paths and signatures. + * + * Only a basic type may be used as the key of a dictionary entry. + * + * This function returns %FALSE for all indefinite types except + * %G_VARIANT_TYPE_BASIC. + * + * Returns: %TRUE if @type is a basic type + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_basic (const GVariantType *type) +{ + gchar first_char; + + g_return_val_if_fail (g_variant_type_check (type), FALSE); + + first_char = g_variant_type_peek_string (type)[0]; + switch (first_char) + { + case 'b': + case 'y': + case 'n': + case 'q': + case 'i': + case 'h': + case 'u': + case 't': + case 'x': + case 'd': + case 's': + case 'o': + case 'g': + case '?': + return TRUE; + + default: + return FALSE; + } +} + +/** + * g_variant_type_is_maybe: + * @type: a #GVariantType + * + * Determines if the given @type is a maybe type. This is true if the + * type string for @type starts with an 'm'. + * + * This function returns %TRUE for any indefinite type for which every + * definite subtype is a maybe type -- %G_VARIANT_TYPE_MAYBE, for + * example. + * + * Returns: %TRUE if @type is a maybe type + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_maybe (const GVariantType *type) +{ + g_return_val_if_fail (g_variant_type_check (type), FALSE); + + return g_variant_type_peek_string (type)[0] == 'm'; +} + +/** + * g_variant_type_is_array: + * @type: a #GVariantType + * + * Determines if the given @type is an array type. This is true if the + * type string for @type starts with an 'a'. + * + * This function returns %TRUE for any indefinite type for which every + * definite subtype is an array type -- %G_VARIANT_TYPE_ARRAY, for + * example. + * + * Returns: %TRUE if @type is an array type + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_array (const GVariantType *type) +{ + g_return_val_if_fail (g_variant_type_check (type), FALSE); + + return g_variant_type_peek_string (type)[0] == 'a'; +} + +/** + * g_variant_type_is_tuple: + * @type: a #GVariantType + * + * Determines if the given @type is a tuple type. This is true if the + * type string for @type starts with a '(' or if @type is + * %G_VARIANT_TYPE_TUPLE. + * + * This function returns %TRUE for any indefinite type for which every + * definite subtype is a tuple type -- %G_VARIANT_TYPE_TUPLE, for + * example. + * + * Returns: %TRUE if @type is a tuple type + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_tuple (const GVariantType *type) +{ + gchar type_char; + + g_return_val_if_fail (g_variant_type_check (type), FALSE); + + type_char = g_variant_type_peek_string (type)[0]; + return type_char == 'r' || type_char == '('; +} + +/** + * g_variant_type_is_dict_entry: + * @type: a #GVariantType + * + * Determines if the given @type is a dictionary entry type. This is + * true if the type string for @type starts with a '{'. + * + * This function returns %TRUE for any indefinite type for which every + * definite subtype is a dictionary entry type -- + * %G_VARIANT_TYPE_DICT_ENTRY, for example. + * + * Returns: %TRUE if @type is a dictionary entry type + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_dict_entry (const GVariantType *type) +{ + g_return_val_if_fail (g_variant_type_check (type), FALSE); + + return g_variant_type_peek_string (type)[0] == '{'; +} + +/** + * g_variant_type_is_variant: + * @type: a #GVariantType + * + * Determines if the given @type is the variant type. + * + * Returns: %TRUE if @type is the variant type + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_variant (const GVariantType *type) +{ + g_return_val_if_fail (g_variant_type_check (type), FALSE); + + return g_variant_type_peek_string (type)[0] == 'v'; +} + +/** + * g_variant_type_hash: + * @type: (type GVariantType): a #GVariantType + * + * Hashes @type. + * + * The argument type of @type is only #gconstpointer to allow use with + * #GHashTable without function pointer casting. A valid + * #GVariantType must be provided. + * + * Returns: the hash value + * + * Since 2.24 + **/ +guint +g_variant_type_hash (gconstpointer type) +{ + const gchar *type_string; + guint value = 0; + gsize length; + gsize i; + + g_return_val_if_fail (g_variant_type_check (type), 0); + + type_string = g_variant_type_peek_string (type); + length = g_variant_type_get_string_length (type); + + for (i = 0; i < length; i++) + value = (value << 5) - value + type_string[i]; + + return value; +} + +/** + * g_variant_type_equal: + * @type1: (type GVariantType): a #GVariantType + * @type2: (type GVariantType): a #GVariantType + * + * Compares @type1 and @type2 for equality. + * + * Only returns %TRUE if the types are exactly equal. Even if one type + * is an indefinite type and the other is a subtype of it, %FALSE will + * be returned if they are not exactly equal. If you want to check for + * subtypes, use g_variant_type_is_subtype_of(). + * + * The argument types of @type1 and @type2 are only #gconstpointer to + * allow use with #GHashTable without function pointer casting. For + * both arguments, a valid #GVariantType must be provided. + * + * Returns: %TRUE if @type1 and @type2 are exactly equal + * + * Since 2.24 + **/ +gboolean +g_variant_type_equal (gconstpointer type1, + gconstpointer type2) +{ + const gchar *string1, *string2; + gsize size1, size2; + + g_return_val_if_fail (g_variant_type_check (type1), FALSE); + g_return_val_if_fail (g_variant_type_check (type2), FALSE); + + if (type1 == type2) + return TRUE; + + size1 = g_variant_type_get_string_length (type1); + size2 = g_variant_type_get_string_length (type2); + + if (size1 != size2) + return FALSE; + + string1 = g_variant_type_peek_string (type1); + string2 = g_variant_type_peek_string (type2); + + return memcmp (string1, string2, size1) == 0; +} + +/** + * g_variant_type_is_subtype_of: + * @type: a #GVariantType + * @supertype: a #GVariantType + * + * Checks if @type is a subtype of @supertype. + * + * This function returns %TRUE if @type is a subtype of @supertype. All + * types are considered to be subtypes of themselves. Aside from that, + * only indefinite types can have subtypes. + * + * Returns: %TRUE if @type is a subtype of @supertype + * + * Since 2.24 + **/ +gboolean +g_variant_type_is_subtype_of (const GVariantType *type, + const GVariantType *supertype) +{ + const gchar *supertype_string; + const gchar *supertype_end; + const gchar *type_string; + + g_return_val_if_fail (g_variant_type_check (type), FALSE); + g_return_val_if_fail (g_variant_type_check (supertype), FALSE); + + supertype_string = g_variant_type_peek_string (supertype); + type_string = g_variant_type_peek_string (type); + + supertype_end = supertype_string + + g_variant_type_get_string_length (supertype); + + /* we know that type and supertype are both well-formed, so it's + * safe to treat this merely as a text processing problem. + */ + while (supertype_string < supertype_end) + { + char supertype_char = *supertype_string++; + + if (supertype_char == *type_string) + type_string++; + + else if (*type_string == ')') + return FALSE; + + else + { + const GVariantType *target_type = (GVariantType *) type_string; + + switch (supertype_char) + { + case 'r': + if (!g_variant_type_is_tuple (target_type)) + return FALSE; + break; + + case '*': + break; + + case '?': + if (!g_variant_type_is_basic (target_type)) + return FALSE; + break; + + default: + return FALSE; + } + + type_string += g_variant_type_get_string_length (target_type); + } + } + + return TRUE; +} + +/** + * g_variant_type_element: + * @type: an array or maybe #GVariantType + * + * Determines the element type of an array or maybe type. + * + * This function may only be used with array or maybe types. + * + * Returns: (transfer none): the element type of @type + * + * Since 2.24 + **/ +const GVariantType * +g_variant_type_element (const GVariantType *type) +{ + const gchar *type_string; + + g_return_val_if_fail (g_variant_type_check (type), NULL); + + type_string = g_variant_type_peek_string (type); + + g_assert (type_string[0] == 'a' || type_string[0] == 'm'); + + return (const GVariantType *) &type_string[1]; +} + +/** + * g_variant_type_first: + * @type: a tuple or dictionary entry #GVariantType + * + * Determines the first item type of a tuple or dictionary entry + * type. + * + * This function may only be used with tuple or dictionary entry types, + * but must not be used with the generic tuple type + * %G_VARIANT_TYPE_TUPLE. + * + * In the case of a dictionary entry type, this returns the type of + * the key. + * + * %NULL is returned in case of @type being %G_VARIANT_TYPE_UNIT. + * + * This call, together with g_variant_type_next() provides an iterator + * interface over tuple and dictionary entry types. + * + * Returns: (transfer none): the first item type of @type, or %NULL + * + * Since 2.24 + **/ +const GVariantType * +g_variant_type_first (const GVariantType *type) +{ + const gchar *type_string; + + g_return_val_if_fail (g_variant_type_check (type), NULL); + + type_string = g_variant_type_peek_string (type); + g_assert (type_string[0] == '(' || type_string[0] == '{'); + + if (type_string[1] == ')') + return NULL; + + return (const GVariantType *) &type_string[1]; +} + +/** + * g_variant_type_next: + * @type: a #GVariantType from a previous call + * + * Determines the next item type of a tuple or dictionary entry + * type. + * + * @type must be the result of a previous call to + * g_variant_type_first() or g_variant_type_next(). + * + * If called on the key type of a dictionary entry then this call + * returns the value type. If called on the value type of a dictionary + * entry then this call returns %NULL. + * + * For tuples, %NULL is returned when @type is the last item in a tuple. + * + * Returns: (transfer none): the next #GVariantType after @type, or %NULL + * + * Since 2.24 + **/ +const GVariantType * +g_variant_type_next (const GVariantType *type) +{ + const gchar *type_string; + + g_return_val_if_fail (g_variant_type_check (type), NULL); + + type_string = g_variant_type_peek_string (type); + type_string += g_variant_type_get_string_length (type); + + if (*type_string == ')' || *type_string == '}') + return NULL; + + return (const GVariantType *) type_string; +} + +/** + * g_variant_type_n_items: + * @type: a tuple or dictionary entry #GVariantType + * + * Determines the number of items contained in a tuple or + * dictionary entry type. + * + * This function may only be used with tuple or dictionary entry types, + * but must not be used with the generic tuple type + * %G_VARIANT_TYPE_TUPLE. + * + * In the case of a dictionary entry type, this function will always + * return 2. + * + * Returns: the number of items in @type + * + * Since 2.24 + **/ +gsize +g_variant_type_n_items (const GVariantType *type) +{ + gsize count = 0; + + g_return_val_if_fail (g_variant_type_check (type), 0); + + for (type = g_variant_type_first (type); + type; + type = g_variant_type_next (type)) + count++; + + return count; +} + +/** + * g_variant_type_key: + * @type: a dictionary entry #GVariantType + * + * Determines the key type of a dictionary entry type. + * + * This function may only be used with a dictionary entry type. Other + * than the additional restriction, this call is equivalent to + * g_variant_type_first(). + * + * Returns: (transfer none): the key type of the dictionary entry + * + * Since 2.24 + **/ +const GVariantType * +g_variant_type_key (const GVariantType *type) +{ + const gchar *type_string; + + g_return_val_if_fail (g_variant_type_check (type), NULL); + + type_string = g_variant_type_peek_string (type); + g_assert (type_string[0] == '{'); + + return (const GVariantType *) &type_string[1]; +} + +/** + * g_variant_type_value: + * @type: a dictionary entry #GVariantType + * + * Determines the value type of a dictionary entry type. + * + * This function may only be used with a dictionary entry type. + * + * Returns: (transfer none): the value type of the dictionary entry + * + * Since 2.24 + **/ +const GVariantType * +g_variant_type_value (const GVariantType *type) +{ + const gchar *type_string; + + g_return_val_if_fail (g_variant_type_check (type), NULL); + + type_string = g_variant_type_peek_string (type); + g_assert (type_string[0] == '{'); + + return g_variant_type_next (g_variant_type_key (type)); +} + +/** + * g_variant_type_new_tuple: + * @items: (array length=length): an array of #GVariantTypes, one for each item + * @length: the length of @items, or -1 + * + * Constructs a new tuple type, from @items. + * + * @length is the number of items in @items, or -1 to indicate that + * @items is %NULL-terminated. + * + * It is appropriate to call g_variant_type_free() on the return value. + * + * Returns: (transfer full): a new tuple #GVariantType + * + * Since 2.24 + **/ +static GVariantType * +g_variant_type_new_tuple_slow (const GVariantType * const *items, + gint length) +{ + /* the "slow" version is needed in case the static buffer of 1024 + * bytes is exceeded when running the normal version. this will + * happen only in truly insane code, so it can be slow. + */ + GString *string; + gsize i; + + string = g_string_new ("("); + for (i = 0; i < length; i++) + { + const GVariantType *type; + gsize size; + + g_return_val_if_fail (g_variant_type_check (items[i]), NULL); + + type = items[i]; + size = g_variant_type_get_string_length (type); + g_string_append_len (string, (const gchar *) type, size); + } + g_string_append_c (string, ')'); + + return (GVariantType *) g_string_free (string, FALSE); +} + +GVariantType * +g_variant_type_new_tuple (const GVariantType * const *items, + gint length) +{ + char buffer[1024]; + gsize offset; + gsize i; + + g_return_val_if_fail (length == 0 || items != NULL, NULL); + + if (length < 0) + for (length = 0; items[length] != NULL; length++); + + offset = 0; + buffer[offset++] = '('; + + for (i = 0; i < length; i++) + { + const GVariantType *type; + gsize size; + + g_return_val_if_fail (g_variant_type_check (items[i]), NULL); + + type = items[i]; + size = g_variant_type_get_string_length (type); + + if (offset + size >= sizeof buffer) /* leave room for ')' */ + return g_variant_type_new_tuple_slow (items, length); + + memcpy (&buffer[offset], type, size); + offset += size; + } + + g_assert (offset < sizeof buffer); + buffer[offset++] = ')'; + + return (GVariantType *) g_memdup (buffer, offset); +} + +/** + * g_variant_type_new_array: + * @element: a #GVariantType + * + * Constructs the type corresponding to an array of elements of the + * type @type. + * + * It is appropriate to call g_variant_type_free() on the return value. + * + * Returns: (transfer full): a new array #GVariantType + * + * Since 2.24 + **/ +GVariantType * +g_variant_type_new_array (const GVariantType *element) +{ + gsize size; + gchar *new; + + g_return_val_if_fail (g_variant_type_check (element), NULL); + + size = g_variant_type_get_string_length (element); + new = g_malloc (size + 1); + + new[0] = 'a'; + memcpy (new + 1, element, size); + + return (GVariantType *) new; +} + +/** + * g_variant_type_new_maybe: + * @element: a #GVariantType + * + * Constructs the type corresponding to a maybe instance containing + * type @type or Nothing. + * + * It is appropriate to call g_variant_type_free() on the return value. + * + * Returns: (transfer full): a new maybe #GVariantType + * + * Since 2.24 + **/ +GVariantType * +g_variant_type_new_maybe (const GVariantType *element) +{ + gsize size; + gchar *new; + + g_return_val_if_fail (g_variant_type_check (element), NULL); + + size = g_variant_type_get_string_length (element); + new = g_malloc (size + 1); + + new[0] = 'm'; + memcpy (new + 1, element, size); + + return (GVariantType *) new; +} + +/** + * g_variant_type_new_dict_entry: + * @key: a basic #GVariantType + * @value: a #GVariantType + * + * Constructs the type corresponding to a dictionary entry with a key + * of type @key and a value of type @value. + * + * It is appropriate to call g_variant_type_free() on the return value. + * + * Returns: (transfer full): a new dictionary entry #GVariantType + * + * Since 2.24 + **/ +GVariantType * +g_variant_type_new_dict_entry (const GVariantType *key, + const GVariantType *value) +{ + gsize keysize, valsize; + gchar *new; + + g_return_val_if_fail (g_variant_type_check (key), NULL); + g_return_val_if_fail (g_variant_type_check (value), NULL); + + keysize = g_variant_type_get_string_length (key); + valsize = g_variant_type_get_string_length (value); + + new = g_malloc (1 + keysize + valsize + 1); + + new[0] = '{'; + memcpy (new + 1, key, keysize); + memcpy (new + 1 + keysize, value, valsize); + new[1 + keysize + valsize] = '}'; + + return (GVariantType *) new; +} + +/* private */ +const GVariantType * +g_variant_type_checked_ (const gchar *type_string) +{ + g_return_val_if_fail (g_variant_type_string_is_valid (type_string), NULL); + return (const GVariantType *) type_string; +} diff --git a/glib/glib/gvarianttype.h b/glib/glib/gvarianttype.h new file mode 100644 index 0000000..fe1ba84 --- /dev/null +++ b/glib/glib/gvarianttype.h @@ -0,0 +1,352 @@ +/* + * Copyright © 2007, 2008 Ryan Lortie + * Copyright © 2009, 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_VARIANT_TYPE_H__ +#define __G_VARIANT_TYPE_H__ + +#include +#include + +G_BEGIN_DECLS + +/** + * GVariantType: + * + * A type in the GVariant type system. + * + * Two types may not be compared by value; use g_variant_type_equal() or + * g_variant_type_is_subtype_of(). May be copied using + * g_variant_type_copy() and freed using g_variant_type_free(). + **/ +typedef struct _GVariantType GVariantType; + +/** + * G_VARIANT_TYPE_BOOLEAN: + * + * The type of a value that can be either %TRUE or %FALSE. + **/ +#define G_VARIANT_TYPE_BOOLEAN ((const GVariantType *) "b") + +/** + * G_VARIANT_TYPE_BYTE: + * + * The type of an integer value that can range from 0 to 255. + **/ +#define G_VARIANT_TYPE_BYTE ((const GVariantType *) "y") + +/** + * G_VARIANT_TYPE_INT16: + * + * The type of an integer value that can range from -32768 to 32767. + **/ +#define G_VARIANT_TYPE_INT16 ((const GVariantType *) "n") + +/** + * G_VARIANT_TYPE_UINT16: + * + * The type of an integer value that can range from 0 to 65535. + * There were about this many people living in Toronto in the 1870s. + **/ +#define G_VARIANT_TYPE_UINT16 ((const GVariantType *) "q") + +/** + * G_VARIANT_TYPE_INT32: + * + * The type of an integer value that can range from -2147483648 to + * 2147483647. + **/ +#define G_VARIANT_TYPE_INT32 ((const GVariantType *) "i") + +/** + * G_VARIANT_TYPE_UINT32: + * + * The type of an integer value that can range from 0 to 4294967295. + * That's one number for everyone who was around in the late 1970s. + **/ +#define G_VARIANT_TYPE_UINT32 ((const GVariantType *) "u") + +/** + * G_VARIANT_TYPE_INT64: + * + * The type of an integer value that can range from + * -9223372036854775808 to 9223372036854775807. + **/ +#define G_VARIANT_TYPE_INT64 ((const GVariantType *) "x") + +/** + * G_VARIANT_TYPE_UINT64: + * + * The type of an integer value that can range from 0 to + * 18446744073709551616. That's a really big number, but a Rubik's + * cube can have a bit more than twice as many possible positions. + **/ +#define G_VARIANT_TYPE_UINT64 ((const GVariantType *) "t") + +/** + * G_VARIANT_TYPE_DOUBLE: + * + * The type of a double precision IEEE754 floating point number. + * These guys go up to about 1.80e308 (plus and minus) but miss out on + * some numbers in between. In any case, that's far greater than the + * estimated number of fundamental particles in the observable + * universe. + **/ +#define G_VARIANT_TYPE_DOUBLE ((const GVariantType *) "d") + +/** + * G_VARIANT_TYPE_STRING: + * + * The type of a string. "" is a string. %NULL is not a string. + **/ +#define G_VARIANT_TYPE_STRING ((const GVariantType *) "s") + +/** + * G_VARIANT_TYPE_OBJECT_PATH: + * + * The type of a D-Bus object reference. These are strings of a + * specific format used to identify objects at a given destination on + * the bus. + * + * If you are not interacting with D-Bus, then there is no reason to make + * use of this type. If you are, then the D-Bus specification contains a + * precise description of valid object paths. + **/ +#define G_VARIANT_TYPE_OBJECT_PATH ((const GVariantType *) "o") + +/** + * G_VARIANT_TYPE_SIGNATURE: + * + * The type of a D-Bus type signature. These are strings of a specific + * format used as type signatures for D-Bus methods and messages. + * + * If you are not interacting with D-Bus, then there is no reason to make + * use of this type. If you are, then the D-Bus specification contains a + * precise description of valid signature strings. + **/ +#define G_VARIANT_TYPE_SIGNATURE ((const GVariantType *) "g") + +/** + * G_VARIANT_TYPE_VARIANT: + * + * The type of a box that contains any other value (including another + * variant). + **/ +#define G_VARIANT_TYPE_VARIANT ((const GVariantType *) "v") + +/** + * G_VARIANT_TYPE_HANDLE: + * + * The type of a 32bit signed integer value, that by convention, is used + * as an index into an array of file descriptors that are sent alongside + * a D-Bus message. + * + * If you are not interacting with D-Bus, then there is no reason to make + * use of this type. + **/ +#define G_VARIANT_TYPE_HANDLE ((const GVariantType *) "h") + +/** + * G_VARIANT_TYPE_UNIT: + * + * The empty tuple type. Has only one instance. Known also as "triv" + * or "void". + **/ +#define G_VARIANT_TYPE_UNIT ((const GVariantType *) "()") + +/** + * G_VARIANT_TYPE_ANY: + * + * An indefinite type that is a supertype of every type (including + * itself). + **/ +#define G_VARIANT_TYPE_ANY ((const GVariantType *) "*") + +/** + * G_VARIANT_TYPE_BASIC: + * + * An indefinite type that is a supertype of every basic (ie: + * non-container) type. + **/ +#define G_VARIANT_TYPE_BASIC ((const GVariantType *) "?") + +/** + * G_VARIANT_TYPE_MAYBE: + * + * An indefinite type that is a supertype of every maybe type. + **/ +#define G_VARIANT_TYPE_MAYBE ((const GVariantType *) "m*") + +/** + * G_VARIANT_TYPE_ARRAY: + * + * An indefinite type that is a supertype of every array type. + **/ +#define G_VARIANT_TYPE_ARRAY ((const GVariantType *) "a*") + +/** + * G_VARIANT_TYPE_TUPLE: + * + * An indefinite type that is a supertype of every tuple type, + * regardless of the number of items in the tuple. + **/ +#define G_VARIANT_TYPE_TUPLE ((const GVariantType *) "r") + +/** + * G_VARIANT_TYPE_DICT_ENTRY: + * + * An indefinite type that is a supertype of every dictionary entry + * type. + **/ +#define G_VARIANT_TYPE_DICT_ENTRY ((const GVariantType *) "{?*}") + +/** + * G_VARIANT_TYPE_DICTIONARY: + * + * An indefinite type that is a supertype of every dictionary type -- + * that is, any array type that has an element type equal to any + * dictionary entry type. + **/ +#define G_VARIANT_TYPE_DICTIONARY ((const GVariantType *) "a{?*}") + +/** + * G_VARIANT_TYPE_STRING_ARRAY: + * + * The type of an array of strings. + **/ +#define G_VARIANT_TYPE_STRING_ARRAY ((const GVariantType *) "as") + +/** + * G_VARIANT_TYPE_OBJECT_PATH_ARRAY: + * + * The type of an array of object paths. + **/ +#define G_VARIANT_TYPE_OBJECT_PATH_ARRAY ((const GVariantType *) "ao") + +/** + * G_VARIANT_TYPE_BYTESTRING: + * + * The type of an array of bytes. This type is commonly used to pass + * around strings that may not be valid utf8. In that case, the + * convention is that the nul terminator character should be included as + * the last character in the array. + **/ +#define G_VARIANT_TYPE_BYTESTRING ((const GVariantType *) "ay") + +/** + * G_VARIANT_TYPE_BYTESTRING_ARRAY: + * + * The type of an array of byte strings (an array of arrays of bytes). + **/ +#define G_VARIANT_TYPE_BYTESTRING_ARRAY ((const GVariantType *) "aay") + +/** + * G_VARIANT_TYPE_VARDICT: + * + * The type of a dictionary mapping strings to variants (the ubiquitous + * "a{sv}" type). + * + * Since: 2.30 + **/ +#define G_VARIANT_TYPE_VARDICT ((const GVariantType *) "a{sv}") + + +/** + * G_VARIANT_TYPE: + * @type_string: a well-formed #GVariantType type string + * + * Converts a string to a const #GVariantType. Depending on the + * current debugging level, this function may perform a runtime check + * to ensure that @string is a valid GVariant type string. + * + * It is always a programmer error to use this macro with an invalid + * type string. If in doubt, use g_variant_type_string_is_valid() to + * check if the string is valid. + * + * Since 2.24 + **/ +#ifndef G_DISABLE_CHECKS +# define G_VARIANT_TYPE(type_string) (g_variant_type_checked_ ((type_string))) +#else +# define G_VARIANT_TYPE(type_string) ((const GVariantType *) (type_string)) +#endif + +/* type string checking */ +gboolean g_variant_type_string_is_valid (const gchar *type_string); +gboolean g_variant_type_string_scan (const gchar *string, + const gchar *limit, + const gchar **endptr); + +/* create/destroy */ +void g_variant_type_free (GVariantType *type); +GVariantType * g_variant_type_copy (const GVariantType *type); +GVariantType * g_variant_type_new (const gchar *type_string); + +/* getters */ +gsize g_variant_type_get_string_length (const GVariantType *type); +const gchar * g_variant_type_peek_string (const GVariantType *type); +gchar * g_variant_type_dup_string (const GVariantType *type); + +/* classification */ +gboolean g_variant_type_is_definite (const GVariantType *type); +gboolean g_variant_type_is_container (const GVariantType *type); +gboolean g_variant_type_is_basic (const GVariantType *type); +gboolean g_variant_type_is_maybe (const GVariantType *type); +gboolean g_variant_type_is_array (const GVariantType *type); +gboolean g_variant_type_is_tuple (const GVariantType *type); +gboolean g_variant_type_is_dict_entry (const GVariantType *type); +gboolean g_variant_type_is_variant (const GVariantType *type); + +/* for hash tables */ +guint g_variant_type_hash (gconstpointer type); +gboolean g_variant_type_equal (gconstpointer type1, + gconstpointer type2); + +/* subtypes */ +gboolean g_variant_type_is_subtype_of (const GVariantType *type, + const GVariantType *supertype); + +/* type iterator interface */ +const GVariantType * g_variant_type_element (const GVariantType *type); +const GVariantType * g_variant_type_first (const GVariantType *type); +const GVariantType * g_variant_type_next (const GVariantType *type); +gsize g_variant_type_n_items (const GVariantType *type); +const GVariantType * g_variant_type_key (const GVariantType *type); +const GVariantType * g_variant_type_value (const GVariantType *type); + +/* constructors */ +GVariantType * g_variant_type_new_array (const GVariantType *element); +GVariantType * g_variant_type_new_maybe (const GVariantType *element); +GVariantType * g_variant_type_new_tuple (const GVariantType * const *items, + gint length); +GVariantType * g_variant_type_new_dict_entry (const GVariantType *key, + const GVariantType *value); + +/*< private >*/ +const GVariantType * g_variant_type_checked_ (const gchar *); + +G_END_DECLS + +#endif /* __G_VARIANT_TYPE_H__ */ diff --git a/glib/glib/gvarianttypeinfo.c b/glib/glib/gvarianttypeinfo.c new file mode 100644 index 0000000..0c380ce --- /dev/null +++ b/glib/glib/gvarianttypeinfo.c @@ -0,0 +1,869 @@ +/* + * Copyright © 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#include "config.h" + +#include "gvarianttypeinfo.h" + +#include +#include +#include +#include + +/* < private > + * GVariantTypeInfo: + * + * This structure contains the necessary information to facilitate the + * serialisation and fast deserialisation of a given type of GVariant + * value. A GVariant instance holds a pointer to one of these + * structures to provide for efficient operation. + * + * The GVariantTypeInfo structures for all of the base types, plus the + * "variant" type are stored in a read-only static array. + * + * For container types, a hash table and reference counting is used to + * ensure that only one of these structures exists for any given type. + * In general, a container GVariantTypeInfo will exist for a given type + * only if one or more GVariant instances of that type exist or if + * another GVariantTypeInfo has that type as a subtype. For example, if + * a process contains a single GVariant instance with type "(asv)", then + * container GVariantTypeInfo structures will exist for "(asv)" and + * for "as" (note that "s" and "v" always exist in the static array). + * + * The trickiest part of GVariantTypeInfo (and in fact, the major reason + * for its existence) is the storage of somewhat magical constants that + * allow for O(1) lookups of items in tuples. This is described below. + * + * 'container_class' is set to 'a' or 'r' if the GVariantTypeInfo is + * contained inside of an ArrayInfo or TupleInfo, respectively. This + * allows the storage of the necessary additional information. + * + * 'fixed_size' is set to the fixed size of the type, if applicable, or + * 0 otherwise (since no type has a fixed size of 0). + * + * 'alignment' is set to one less than the alignment requirement for + * this type. This makes many operations much more convenient. + */ +struct _GVariantTypeInfo +{ + gsize fixed_size; + guchar alignment; + guchar container_class; +}; + +/* Container types are reference counted. They also need to have their + * type string stored explicitly since it is not merely a single letter. + */ +typedef struct +{ + GVariantTypeInfo info; + + gchar *type_string; + gint ref_count; +} ContainerInfo; + +/* For 'array' and 'maybe' types, we store some extra information on the + * end of the GVariantTypeInfo struct -- the element type (ie: "s" for + * "as"). The container GVariantTypeInfo structure holds a reference to + * the element typeinfo. + */ +typedef struct +{ + ContainerInfo container; + + GVariantTypeInfo *element; +} ArrayInfo; + +/* For 'tuple' and 'dict entry' types, we store extra information for + * each member -- its type and how to find it inside the serialised data + * in O(1) time using 4 variables -- 'i', 'a', 'b', and 'c'. See the + * comment on GVariantMemberInfo in gvarianttypeinfo.h. + */ +typedef struct +{ + ContainerInfo container; + + GVariantMemberInfo *members; + gsize n_members; +} TupleInfo; + + +/* Hard-code the base types in a constant array */ +static const GVariantTypeInfo g_variant_type_info_basic_table[24] = { +#define fixed_aligned(x) x, x - 1 +#define not_a_type 0, +#define unaligned 0, 0 +#define aligned(x) 0, x - 1 + /* 'b' */ { fixed_aligned(1) }, /* boolean */ + /* 'c' */ { not_a_type }, + /* 'd' */ { fixed_aligned(8) }, /* double */ + /* 'e' */ { not_a_type }, + /* 'f' */ { not_a_type }, + /* 'g' */ { unaligned }, /* signature string */ + /* 'h' */ { fixed_aligned(4) }, /* file handle (int32) */ + /* 'i' */ { fixed_aligned(4) }, /* int32 */ + /* 'j' */ { not_a_type }, + /* 'k' */ { not_a_type }, + /* 'l' */ { not_a_type }, + /* 'm' */ { not_a_type }, + /* 'n' */ { fixed_aligned(2) }, /* int16 */ + /* 'o' */ { unaligned }, /* object path string */ + /* 'p' */ { not_a_type }, + /* 'q' */ { fixed_aligned(2) }, /* uint16 */ + /* 'r' */ { not_a_type }, + /* 's' */ { unaligned }, /* string */ + /* 't' */ { fixed_aligned(8) }, /* uint64 */ + /* 'u' */ { fixed_aligned(4) }, /* uint32 */ + /* 'v' */ { aligned(8) }, /* variant */ + /* 'w' */ { not_a_type }, + /* 'x' */ { fixed_aligned(8) }, /* int64 */ + /* 'y' */ { fixed_aligned(1) }, /* byte */ +#undef fixed_aligned +#undef not_a_type +#undef unaligned +#undef aligned +}; + +/* We need to have type strings to return for the base types. We store + * those in another array. Since all base type strings are single + * characters this is easy. By not storing pointers to strings into the + * GVariantTypeInfo itself, we save a bunch of relocations. + */ +static const char g_variant_type_info_basic_chars[24][2] = { + "b", " ", "d", " ", " ", "g", "h", "i", " ", " ", " ", " ", + "n", "o", " ", "q", " ", "s", "t", "u", "v", " ", "x", "y" +}; + +/* sanity checks to make debugging easier */ +static void +g_variant_type_info_check (const GVariantTypeInfo *info, + char container_class) +{ + g_assert (!container_class || info->container_class == container_class); + + /* alignment can only be one of these */ + g_assert (info->alignment == 0 || info->alignment == 1 || + info->alignment == 3 || info->alignment == 7); + + if (info->container_class) + { + ContainerInfo *container = (ContainerInfo *) info; + + /* extra checks for containers */ + g_assert_cmpint (container->ref_count, >, 0); + g_assert (container->type_string != NULL); + } + else + { + gint index; + + /* if not a container, then ensure that it is a valid member of + * the basic types table + */ + index = info - g_variant_type_info_basic_table; + + g_assert (G_N_ELEMENTS (g_variant_type_info_basic_table) == 24); + g_assert (G_N_ELEMENTS (g_variant_type_info_basic_chars) == 24); + g_assert (0 <= index && index < 24); + g_assert (g_variant_type_info_basic_chars[index][0] != ' '); + } +} + +/* < private > + * g_variant_type_info_get_type_string: + * @info: a #GVariantTypeInfo + * + * Gets the type string for @info. The string is nul-terminated. + */ +const gchar * +g_variant_type_info_get_type_string (GVariantTypeInfo *info) +{ + g_variant_type_info_check (info, 0); + + if (info->container_class) + { + ContainerInfo *container = (ContainerInfo *) info; + + /* containers have their type string stored inside them */ + return container->type_string; + } + else + { + gint index; + + /* look up the type string in the base type array. the call to + * g_variant_type_info_check() above already ensured validity. + */ + index = info - g_variant_type_info_basic_table; + + return g_variant_type_info_basic_chars[index]; + } +} + +/* < private > + * g_variant_type_info_query: + * @info: a #GVariantTypeInfo + * @alignment: the location to store the alignment, or %NULL + * @fixed_size: the location to store the fixed size, or %NULL + * + * Queries @info to determine the alignment requirements and fixed size + * (if any) of the type. + * + * @fixed_size, if non-%NULL is set to the fixed size of the type, or 0 + * to indicate that the type is a variable-sized type. No type has a + * fixed size of 0. + * + * @alignment, if non-%NULL, is set to one less than the required + * alignment of the type. For example, for a 32bit integer, @alignment + * would be set to 3. This allows you to round an integer up to the + * proper alignment by performing the following efficient calculation: + * + * offset += ((-offset) & alignment); + */ +void +g_variant_type_info_query (GVariantTypeInfo *info, + guint *alignment, + gsize *fixed_size) +{ + g_variant_type_info_check (info, 0); + + if (alignment) + *alignment = info->alignment; + + if (fixed_size) + *fixed_size = info->fixed_size; +} + +/* == array == */ +#define GV_ARRAY_INFO_CLASS 'a' +static ArrayInfo * +GV_ARRAY_INFO (GVariantTypeInfo *info) +{ + g_variant_type_info_check (info, GV_ARRAY_INFO_CLASS); + + return (ArrayInfo *) info; +} + +static void +array_info_free (GVariantTypeInfo *info) +{ + ArrayInfo *array_info; + + g_assert (info->container_class == GV_ARRAY_INFO_CLASS); + array_info = (ArrayInfo *) info; + + g_variant_type_info_unref (array_info->element); + g_slice_free (ArrayInfo, array_info); +} + +static ContainerInfo * +array_info_new (const GVariantType *type) +{ + ArrayInfo *info; + + info = g_slice_new (ArrayInfo); + info->container.info.container_class = GV_ARRAY_INFO_CLASS; + + info->element = g_variant_type_info_get (g_variant_type_element (type)); + info->container.info.alignment = info->element->alignment; + info->container.info.fixed_size = 0; + + return (ContainerInfo *) info; +} + +/* < private > + * g_variant_type_info_element: + * @info: a #GVariantTypeInfo for an array or maybe type + * + * Returns the element type for the array or maybe type. A reference is + * not added, so the caller must add their own. + */ +GVariantTypeInfo * +g_variant_type_info_element (GVariantTypeInfo *info) +{ + return GV_ARRAY_INFO (info)->element; +} + +/* < private > + * g_variant_type_query_element: + * @info: a #GVariantTypeInfo for an array or maybe type + * @alignment: the location to store the alignment, or %NULL + * @fixed_size: the location to store the fixed size, or %NULL + * + * Returns the alignment requires and fixed size (if any) for the + * element type of the array. This call is a convenience wrapper around + * g_variant_type_info_element() and g_variant_type_info_query(). + */ +void +g_variant_type_info_query_element (GVariantTypeInfo *info, + guint *alignment, + gsize *fixed_size) +{ + g_variant_type_info_query (GV_ARRAY_INFO (info)->element, + alignment, fixed_size); +} + +/* == tuple == */ +#define GV_TUPLE_INFO_CLASS 'r' +static TupleInfo * +GV_TUPLE_INFO (GVariantTypeInfo *info) +{ + g_variant_type_info_check (info, GV_TUPLE_INFO_CLASS); + + return (TupleInfo *) info; +} + +static void +tuple_info_free (GVariantTypeInfo *info) +{ + TupleInfo *tuple_info; + gint i; + + g_assert (info->container_class == GV_TUPLE_INFO_CLASS); + tuple_info = (TupleInfo *) info; + + for (i = 0; i < tuple_info->n_members; i++) + g_variant_type_info_unref (tuple_info->members[i].type_info); + + g_slice_free1 (sizeof (GVariantMemberInfo) * tuple_info->n_members, + tuple_info->members); + g_slice_free (TupleInfo, tuple_info); +} + +static void +tuple_allocate_members (const GVariantType *type, + GVariantMemberInfo **members, + gsize *n_members) +{ + const GVariantType *item_type; + gsize i = 0; + + *n_members = g_variant_type_n_items (type); + *members = g_slice_alloc (sizeof (GVariantMemberInfo) * *n_members); + + item_type = g_variant_type_first (type); + while (item_type) + { + GVariantMemberInfo *member = &(*members)[i++]; + + member->type_info = g_variant_type_info_get (item_type); + item_type = g_variant_type_next (item_type); + + if (member->type_info->fixed_size) + member->ending_type = G_VARIANT_MEMBER_ENDING_FIXED; + else if (item_type == NULL) + member->ending_type = G_VARIANT_MEMBER_ENDING_LAST; + else + member->ending_type = G_VARIANT_MEMBER_ENDING_OFFSET; + } + + g_assert (i == *n_members); +} + +/* this is g_variant_type_info_query for a given member of the tuple. + * before the access is done, it is ensured that the item is within + * range and %FALSE is returned if not. + */ +static gboolean +tuple_get_item (TupleInfo *info, + GVariantMemberInfo *item, + gsize *d, + gsize *e) +{ + if (&info->members[info->n_members] == item) + return FALSE; + + *d = item->type_info->alignment; + *e = item->type_info->fixed_size; + return TRUE; +} + +/* Read the documentation for #GVariantMemberInfo in gvarianttype.h + * before attempting to understand this. + * + * This function adds one set of "magic constant" values (for one item + * in the tuple) to the table. + * + * The algorithm in tuple_generate_table() calculates values of 'a', 'b' + * and 'c' for each item, such that the procedure for finding the item + * is to start at the end of the previous variable-sized item, add 'a', + * then round up to the nearest multiple of 'b', then then add 'c'. + * Note that 'b' is stored in the usual "one less than" form. ie: + * + * start = ROUND_UP(prev_end + a, (b + 1)) + c; + * + * We tweak these values a little to allow for a slightly easier + * computation and more compact storage. + */ +static void +tuple_table_append (GVariantMemberInfo **items, + gsize i, + gsize a, + gsize b, + gsize c) +{ + GVariantMemberInfo *item = (*items)++; + + /* We can shift multiples of the alignment size from 'c' into 'a'. + * As long as we're shifting whole multiples, it won't affect the + * result. This means that we can take the "aligned" portion off of + * 'c' and add it into 'a'. + * + * Imagine (for sake of clarity) that ROUND_10 rounds up to the + * nearest 10. It is clear that: + * + * ROUND_10(a) + c == ROUND_10(a + 10*(c / 10)) + (c % 10) + * + * ie: remove the 10s portion of 'c' and add it onto 'a'. + * + * To put some numbers on it, imagine we start with a = 34 and c = 27: + * + * ROUND_10(34) + 27 = 40 + 27 = 67 + * + * but also, we can split 27 up into 20 and 7 and do this: + * + * ROUND_10(34 + 20) + 7 = ROUND_10(54) + 7 = 60 + 7 = 67 + * ^^ ^ + * without affecting the result. We do that here. + * + * This reduction in the size of 'c' means that we can store it in a + * gchar instead of a gsize. Due to how the structure is packed, this + * ends up saving us 'two pointer sizes' per item in each tuple when + * allocating using GSlice. + */ + a += ~b & c; /* take the "aligned" part of 'c' and add to 'a' */ + c &= b; /* chop 'c' to contain only the unaligned part */ + + + /* Finally, we made one last adjustment. Recall: + * + * start = ROUND_UP(prev_end + a, (b + 1)) + c; + * + * Forgetting the '+ c' for the moment: + * + * ROUND_UP(prev_end + a, (b + 1)); + * + * we can do a "round up" operation by adding 1 less than the amount + * to round up to, then rounding down. ie: + * + * #define ROUND_UP(x, y) ROUND_DOWN(x + (y-1), y) + * + * Of course, for rounding down to a power of two, we can just mask + * out the appropriate number of low order bits: + * + * #define ROUND_DOWN(x, y) (x & ~(y - 1)) + * + * Which gives us + * + * #define ROUND_UP(x, y) (x + (y - 1) & ~(y - 1)) + * + * but recall that our alignment value 'b' is already "one less". + * This means that to round 'prev_end + a' up to 'b' we can just do: + * + * ((prev_end + a) + b) & ~b + * + * Associativity, and putting the 'c' back on: + * + * (prev_end + (a + b)) & ~b + c + * + * Now, since (a + b) is constant, we can just add 'b' to 'a' now and + * store that as the number to add to prev_end. Then we use ~b as the + * number to take a bitwise 'and' with. Finally, 'c' is added on. + * + * Note, however, that all the low order bits of the 'aligned' value + * are masked out and that all of the high order bits of 'c' have been + * "moved" to 'a' (in the previous step). This means that there are + * no overlapping bits in the addition -- so we can do a bitwise 'or' + * equivalently. + * + * This means that we can now compute the start address of a given + * item in the tuple using the algorithm given in the documentation + * for #GVariantMemberInfo: + * + * item_start = ((prev_end + a) & b) | c; + */ + + item->i = i; + item->a = a + b; + item->b = ~b; + item->c = c; +} + +static gsize +tuple_align (gsize offset, + guint alignment) +{ + return offset + ((-offset) & alignment); +} + +/* This function is the heart of the algorithm for calculating 'i', 'a', + * 'b' and 'c' for each item in the tuple. + * + * Imagine we want to find the start of the "i" in the type "(su(qx)ni)". + * That's a string followed by a uint32, then a tuple containing a + * uint16 and a int64, then an int16, then our "i". In order to get to + * our "i" we: + * + * Start at the end of the string, align to 4 (for the uint32), add 4. + * Align to 8, add 16 (for the tuple). Align to 2, add 2 (for the + * int16). Then we're there. It turns out that, given 3 simple rules, + * we can flatten this iteration into one addition, one alignment, then + * one more addition. + * + * The loop below plays through each item in the tuple, querying its + * alignment and fixed_size into 'd' and 'e', respectively. At all + * times the variables 'a', 'b', and 'c' are maintained such that in + * order to get to the current point, you add 'a', align to 'b' then add + * 'c'. 'b' is kept in "one less than" form. For each item, the proper + * alignment is applied to find the values of 'a', 'b' and 'c' to get to + * the start of that item. Those values are recorded into the table. + * The fixed size of the item (if applicable) is then added on. + * + * These 3 rules are how 'a', 'b' and 'c' are modified for alignment and + * addition of fixed size. They have been proven correct but are + * presented here, without proof: + * + * 1) in order to "align to 'd'" where 'd' is less than or equal to the + * largest level of alignment seen so far ('b'), you align 'c' to + * 'd'. + * 2) in order to "align to 'd'" where 'd' is greater than the largest + * level of alignment seen so far, you add 'c' aligned to 'b' to the + * value of 'a', set 'b' to 'd' (ie: increase the 'largest alignment + * seen') and reset 'c' to 0. + * 3) in order to "add 'e'", just add 'e' to 'c'. + */ +static void +tuple_generate_table (TupleInfo *info) +{ + GVariantMemberInfo *items = info->members; + gsize i = -1, a = 0, b = 0, c = 0, d, e; + + /* iterate over each item in the tuple. + * 'd' will be the alignment of the item (in one-less form) + * 'e' will be the fixed size (or 0 for variable-size items) + */ + while (tuple_get_item (info, items, &d, &e)) + { + /* align to 'd' */ + if (d <= b) + c = tuple_align (c, d); /* rule 1 */ + else + a += tuple_align (c, b), b = d, c = 0; /* rule 2 */ + + /* the start of the item is at this point (ie: right after we + * have aligned for it). store this information in the table. + */ + tuple_table_append (&items, i, a, b, c); + + /* "move past" the item by adding in its size. */ + if (e == 0) + /* variable size: + * + * we'll have an offset stored to mark the end of this item, so + * just bump the offset index to give us a new starting point + * and reset all the counters. + */ + i++, a = b = c = 0; + else + /* fixed size */ + c += e; /* rule 3 */ + } +} + +static void +tuple_set_base_info (TupleInfo *info) +{ + GVariantTypeInfo *base = &info->container.info; + + if (info->n_members > 0) + { + GVariantMemberInfo *m; + + /* the alignment requirement of the tuple is the alignment + * requirement of its largest item. + */ + base->alignment = 0; + for (m = info->members; m < &info->members[info->n_members]; m++) + /* can find the max of a list of "one less than" powers of two + * by 'or'ing them + */ + base->alignment |= m->type_info->alignment; + + m--; /* take 'm' back to the last item */ + + /* the structure only has a fixed size if no variable-size + * offsets are stored and the last item is fixed-sized too (since + * an offset is never stored for the last item). + */ + if (m->i == -1 && m->type_info->fixed_size) + /* in that case, the fixed size can be found by finding the + * start of the last item (in the usual way) and adding its + * fixed size. + * + * if a tuple has a fixed size then it is always a multiple of + * the alignment requirement (to make packing into arrays + * easier) so we round up to that here. + */ + base->fixed_size = + tuple_align (((m->a & m->b) | m->c) + m->type_info->fixed_size, + base->alignment); + else + /* else, the tuple is not fixed size */ + base->fixed_size = 0; + } + else + { + /* the empty tuple: '()'. + * + * has a size of 1 and an no alignment requirement. + * + * It has a size of 1 (not 0) for two practical reasons: + * + * 1) So we can determine how many of them are in an array + * without dividing by zero or without other tricks. + * + * 2) Even if we had some trick to know the number of items in + * the array (as GVariant did at one time) this would open a + * potential denial of service attack: an attacker could send + * you an extremely small array (in terms of number of bytes) + * containing trillions of zero-sized items. If you iterated + * over this array you would effectively infinite-loop your + * program. By forcing a size of at least one, we bound the + * amount of computation done in response to a message to a + * reasonable function of the size of that message. + */ + base->alignment = 0; + base->fixed_size = 1; + } +} + +static ContainerInfo * +tuple_info_new (const GVariantType *type) +{ + TupleInfo *info; + + info = g_slice_new (TupleInfo); + info->container.info.container_class = GV_TUPLE_INFO_CLASS; + + tuple_allocate_members (type, &info->members, &info->n_members); + tuple_generate_table (info); + tuple_set_base_info (info); + + return (ContainerInfo *) info; +} + +/* < private > + * g_variant_type_info_n_members: + * @info: a #GVariantTypeInfo for a tuple or dictionary entry type + * + * Returns the number of members in a tuple or dictionary entry type. + * For a dictionary entry this will always be 2. + */ +gsize +g_variant_type_info_n_members (GVariantTypeInfo *info) +{ + return GV_TUPLE_INFO (info)->n_members; +} + +/* < private > + * g_variant_type_info_member_info: + * @info: a #GVariantTypeInfo for a tuple or dictionary entry type + * @index: the member to fetch information for + * + * Returns the #GVariantMemberInfo for a given member. See + * documentation for that structure for why you would want this + * information. + * + * @index must refer to a valid child (ie: strictly less than + * g_variant_type_info_n_members() returns). + */ +const GVariantMemberInfo * +g_variant_type_info_member_info (GVariantTypeInfo *info, + gsize index) +{ + TupleInfo *tuple_info = GV_TUPLE_INFO (info); + + if (index < tuple_info->n_members) + return &tuple_info->members[index]; + + return NULL; +} + +/* == new/ref/unref == */ +static GRecMutex g_variant_type_info_lock; +static GHashTable *g_variant_type_info_table; + +/* < private > + * g_variant_type_info_get: + * @type: a #GVariantType + * + * Returns a reference to a #GVariantTypeInfo for @type. + * + * If an info structure already exists for this type, a new reference is + * returned. If not, the required calculations are performed and a new + * info structure is returned. + * + * It is appropriate to call g_variant_type_info_unref() on the return + * value. + */ +GVariantTypeInfo * +g_variant_type_info_get (const GVariantType *type) +{ + char type_char; + + type_char = g_variant_type_peek_string (type)[0]; + + if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE || + type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY || + type_char == G_VARIANT_TYPE_INFO_CHAR_TUPLE || + type_char == G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY) + { + GVariantTypeInfo *info; + gchar *type_string; + + type_string = g_variant_type_dup_string (type); + + g_rec_mutex_lock (&g_variant_type_info_lock); + + if (g_variant_type_info_table == NULL) + g_variant_type_info_table = g_hash_table_new (g_str_hash, + g_str_equal); + info = g_hash_table_lookup (g_variant_type_info_table, type_string); + + if (info == NULL) + { + ContainerInfo *container; + + if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE || + type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY) + { + container = array_info_new (type); + } + else /* tuple or dict entry */ + { + container = tuple_info_new (type); + } + + info = (GVariantTypeInfo *) container; + container->type_string = type_string; + container->ref_count = 1; + + g_hash_table_insert (g_variant_type_info_table, type_string, info); + type_string = NULL; + } + else + g_variant_type_info_ref (info); + + g_rec_mutex_unlock (&g_variant_type_info_lock); + g_variant_type_info_check (info, 0); + g_free (type_string); + + return info; + } + else + { + const GVariantTypeInfo *info; + int index; + + index = type_char - 'b'; + g_assert (G_N_ELEMENTS (g_variant_type_info_basic_table) == 24); + g_assert_cmpint (0, <=, index); + g_assert_cmpint (index, <, 24); + + info = g_variant_type_info_basic_table + index; + g_variant_type_info_check (info, 0); + + return (GVariantTypeInfo *) info; + } +} + +/* < private > + * g_variant_type_info_ref: + * @info: a #GVariantTypeInfo + * + * Adds a reference to @info. + */ +GVariantTypeInfo * +g_variant_type_info_ref (GVariantTypeInfo *info) +{ + g_variant_type_info_check (info, 0); + + if (info->container_class) + { + ContainerInfo *container = (ContainerInfo *) info; + + g_assert_cmpint (container->ref_count, >, 0); + g_atomic_int_inc (&container->ref_count); + } + + return info; +} + +/* < private > + * g_variant_type_info_unref: + * @info: a #GVariantTypeInfo + * + * Releases a reference held on @info. This may result in @info being + * freed. + */ +void +g_variant_type_info_unref (GVariantTypeInfo *info) +{ + g_variant_type_info_check (info, 0); + + if (info->container_class) + { + ContainerInfo *container = (ContainerInfo *) info; + + g_rec_mutex_lock (&g_variant_type_info_lock); + if (g_atomic_int_dec_and_test (&container->ref_count)) + { + g_hash_table_remove (g_variant_type_info_table, + container->type_string); + if (g_hash_table_size (g_variant_type_info_table) == 0) + { + g_hash_table_unref (g_variant_type_info_table); + g_variant_type_info_table = NULL; + } + g_rec_mutex_unlock (&g_variant_type_info_lock); + + g_free (container->type_string); + + if (info->container_class == GV_ARRAY_INFO_CLASS) + array_info_free (info); + + else if (info->container_class == GV_TUPLE_INFO_CLASS) + tuple_info_free (info); + + else + g_assert_not_reached (); + } + else + g_rec_mutex_unlock (&g_variant_type_info_lock); + } +} + +void +g_variant_type_info_assert_no_infos (void) +{ + g_assert (g_variant_type_info_table == NULL); +} diff --git a/glib/glib/gvarianttypeinfo.h b/glib/glib/gvarianttypeinfo.h new file mode 100644 index 0000000..aaf14f4 --- /dev/null +++ b/glib/glib/gvarianttypeinfo.h @@ -0,0 +1,151 @@ +/* + * Copyright © 2008 Ryan Lortie + * Copyright © 2010 Codethink Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#ifndef __G_VARIANT_TYPE_INFO_H__ +#define __G_VARIANT_TYPE_INFO_H__ + +#include + +#define G_VARIANT_TYPE_INFO_CHAR_MAYBE 'm' +#define G_VARIANT_TYPE_INFO_CHAR_ARRAY 'a' +#define G_VARIANT_TYPE_INFO_CHAR_TUPLE '(' +#define G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY '{' +#define G_VARIANT_TYPE_INFO_CHAR_VARIANT 'v' +#define g_variant_type_info_get_type_char(info) \ + (g_variant_type_info_get_type_string(info)[0]) + +typedef struct _GVariantTypeInfo GVariantTypeInfo; + +/* < private > + * GVariantMemberInfo: + * + * This structure describes how to construct a GVariant instance + * corresponding to a given child of a tuple or dictionary entry in a + * very short constant time. It contains the typeinfo of the child, + * along with 4 constants that allow the bounds of the child's + * serialised data within the container's serialised data to be found + * very efficiently. + * + * Since dictionary entries are serialised as if they were tuples of 2 + * items, the term "tuple" will be used here in the general sense to + * refer to tuples and dictionary entries. + * + * BACKGROUND: + * The serialised data for a tuple contains an array of "offsets" at + * the end. There is one "offset" in this array for each + * variable-sized item in the tuple (except for the last one). The + * offset points to the end point of that item's serialised data. The + * procedure for finding the start point is described below. An + * offset is not needed for the last item because the end point of the + * last item is merely the end point of the container itself (after + * the offsets array has been accounted for). An offset is not needed + * for fixed-sized items (like integers) because, due to their fixed + * size, the end point is a constant addition to the start point. + * + * It is clear that the starting point of a given item in the tuple is + * determined by the items that precede it in the tuple. Logically, + * the start point of a particular item in a given type of tuple can + * be determined entirely by the end point of the nearest + * variable-sized item that came before it (or from the start of the + * container itself in case there is no preceding variable-sized + * item). In the case of "(isis)" for example, in order to find out + * the start point of the last string, one must start at the end point + * of the first string, align to 4 (for the integer's alignment) and + * then add 4 (for storing the integer). That's the point where the + * string starts (since no special alignment is required for strings). + * + * Of course, this process requires iterating over the types in the + * tuple up to the item of interest. As it turns out, it is possible + * to determine 3 constants 'a', 'b', and 'c' for each item in the + * tuple, such that, given the ending offset of the nearest previous + * variable-sized item (prev_end), a very simple calculation can be + * performed to determine the start of the item of interest. + * + * The constants in this structure are used as follows: + * + * First, among the array of offets contained in the tuple, 'i' is the + * index of the offset that refers to the end of the variable-sized item + * preceding the item of interest. If no variable-sized items precede + * this item, then 'i' will be -1. + * + * Let 'prev_end' be the end offset of the previous item (or 0 in the + * case that there was no such item). The start address of this item + * can then be calculate using 'a', 'b', and 'c': + * + * item_start = ((prev_end + a) & b) | c; + * + * For details about how 'a', 'b' and 'c' are calculated, see the + * comments at the point of the implementation in gvariantypeinfo.c. + * + * The end address of the item is then determined in one of three ways, + * according to the 'end_type' field. + * + * - FIXED: For fixed sized items, the end address is equal to the + * start address plus the fixed size. + * + * - LAST: For the last variable sized item in the tuple, the end + * address is equal to the end address of the tuple, minus the size + * of the offset array. + * + * - OFFSET: For other variable sized items, the next index past 'i' + * (ie: 'i + 1') must be consulted to find the end of this item. + */ + +typedef struct +{ + GVariantTypeInfo *type_info; + + gsize i, a; + gint8 b, c; + + guint8 ending_type; +} GVariantMemberInfo; + +#define G_VARIANT_MEMBER_ENDING_FIXED 0 +#define G_VARIANT_MEMBER_ENDING_LAST 1 +#define G_VARIANT_MEMBER_ENDING_OFFSET 2 + +/* query */ +const gchar * g_variant_type_info_get_type_string (GVariantTypeInfo *typeinfo); + +void g_variant_type_info_query (GVariantTypeInfo *typeinfo, + guint *alignment, + gsize *size); + +/* array */ +GVariantTypeInfo * g_variant_type_info_element (GVariantTypeInfo *typeinfo); +void g_variant_type_info_query_element (GVariantTypeInfo *typeinfo, + guint *alignment, + gsize *size); + +/* structure */ +gsize g_variant_type_info_n_members (GVariantTypeInfo *typeinfo); +const GVariantMemberInfo * g_variant_type_info_member_info (GVariantTypeInfo *typeinfo, + gsize index); + +/* new/ref/unref */ +GVariantTypeInfo * g_variant_type_info_get (const GVariantType *type); +GVariantTypeInfo * g_variant_type_info_ref (GVariantTypeInfo *typeinfo); +void g_variant_type_info_unref (GVariantTypeInfo *typeinfo); +void g_variant_type_info_assert_no_infos (void); + +#endif /* __G_VARIANT_TYPE_INFO_H__ */ diff --git a/glib/glib/gversion.c b/glib/glib/gversion.c new file mode 100644 index 0000000..70650b3 --- /dev/null +++ b/glib/glib/gversion.c @@ -0,0 +1,157 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#include "config.h" + +#include "gversion.h" + +/** + * SECTION:version + * @Title: Version Information + * @Short_description: variables and functions to check the GLib version + * + * GLib provides version information, primarily useful in configure + * checks for builds that have a configure script. Applications will + * not typically use the features described here. + * + * The GLib headers annotate deprecated APIs in a way that produces + * compiler warnings if these deprecated APIs are used. The warnings + * can be turned off by defining the macro %GLIB_DISABLE_DEPRECATION_WARNINGS + * before including the glib.h header. + * + * GLib also provides support for building applications against + * defined subsets of deprecated or new GLib APIs. Define the macro + * %GLIB_VERSION_MIN_REQUIRED to specify up to what version of GLib + * you want to receive warnings about deprecated APIs. Define the + * macro %GLIB_VERSION_MAX_ALLOWED to specify the newest version of + * GLib whose API you want to use. + */ + +/** + * GLIB_MAJOR_VERSION: + * + * The major version number of the GLib library. + * + * Like #glib_major_version, but from the headers used at + * application compile time, rather than from the library + * linked against at application run time. + */ + +/** + * GLIB_MINOR_VERSION: + * + * The minor version number of the GLib library. + * + * Like #gtk_minor_version, but from the headers used at + * application compile time, rather than from the library + * linked against at application run time. + */ + +/** + * GLIB_MICRO_VERSION: + * + * The micro version number of the GLib library. + * + * Like #gtk_micro_version, but from the headers used at + * application compile time, rather than from the library + * linked against at application run time. + */ + +/** + * GLIB_CHECK_VERSION: + * @major: the major version to check for + * @minor: the minor version to check for + * @micro: the micro version to check for + * + * Checks the version of the GLib library that is being compiled + * against. + * + * + * Checking the version of the GLib library + * + * if (!GLIB_CHECK_VERSION (1, 2, 0)) + * g_error ("GLib version 1.2.0 or above is needed"); + * + * + * + * See glib_check_version() for a runtime check. + * + * Returns: %TRUE if the version of the GLib header files + * is the same as or newer than the passed-in version. + */ + +const guint glib_major_version = GLIB_MAJOR_VERSION; +const guint glib_minor_version = GLIB_MINOR_VERSION; +const guint glib_micro_version = GLIB_MICRO_VERSION; +const guint glib_interface_age = GLIB_INTERFACE_AGE; +const guint glib_binary_age = GLIB_BINARY_AGE; + +/** + * glib_check_version: + * @required_major: the required major version. + * @required_minor: the required minor version. + * @required_micro: the required micro version. + * + * Checks that the GLib library in use is compatible with the + * given version. Generally you would pass in the constants + * #GLIB_MAJOR_VERSION, #GLIB_MINOR_VERSION, #GLIB_MICRO_VERSION + * as the three arguments to this function; that produces + * a check that the library in use is compatible with + * the version of GLib the application or module was compiled + * against. + * + * Compatibility is defined by two things: first the version + * of the running library is newer than the version + * @required_major.required_minor.@required_micro. Second + * the running library must be binary compatible with the + * version @required_major.required_minor.@required_micro + * (same major version.) + * + * Return value: %NULL if the GLib library is compatible with the + * given version, or a string describing the version mismatch. + * The returned string is owned by GLib and must not be modified + * or freed. + * + * Since: 2.6 + */ +const gchar * +glib_check_version (guint required_major, + guint required_minor, + guint required_micro) +{ + gint glib_effective_micro = 100 * GLIB_MINOR_VERSION + GLIB_MICRO_VERSION; + gint required_effective_micro = 100 * required_minor + required_micro; + + if (required_major > GLIB_MAJOR_VERSION) + return "GLib version too old (major mismatch)"; + if (required_major < GLIB_MAJOR_VERSION) + return "GLib version too new (major mismatch)"; + if (required_effective_micro < glib_effective_micro - GLIB_BINARY_AGE) + return "GLib version too new (micro mismatch)"; + if (required_effective_micro > glib_effective_micro) + return "GLib version too old (micro mismatch)"; + return NULL; +} diff --git a/glib/glib/gversion.h b/glib/glib/gversion.h new file mode 100644 index 0000000..35a7d3e --- /dev/null +++ b/glib/glib/gversion.h @@ -0,0 +1,78 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_VERSION_H__ +#define __G_VERSION_H__ + +#include + +G_BEGIN_DECLS + +GLIB_VAR const guint glib_major_version; +GLIB_VAR const guint glib_minor_version; +GLIB_VAR const guint glib_micro_version; +GLIB_VAR const guint glib_interface_age; +GLIB_VAR const guint glib_binary_age; + +const gchar * glib_check_version (guint required_major, + guint required_minor, + guint required_micro); + +/** + * GLIB_CHECK_VERSION: + * @major: the major version to check for + * @minor: the minor version to check for + * @micro: the micro version to check for + * + * Checks the version of the GLib library that is being compiled + * against. + * + * + * Checking the version of the GLib library + * + * if (!GLIB_CHECK_VERSION (1, 2, 0)) + * g_error ("GLib version 1.2.0 or above is needed"); + * + * + * + * See glib_check_version() for a runtime check. + * + * Returns: %TRUE if the version of the GLib header files + * is the same as or newer than the passed-in version. + */ +#define GLIB_CHECK_VERSION(major,minor,micro) \ + (GLIB_MAJOR_VERSION > (major) || \ + (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION > (minor)) || \ + (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION == (minor) && \ + GLIB_MICRO_VERSION >= (micro))) + +G_END_DECLS + +#endif /* __G_VERSION_H__ */ diff --git a/glib/glib/gversionmacros.h b/glib/glib/gversionmacros.h new file mode 100644 index 0000000..95b0e7f --- /dev/null +++ b/glib/glib/gversionmacros.h @@ -0,0 +1,212 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_VERSION_MACROS_H__ +#define __G_VERSION_MACROS_H__ + +/* Version boundaries checks */ + +#define G_ENCODE_VERSION(major,minor) ((major) << 16 | (minor) << 8) + +/* XXX: Every new stable minor release bump should add a macro here */ + +/** + * GLIB_VERSION_2_26: + * + * A macro that evaluates to the 2.26 version of GLib, in a format + * that can be used by the C pre-processor. + * + * Since: 2.32 + */ +#define GLIB_VERSION_2_26 (G_ENCODE_VERSION (2, 26)) + +/** + * GLIB_VERSION_2_28: + * + * A macro that evaluates to the 2.28 version of GLib, in a format + * that can be used by the C pre-processor. + * + * Since: 2.32 + */ +#define GLIB_VERSION_2_28 (G_ENCODE_VERSION (2, 28)) + +/** + * GLIB_VERSION_2_30: + * + * A macro that evaluates to the 2.30 version of GLib, in a format + * that can be used by the C pre-processor. + * + * Since: 2.32 + */ +#define GLIB_VERSION_2_30 (G_ENCODE_VERSION (2, 30)) + +/** + * GLIB_VERSION_2_32: + * + * A macro that evaluates to the 2.32 version of GLib, in a format + * that can be used by the C pre-processor. + * + * Since: 2.32 + */ +#define GLIB_VERSION_2_32 (G_ENCODE_VERSION (2, 32)) + +/* evaluates to the current stable version; for development cycles, + * this means the next stable target + */ +#if (GLIB_MINOR_VERSION % 2) +#define GLIB_VERSION_CUR_STABLE (G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION + 1)) +#else +#define GLIB_VERSION_CUR_STABLE (G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION)) +#endif + +/* evaluates to the previous stable version */ +#if (GLIB_MINOR_VERSION % 2) +#define GLIB_VERSION_PREV_STABLE (G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION - 1)) +#else +#define GLIB_VERSION_PREV_STABLE (G_ENCODE_VERSION (GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION - 2)) +#endif + +/** + * GLIB_VERSION_MIN_REQUIRED: + * + * A macro that should be defined by the user prior to including + * the glib.h header. + * The definition should be one of the predefined GLib version + * macros: %GLIB_VERSION_2_26, %GLIB_VERSION_2_28,... + * + * This macro defines the lower bound for the GLib API to use. + * + * If a function has been deprecated in a newer version of GLib, + * it is possible to use this symbol to avoid the compiler warnings + * without disabling warning for every deprecated function. + * + * Since: 2.32 + */ +#ifndef GLIB_VERSION_MIN_REQUIRED +# define GLIB_VERSION_MIN_REQUIRED (GLIB_VERSION_PREV_STABLE) +#endif + +/** + * GLIB_VERSION_MAX_ALLOWED: + * + * A macro that should be defined by the user prior to including + * the glib.h header. + * The definition should be one of the predefined GLib version + * macros: %GLIB_VERSION_2_26, %GLIB_VERSION_2_28,... + * + * This macro defines the upper bound for the GLib API to use. + * + * If a function has been introduced in a newer version of GLib, + * it is possible to use this symbol to get compiler warnings when + * trying to use that function. + * + * Since: 2.32 + */ +#ifndef GLIB_VERSION_MAX_ALLOWED +# if GLIB_VERSION_MIN_REQUIRED > GLIB_VERSION_PREV_STABLE +# define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_MIN_REQUIRED +# else +# define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_CUR_STABLE +# endif +#endif + +/* sanity checks */ +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_MIN_REQUIRED +#error "GLIB_VERSION_MAX_ALLOWED must be >= GLIB_VERSION_MIN_REQUIRED" +#endif +#if GLIB_VERSION_MIN_REQUIRED < GLIB_VERSION_2_26 +#error "GLIB_VERSION_MIN_REQUIRED must be >= GLIB_VERSION_2_26" +#endif + +/* These macros are used to mark deprecated functions in GLib headers, + * and thus have to be exposed in installed headers. But please + * do *not* use them in other projects. Instead, use G_DEPRECATED + * or define your own wrappers around it. + */ + +/* XXX: Every new stable minor release should add a set of macros here */ + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_26 +# define GLIB_DEPRECATED_IN_2_26 GLIB_DEPRECATED +# define GLIB_DEPRECATED_IN_2_26_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GLIB_DEPRECATED_IN_2_26 +# define GLIB_DEPRECATED_IN_2_26_FOR(f) +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_26 +# define GLIB_AVAILABLE_IN_2_26 GLIB_UNAVAILABLE(2, 26) +#else +# define GLIB_AVAILABLE_IN_2_26 +#endif + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_28 +# define GLIB_DEPRECATED_IN_2_28 GLIB_DEPRECATED +# define GLIB_DEPRECATED_IN_2_28_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GLIB_DEPRECATED_IN_2_28 +# define GLIB_DEPRECATED_IN_2_28_FOR(f) +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_28 +# define GLIB_AVAILABLE_IN_2_28 GLIB_UNAVAILABLE(2, 28) +#else +# define GLIB_AVAILABLE_IN_2_28 +#endif + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_30 +# define GLIB_DEPRECATED_IN_2_30 GLIB_DEPRECATED +# define GLIB_DEPRECATED_IN_2_30_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GLIB_DEPRECATED_IN_2_30 +# define GLIB_DEPRECATED_IN_2_30_FOR(f) +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_30 +# define GLIB_AVAILABLE_IN_2_30 GLIB_UNAVAILABLE(2, 30) +#else +# define GLIB_AVAILABLE_IN_2_30 +#endif + +#if GLIB_VERSION_MIN_REQUIRED >= GLIB_VERSION_2_32 +# define GLIB_DEPRECATED_IN_2_32 GLIB_DEPRECATED +# define GLIB_DEPRECATED_IN_2_32_FOR(f) GLIB_DEPRECATED_FOR(f) +#else +# define GLIB_DEPRECATED_IN_2_32 +# define GLIB_DEPRECATED_IN_2_32_FOR(f) +#endif + +#if GLIB_VERSION_MAX_ALLOWED < GLIB_VERSION_2_32 +# define GLIB_AVAILABLE_IN_2_32 GLIB_UNAVAILABLE(2, 32) +#else +# define GLIB_AVAILABLE_IN_2_32 +#endif + +#endif /* __G_VERSION_MACROS_H__ */ diff --git a/glib/glib/gwakeup.c b/glib/glib/gwakeup.c new file mode 100644 index 0000000..bb49059 --- /dev/null +++ b/glib/glib/gwakeup.c @@ -0,0 +1,260 @@ +/* + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#include "config.h" + + +/* gwakeup.h is special -- GIO and some test cases include it. As such, + * it cannot include other glib headers without triggering the single + * includes warnings. We have to manually include its dependencies here + * (and at all other use sites). + */ +#ifdef GLIB_COMPILATION +#include "gtypes.h" +#include "gpoll.h" +#else +#include +#endif + +#include "gwakeup.h" + +/*< private > + * SECTION:gwakeup + * @title: GWakeup + * @short_description: portable cross-thread event signal mechanism + * + * #GWakeup is a simple and portable way of signaling events between + * different threads in a way that integrates nicely with g_poll(). + * GLib uses it internally for cross-thread signalling in the + * implementation of #GMainContext and #GCancellable. + * + * You first create a #GWakeup with g_wakeup_new() and initialise a + * #GPollFD from it using g_wakeup_get_pollfd(). Polling on the created + * #GPollFD will block until g_wakeup_signal() is called, at which point + * it will immediately return. Future attempts to poll will continue to + * return until g_wakeup_acknowledge() is called. g_wakeup_free() is + * used to free a #GWakeup. + * + * On sufficiently modern Linux, this is implemented using eventfd. On + * Windows it is implemented using an event handle. On other systems it + * is implemented with a pair of pipes. + * + * Since: 2.30 + **/ +#ifdef _WIN32 + +#include + +#ifdef GLIB_COMPILATION +#include "gmessages.h" +#include "giochannel.h" +#include "gwin32.h" +#endif + +GWakeup * +g_wakeup_new (void) +{ + HANDLE wakeup; + + wakeup = CreateEvent (NULL, TRUE, FALSE, NULL); + + if (wakeup == NULL) + g_error ("Cannot create event for GWakeup: %s", + g_win32_error_message (GetLastError ())); + + return (GWakeup *) wakeup; +} + +void +g_wakeup_get_pollfd (GWakeup *wakeup, + GPollFD *poll_fd) +{ + poll_fd->fd = (gintptr) wakeup; + poll_fd->events = G_IO_IN; +} + +void +g_wakeup_acknowledge (GWakeup *wakeup) +{ + ResetEvent ((HANDLE) wakeup); +} + +void +g_wakeup_signal (GWakeup *wakeup) +{ + SetEvent ((HANDLE) wakeup); +} + +void +g_wakeup_free (GWakeup *wakeup) +{ + CloseHandle ((HANDLE) wakeup); +} + +#else + +#include "glib-unix.h" +#include + +#if defined (HAVE_EVENTFD) +#include +#endif + +struct _GWakeup +{ + gint fds[2]; +}; + +/** + * g_wakeup_new: + * + * Creates a new #GWakeup. + * + * You should use g_wakeup_free() to free it when you are done. + * + * Returns: a new #GWakeup + * + * Since: 2.30 + **/ +GWakeup * +g_wakeup_new (void) +{ + GError *error = NULL; + GWakeup *wakeup; + + wakeup = g_slice_new (GWakeup); + + /* try eventfd first, if we think we can */ +#if defined (HAVE_EVENTFD) +#ifndef TEST_EVENTFD_FALLBACK + wakeup->fds[0] = eventfd (0, EFD_CLOEXEC | EFD_NONBLOCK); +#else + wakeup->fds[0] = -1; +#endif + + if (wakeup->fds[0] != -1) + { + wakeup->fds[1] = -1; + return wakeup; + } + + /* for any failure, try a pipe instead */ +#endif + + if (!g_unix_open_pipe (wakeup->fds, FD_CLOEXEC, &error)) + g_error ("Creating pipes for GWakeup: %s\n", error->message); + + if (!g_unix_set_fd_nonblocking (wakeup->fds[0], TRUE, &error) || + !g_unix_set_fd_nonblocking (wakeup->fds[1], TRUE, &error)) + g_error ("Set pipes non-blocking for GWakeup: %s\n", error->message); + + return wakeup; +} + +/** + * g_wakeup_get_pollfd: + * @wakeup: a #GWakeup + * @poll_fd: a #GPollFD + * + * Prepares a @poll_fd such that polling on it will succeed when + * g_wakeup_signal() has been called on @wakeup. + * + * @poll_fd is valid until @wakeup is freed. + * + * Since: 2.30 + **/ +void +g_wakeup_get_pollfd (GWakeup *wakeup, + GPollFD *poll_fd) +{ + poll_fd->fd = wakeup->fds[0]; + poll_fd->events = G_IO_IN; +} + +/** + * g_wakeup_acknowledge: + * @wakeup: a #GWakeup + * + * Acknowledges receipt of a wakeup signal on @wakeup. + * + * You must call this after @wakeup polls as ready. If not, it will + * continue to poll as ready until you do so. + * + * If you call this function and @wakeup is not signaled, nothing + * happens. + * + * Since: 2.30 + **/ +void +g_wakeup_acknowledge (GWakeup *wakeup) +{ + char buffer[16]; + + /* read until it is empty */ + while (read (wakeup->fds[0], buffer, sizeof buffer) == sizeof buffer); +} + +/** + * g_wakeup_signal: + * @wakeup: a #GWakeup + * + * Signals @wakeup. + * + * Any future (or present) polling on the #GPollFD returned by + * g_wakeup_get_pollfd() will immediately succeed until such a time as + * g_wakeup_acknowledge() is called. + * + * This function is safe to call from a UNIX signal handler. + * + * Since: 2.30 + **/ +void +g_wakeup_signal (GWakeup *wakeup) +{ + guint64 one = 1; + + if (wakeup->fds[1] == -1) + write (wakeup->fds[0], &one, sizeof one); + else + write (wakeup->fds[1], &one, 1); +} + +/** + * g_wakeup_free: + * @wakeup: a #GWakeup + * + * Frees @wakeup. + * + * You must not currently be polling on the #GPollFD returned by + * g_wakeup_get_pollfd(), or the result is undefined. + **/ +void +g_wakeup_free (GWakeup *wakeup) +{ + close (wakeup->fds[0]); + + if (wakeup->fds[1] != -1) + close (wakeup->fds[1]); + + g_slice_free (GWakeup, wakeup); +} + +#endif /* !_WIN32 */ diff --git a/glib/glib/gwakeup.h b/glib/glib/gwakeup.h new file mode 100644 index 0000000..bd94520 --- /dev/null +++ b/glib/glib/gwakeup.h @@ -0,0 +1,37 @@ +/* + * Copyright © 2011 Canonical Limited + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the licence, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + * Author: Ryan Lortie + */ + +#ifndef __G_WAKEUP_H__ +#define __G_WAKEUP_H__ + +#include + +typedef struct _GWakeup GWakeup; + +G_GNUC_INTERNAL GWakeup * g_wakeup_new (void); +G_GNUC_INTERNAL void g_wakeup_free (GWakeup *wakeup); + +G_GNUC_INTERNAL void g_wakeup_get_pollfd (GWakeup *wakeup, + GPollFD *poll_fd); +G_GNUC_INTERNAL void g_wakeup_signal (GWakeup *wakeup); +G_GNUC_INTERNAL void g_wakeup_acknowledge (GWakeup *wakeup); + +#endif diff --git a/glib/glib/gwin32.c b/glib/glib/gwin32.c new file mode 100644 index 0000000..e12fa7a --- /dev/null +++ b/glib/glib/gwin32.c @@ -0,0 +1,577 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1998 Peter Mattis, Spencer Kimball and Josh MacDonald + * Copyright (C) 1998-1999 Tor Lillqvist + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +/* + * MT safe for the unix part, FIXME: make the win32 part MT safe as well. + */ + +#include "config.h" + +#include "glibconfig.h" + +#include +#include +#include +#include +#include + +#define STRICT /* Strict typing, please */ +#include +#undef STRICT +#ifndef G_WITH_CYGWIN +#include +#endif +#include +#include +#if defined(_MSC_VER) || defined(__DMC__) +# include +#endif /* _MSC_VER || __DMC__ */ + +#include "glib.h" +#include "gthreadprivate.h" + +#ifdef G_WITH_CYGWIN +#include +#endif + +#ifndef G_WITH_CYGWIN + +gint +g_win32_ftruncate (gint fd, + guint size) +{ + return _chsize (fd, size); +} + +#endif + +/** + * g_win32_getlocale: + * + * The setlocale() function in the Microsoft C library uses locale + * names of the form "English_United States.1252" etc. We want the + * UNIXish standard form "en_US", "zh_TW" etc. This function gets the + * current thread locale from Windows - without any encoding info - + * and returns it as a string of the above form for use in forming + * file names etc. The returned string should be deallocated with + * g_free(). + * + * Returns: newly-allocated locale name. + **/ + +#ifndef SUBLANG_SERBIAN_LATIN_BA +#define SUBLANG_SERBIAN_LATIN_BA 0x06 +#endif + +gchar * +g_win32_getlocale (void) +{ + LCID lcid; + LANGID langid; + gchar *ev; + gint primary, sub; + char iso639[10]; + char iso3166[10]; + const gchar *script = NULL; + + /* Let the user override the system settings through environment + * variables, as on POSIX systems. Note that in GTK+ applications + * since GTK+ 2.10.7 setting either LC_ALL or LANG also sets the + * Win32 locale and C library locale through code in gtkmain.c. + */ + if (((ev = getenv ("LC_ALL")) != NULL && ev[0] != '\0') + || ((ev = getenv ("LC_MESSAGES")) != NULL && ev[0] != '\0') + || ((ev = getenv ("LANG")) != NULL && ev[0] != '\0')) + return g_strdup (ev); + + lcid = GetThreadLocale (); + + if (!GetLocaleInfo (lcid, LOCALE_SISO639LANGNAME, iso639, sizeof (iso639)) || + !GetLocaleInfo (lcid, LOCALE_SISO3166CTRYNAME, iso3166, sizeof (iso3166))) + return g_strdup ("C"); + + /* Strip off the sorting rules, keep only the language part. */ + langid = LANGIDFROMLCID (lcid); + + /* Split into language and territory part. */ + primary = PRIMARYLANGID (langid); + sub = SUBLANGID (langid); + + /* Handle special cases */ + switch (primary) + { + case LANG_AZERI: + switch (sub) + { + case SUBLANG_AZERI_LATIN: + script = "@Latn"; + break; + case SUBLANG_AZERI_CYRILLIC: + script = "@Cyrl"; + break; + } + break; + case LANG_SERBIAN: /* LANG_CROATIAN == LANG_SERBIAN */ + switch (sub) + { + case SUBLANG_SERBIAN_LATIN: + case 0x06: /* Serbian (Latin) - Bosnia and Herzegovina */ + script = "@Latn"; + break; + } + break; + case LANG_UZBEK: + switch (sub) + { + case SUBLANG_UZBEK_LATIN: + script = "@Latn"; + break; + case SUBLANG_UZBEK_CYRILLIC: + script = "@Cyrl"; + break; + } + break; + } + return g_strconcat (iso639, "_", iso3166, script, NULL); +} + +/** + * g_win32_error_message: + * @error: error code. + * + * Translate a Win32 error code (as returned by GetLastError()) into + * the corresponding message. The message is either language neutral, + * or in the thread's language, or the user's language, the system's + * language, or US English (see docs for FormatMessage()). The + * returned string is in UTF-8. It should be deallocated with + * g_free(). + * + * Returns: newly-allocated error message + **/ +gchar * +g_win32_error_message (gint error) +{ + gchar *retval; + wchar_t *msg = NULL; + int nchars; + + FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER + |FORMAT_MESSAGE_IGNORE_INSERTS + |FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, + (LPWSTR) &msg, 0, NULL); + if (msg != NULL) + { + nchars = wcslen (msg); + + if (nchars > 2 && msg[nchars-1] == '\n' && msg[nchars-2] == '\r') + msg[nchars-2] = '\0'; + + retval = g_utf16_to_utf8 (msg, -1, NULL, NULL, NULL); + + LocalFree (msg); + } + else + retval = g_strdup (""); + + return retval; +} + +/** + * g_win32_get_package_installation_directory_of_module: + * @hmodule: The Win32 handle for a DLL loaded into the current process, or %NULL + * + * This function tries to determine the installation directory of a + * software package based on the location of a DLL of the software + * package. + * + * @hmodule should be the handle of a loaded DLL or %NULL. The + * function looks up the directory that DLL was loaded from. If + * @hmodule is NULL, the directory the main executable of the current + * process is looked up. If that directory's last component is "bin" + * or "lib", its parent directory is returned, otherwise the directory + * itself. + * + * It thus makes sense to pass only the handle to a "public" DLL of a + * software package to this function, as such DLLs typically are known + * to be installed in a "bin" or occasionally "lib" subfolder of the + * installation folder. DLLs that are of the dynamically loaded module + * or plugin variety are often located in more private locations + * deeper down in the tree, from which it is impossible for GLib to + * deduce the root of the package installation. + * + * The typical use case for this function is to have a DllMain() that + * saves the handle for the DLL. Then when code in the DLL needs to + * construct names of files in the installation tree it calls this + * function passing the DLL handle. + * + * Returns: a string containing the guessed installation directory for + * the software package @hmodule is from. The string is in the GLib + * file name encoding, i.e. UTF-8. The return value should be freed + * with g_free() when not needed any longer. If the function fails + * %NULL is returned. + * + * Since: 2.16 + */ +gchar * +g_win32_get_package_installation_directory_of_module (gpointer hmodule) +{ + gchar *retval; + gchar *p; + wchar_t wc_fn[MAX_PATH]; + + if (!GetModuleFileNameW (hmodule, wc_fn, MAX_PATH)) + return NULL; + + retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL); + + if ((p = strrchr (retval, G_DIR_SEPARATOR)) != NULL) + *p = '\0'; + + p = strrchr (retval, G_DIR_SEPARATOR); + if (p && (g_ascii_strcasecmp (p + 1, "bin") == 0 || + g_ascii_strcasecmp (p + 1, "lib") == 0)) + *p = '\0'; + +#ifdef G_WITH_CYGWIN + /* In Cygwin we need to have POSIX paths */ + { + gchar tmp[MAX_PATH]; + + cygwin_conv_to_posix_path (retval, tmp); + g_free (retval); + retval = g_strdup (tmp); + } +#endif + + return retval; +} + +static gchar * +get_package_directory_from_module (const gchar *module_name) +{ + static GHashTable *module_dirs = NULL; + G_LOCK_DEFINE_STATIC (module_dirs); + HMODULE hmodule = NULL; + gchar *fn; + + G_LOCK (module_dirs); + + if (module_dirs == NULL) + module_dirs = g_hash_table_new (g_str_hash, g_str_equal); + + fn = g_hash_table_lookup (module_dirs, module_name ? module_name : ""); + + if (fn) + { + G_UNLOCK (module_dirs); + return g_strdup (fn); + } + + if (module_name) + { + wchar_t *wc_module_name = g_utf8_to_utf16 (module_name, -1, NULL, NULL, NULL); + hmodule = GetModuleHandleW (wc_module_name); + g_free (wc_module_name); + + if (!hmodule) + { + G_UNLOCK (module_dirs); + return NULL; + } + } + + fn = g_win32_get_package_installation_directory_of_module (hmodule); + + if (fn == NULL) + { + G_UNLOCK (module_dirs); + return NULL; + } + + g_hash_table_insert (module_dirs, module_name ? g_strdup (module_name) : "", fn); + + G_UNLOCK (module_dirs); + + return g_strdup (fn); +} + +/** + * g_win32_get_package_installation_directory: + * @package: You should pass %NULL for this. + * @dll_name: The name of a DLL that a package provides in UTF-8, or %NULL. + * + * Try to determine the installation directory for a software package. + * + * This function is deprecated. Use + * g_win32_get_package_installation_directory_of_module() instead. + * + * The use of @package is deprecated. You should always pass %NULL. A + * warning is printed if non-NULL is passed as @package. + * + * The original intended use of @package was for a short identifier of + * the package, typically the same identifier as used for + * GETTEXT_PACKAGE in software configured using GNU + * autotools. The function first looks in the Windows Registry for the + * value #InstallationDirectory in the key + * #HKLM\Software\@package, and if that value + * exists and is a string, returns that. + * + * It is strongly recommended that packagers of GLib-using libraries + * for Windows do not store installation paths in the Registry to be + * used by this function as that interfers with having several + * parallel installations of the library. Enabling multiple + * installations of different versions of some GLib-using library, or + * GLib itself, is desirable for various reasons. + * + * For this reason it is recommeded to always pass %NULL as + * @package to this function, to avoid the temptation to use the + * Registry. In version 2.20 of GLib the @package parameter + * will be ignored and this function won't look in the Registry at all. + * + * If @package is %NULL, or the above value isn't found in the + * Registry, but @dll_name is non-%NULL, it should name a DLL loaded + * into the current process. Typically that would be the name of the + * DLL calling this function, looking for its installation + * directory. The function then asks Windows what directory that DLL + * was loaded from. If that directory's last component is "bin" or + * "lib", the parent directory is returned, otherwise the directory + * itself. If that DLL isn't loaded, the function proceeds as if + * @dll_name was %NULL. + * + * If both @package and @dll_name are %NULL, the directory from where + * the main executable of the process was loaded is used instead in + * the same way as above. + * + * Returns: a string containing the installation directory for + * @package. The string is in the GLib file name encoding, + * i.e. UTF-8. The return value should be freed with g_free() when not + * needed any longer. If the function fails %NULL is returned. + * + * Deprecated: 2.18: Pass the HMODULE of a DLL or EXE to + * g_win32_get_package_installation_directory_of_module() instead. + **/ + + gchar * +g_win32_get_package_installation_directory_utf8 (const gchar *package, + const gchar *dll_name) +{ + gchar *result = NULL; + + if (package != NULL) + g_warning ("Passing a non-NULL package to g_win32_get_package_installation_directory() is deprecated and it is ignored."); + + if (dll_name != NULL) + result = get_package_directory_from_module (dll_name); + + if (result == NULL) + result = get_package_directory_from_module (NULL); + + return result; +} + +#if !defined (_WIN64) + +/* DLL ABI binary compatibility version that uses system codepage file names */ + +gchar * +g_win32_get_package_installation_directory (const gchar *package, + const gchar *dll_name) +{ + gchar *utf8_package = NULL, *utf8_dll_name = NULL; + gchar *utf8_retval, *retval; + + if (package != NULL) + utf8_package = g_locale_to_utf8 (package, -1, NULL, NULL, NULL); + + if (dll_name != NULL) + utf8_dll_name = g_locale_to_utf8 (dll_name, -1, NULL, NULL, NULL); + + utf8_retval = + g_win32_get_package_installation_directory_utf8 (utf8_package, + utf8_dll_name); + + retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL); + + g_free (utf8_package); + g_free (utf8_dll_name); + g_free (utf8_retval); + + return retval; +} + +#endif + +/** + * g_win32_get_package_installation_subdirectory: + * @package: You should pass %NULL for this. + * @dll_name: The name of a DLL that a package provides, in UTF-8, or %NULL. + * @subdir: A subdirectory of the package installation directory, also in UTF-8 + * + * This function is deprecated. Use + * g_win32_get_package_installation_directory_of_module() and + * g_build_filename() instead. + * + * Returns a newly-allocated string containing the path of the + * subdirectory @subdir in the return value from calling + * g_win32_get_package_installation_directory() with the @package and + * @dll_name parameters. See the documentation for + * g_win32_get_package_installation_directory() for more details. In + * particular, note that it is deprecated to pass anything except NULL + * as @package. + * + * Returns: a string containing the complete path to @subdir inside + * the installation directory of @package. The returned string is in + * the GLib file name encoding, i.e. UTF-8. The return value should be + * freed with g_free() when no longer needed. If something goes wrong, + * %NULL is returned. + * + * Deprecated: 2.18: Pass the HMODULE of a DLL or EXE to + * g_win32_get_package_installation_directory_of_module() instead, and + * then construct a subdirectory pathname with g_build_filename(). + **/ + +gchar * +g_win32_get_package_installation_subdirectory_utf8 (const gchar *package, + const gchar *dll_name, + const gchar *subdir) +{ + gchar *prefix; + gchar *dirname; + + prefix = g_win32_get_package_installation_directory_utf8 (package, dll_name); + + dirname = g_build_filename (prefix, subdir, NULL); + g_free (prefix); + + return dirname; +} + +#if !defined (_WIN64) + +/* DLL ABI binary compatibility version that uses system codepage file names */ + +gchar * +g_win32_get_package_installation_subdirectory (const gchar *package, + const gchar *dll_name, + const gchar *subdir) +{ + gchar *prefix; + gchar *dirname; + + prefix = g_win32_get_package_installation_directory (package, dll_name); + + dirname = g_build_filename (prefix, subdir, NULL); + g_free (prefix); + + return dirname; +} + +#endif + +/** + * g_win32_get_windows_version: + * + * Returns version information for the Windows operating system the + * code is running on. See MSDN documentation for the GetVersion() + * function. To summarize, the most significant bit is one on Win9x, + * and zero on NT-based systems. Since version 2.14, GLib works only + * on NT-based systems, so checking whether your are running on Win9x + * in your own software is moot. The least significant byte is 4 on + * Windows NT 4, and 5 on Windows XP. Software that needs really + * detailed version and feature information should use Win32 API like + * GetVersionEx() and VerifyVersionInfo(). + * + * Returns: The version information. + * + * Since: 2.6 + **/ +guint +g_win32_get_windows_version (void) +{ + static gsize windows_version; + + if (g_once_init_enter (&windows_version)) + g_once_init_leave (&windows_version, GetVersion ()); + + return windows_version; +} + +/** + * g_win32_locale_filename_from_utf8: + * @utf8filename: a UTF-8 encoded filename. + * + * Converts a filename from UTF-8 to the system codepage. + * + * On NT-based Windows, on NTFS file systems, file names are in + * Unicode. It is quite possible that Unicode file names contain + * characters not representable in the system codepage. (For instance, + * Greek or Cyrillic characters on Western European or US Windows + * installations, or various less common CJK characters on CJK Windows + * installations.) + * + * In such a case, and if the filename refers to an existing file, and + * the file system stores alternate short (8.3) names for directory + * entries, the short form of the filename is returned. Note that the + * "short" name might in fact be longer than the Unicode name if the + * Unicode name has very short pathname components containing + * non-ASCII characters. If no system codepage name for the file is + * possible, %NULL is returned. + * + * The return value is dynamically allocated and should be freed with + * g_free() when no longer needed. + * + * Return value: The converted filename, or %NULL on conversion + * failure and lack of short names. + * + * Since: 2.8 + */ +gchar * +g_win32_locale_filename_from_utf8 (const gchar *utf8filename) +{ + gchar *retval = g_locale_from_utf8 (utf8filename, -1, NULL, NULL, NULL); + + if (retval == NULL) + { + /* Conversion failed, so convert to wide chars, check if there + * is a 8.3 version, and use that. + */ + wchar_t *wname = g_utf8_to_utf16 (utf8filename, -1, NULL, NULL, NULL); + if (wname != NULL) + { + wchar_t wshortname[MAX_PATH + 1]; + if (GetShortPathNameW (wname, wshortname, G_N_ELEMENTS (wshortname))) + { + gchar *tem = g_utf16_to_utf8 (wshortname, -1, NULL, NULL, NULL); + retval = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL); + g_free (tem); + } + g_free (wname); + } + } + return retval; +} diff --git a/glib/glib/gwin32.h b/glib/glib/gwin32.h new file mode 100644 index 0000000..b0fb7c0 --- /dev/null +++ b/glib/glib/gwin32.h @@ -0,0 +1,118 @@ +/* GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +/* + * Modified by the GLib Team and others 1997-2000. See the AUTHORS + * file for a list of people on the GLib Team. See the ChangeLog + * files for a list of changes. These files are distributed with + * GLib at ftp://ftp.gtk.org/pub/gtk/. + */ + +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + +#ifndef __G_WIN32_H__ +#define __G_WIN32_H__ + +#include + +#ifdef G_PLATFORM_WIN32 + +G_BEGIN_DECLS + +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif + +#ifdef G_OS_WIN32 + +/* + * To get prototypes for the following POSIXish functions, you have to + * include the indicated non-POSIX headers. The functions are defined + * in OLDNAMES.LIB (MSVC) or -lmoldname-msvc (mingw32). But note that + * for POSIX functions that take or return file names in the system + * codepage, in many cases you would want to use the GLib wrappers in + * gstdio.h and UTF-8 instead. + * + * getcwd: (MSVC), (mingw32) + * getpid: + * access: + * unlink: or + * open, read, write, lseek, close: + * rmdir: + * pipe: (actually, _pipe()) + */ + +/* For some POSIX functions that are not provided by the MS runtime, + * we provide emulation functions in glib, which are prefixed with + * g_win32_. Or that was the idea at some time, but there is just one + * of those: + */ +gint g_win32_ftruncate (gint f, + guint size); +#endif /* G_OS_WIN32 */ + +/* The MS setlocale uses locale names of the form "English_United + * States.1252" etc. We want the Unixish standard form "en", "zh_TW" + * etc. This function gets the current thread locale from Windows and + * returns it as a string of the above form for use in forming file + * names etc. The returned string should be deallocated with g_free(). + */ +gchar* g_win32_getlocale (void); + +/* Translate a Win32 error code (as returned by GetLastError()) into + * the corresponding message. The returned string should be deallocated + * with g_free(). + */ +gchar* g_win32_error_message (gint error); + +#ifndef G_DISABLE_DEPRECATED + +#ifndef __GTK_DOC_IGNORE__ +#ifdef _WIN64 +#define g_win32_get_package_installation_directory g_win32_get_package_installation_directory_utf8 +#define g_win32_get_package_installation_subdirectory g_win32_get_package_installation_subdirectory_utf8 +#endif +#endif + +gchar* g_win32_get_package_installation_directory (const gchar *package, + const gchar *dll_name); + +gchar* g_win32_get_package_installation_subdirectory (const gchar *package, + const gchar *dll_name, + const gchar *subdir); + +#endif + +gchar* g_win32_get_package_installation_directory_of_module (gpointer hmodule); + +guint g_win32_get_windows_version (void); + +gchar* g_win32_locale_filename_from_utf8 (const gchar *utf8filename); + +/* As of GLib 2.14 we only support NT-based Windows */ +#define G_WIN32_IS_NT_BASED() TRUE +#define G_WIN32_HAVE_WIDECHAR_API() TRUE + +G_END_DECLS + +#endif /* G_PLATFORM_WIN32 */ + +#endif /* __G_WIN32_H__ */ diff --git a/glib/glib/libcharset/.gitignore b/glib/glib/libcharset/.gitignore new file mode 100644 index 0000000..0cef440 --- /dev/null +++ b/glib/glib/libcharset/.gitignore @@ -0,0 +1,3 @@ +charset.alias +ref-add.sed +ref-del.sed diff --git a/glib/glib/libcharset/Makefile.am b/glib/glib/libcharset/Makefile.am new file mode 100644 index 0000000..f5362df --- /dev/null +++ b/glib/glib/libcharset/Makefile.am @@ -0,0 +1,64 @@ +## Process this file with automake to produce Makefile.in +include $(top_srcdir)/Makefile.decl + +INCLUDES = \ + -DLIBDIR=\"$(libdir)\" $(config_h_INCLUDES) + +noinst_LTLIBRARIES = libcharset.la + +libcharset_la_SOURCES = \ + libcharset.h \ + localcharset.h \ + localcharset.c + +EXTRA_DIST += \ + README \ + config.charset \ + ref-add.sin \ + ref-del.sin \ + glibc21.m4 \ + codeset.m4 \ + update.sh \ + make-patch.sh \ + libcharset-glib.patch + +charset_alias = $(DESTDIR)$(libdir)/charset.alias +charset_tmp = $(DESTDIR)$(libdir)/charset.tmp +install-exec-local: all-local + $(mkinstalldirs) $(DESTDIR)$(libdir) + if test -f $(charset_alias); then \ + sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + else \ + if test @GLIBC21@ = no; then \ + sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + fi ; \ + fi + +uninstall-local: all-local + if test -f $(charset_alias); then \ + sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ + if grep '^# Packages using this file: $$' $(charset_tmp) \ + > /dev/null; then \ + rm -f $(charset_alias); \ + else \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ + fi; \ + rm -f $(charset_tmp); \ + fi + +charset.alias: config.charset + $(AM_V_GEN) $(SHELL) $(srcdir)/config.charset '@host@' > t-$@ + @mv t-$@ $@ + +all-local: ref-add.sed ref-del.sed charset.alias + +SUFFIXES = .sed .sin +.sin.sed: + $(AM_V_GEN) $(SED) -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $< > t-$@ + @mv t-$@ $@ + +CLEANFILES = charset.alias ref-add.sed ref-del.sed diff --git a/glib/glib/libcharset/README b/glib/glib/libcharset/README new file mode 100644 index 0000000..c8f53bd --- /dev/null +++ b/glib/glib/libcharset/README @@ -0,0 +1,46 @@ +The sources are derived from Bruno Haible's libcharset library included +with libiconv: + + http//www.gnu.org/software/libiconv + +The 'update.sh' script in this directory, when pointed at +the original sources updates the files in this directory +(and elsewhere in the GLib distribution) to the new version + +The 'make-patch.sh' script in this directory regenerates +the patch files included in this directory from a copy +of the pristine sources and the files in this directory. + +The license on the portions from libiconv portions is reproduced +below. + +Owen Taylor +26 September 2001 + +Updated to libiconv-1.12. + +Behdad Esfahbod +20 May 2008 + +==== + +/* Determine a canonical name for the current locale's character encoding. + + Copyright (C) 2000-2001 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. */ + +/* Written by Bruno Haible . */ diff --git a/glib/glib/libcharset/codeset.m4 b/glib/glib/libcharset/codeset.m4 new file mode 100644 index 0000000..a6e67ec --- /dev/null +++ b/glib/glib/libcharset/codeset.m4 @@ -0,0 +1,21 @@ +# codeset.m4 serial AM1 (gettext-0.10.40) +dnl Copyright (C) 2000-2002 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([AM_LANGINFO_CODESET], +[ + AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset, + [AC_TRY_LINK([#include ], + [char* cs = nl_langinfo(CODESET);], + am_cv_langinfo_codeset=yes, + am_cv_langinfo_codeset=no) + ]) + if test $am_cv_langinfo_codeset = yes; then + AC_DEFINE(HAVE_LANGINFO_CODESET, 1, + [Define if you have and nl_langinfo(CODESET).]) + fi +]) diff --git a/glib/glib/libcharset/config.charset b/glib/glib/libcharset/config.charset new file mode 100755 index 0000000..e8c258b --- /dev/null +++ b/glib/glib/libcharset/config.charset @@ -0,0 +1,640 @@ +#! /bin/sh +# Output a system dependent table of character encoding aliases. +# +# Copyright (C) 2000-2004, 2006 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published +# by the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. +# +# The table consists of lines of the form +# ALIAS CANONICAL +# +# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)". +# ALIAS is compared in a case sensitive way. +# +# CANONICAL is the GNU canonical name for this character encoding. +# It must be an encoding supported by libiconv. Support by GNU libc is +# also desirable. CANONICAL is case insensitive. Usually an upper case +# MIME charset name is preferred. +# The current list of GNU canonical charset names is as follows. +# +# name MIME? used by which systems +# ASCII, ANSI_X3.4-1968 glibc solaris freebsd netbsd darwin +# ISO-8859-1 Y glibc aix hpux irix osf solaris freebsd netbsd darwin +# ISO-8859-2 Y glibc aix hpux irix osf solaris freebsd netbsd darwin +# ISO-8859-3 Y glibc solaris +# ISO-8859-4 Y osf solaris freebsd netbsd darwin +# ISO-8859-5 Y glibc aix hpux irix osf solaris freebsd netbsd darwin +# ISO-8859-6 Y glibc aix hpux solaris +# ISO-8859-7 Y glibc aix hpux irix osf solaris netbsd darwin +# ISO-8859-8 Y glibc aix hpux osf solaris +# ISO-8859-9 Y glibc aix hpux irix osf solaris darwin +# ISO-8859-13 glibc netbsd darwin +# ISO-8859-14 glibc +# ISO-8859-15 glibc aix osf solaris freebsd darwin +# KOI8-R Y glibc solaris freebsd netbsd darwin +# KOI8-U Y glibc freebsd netbsd darwin +# KOI8-T glibc +# CP437 dos +# CP775 dos +# CP850 aix osf dos +# CP852 dos +# CP855 dos +# CP856 aix +# CP857 dos +# CP861 dos +# CP862 dos +# CP864 dos +# CP865 dos +# CP866 freebsd netbsd darwin dos +# CP869 dos +# CP874 woe32 dos +# CP922 aix +# CP932 aix woe32 dos +# CP943 aix +# CP949 osf woe32 dos +# CP950 woe32 dos +# CP1046 aix +# CP1124 aix +# CP1125 dos +# CP1129 aix +# CP1250 woe32 +# CP1251 glibc solaris netbsd darwin woe32 +# CP1252 aix woe32 +# CP1253 woe32 +# CP1254 woe32 +# CP1255 glibc woe32 +# CP1256 woe32 +# CP1257 woe32 +# GB2312 Y glibc aix hpux irix solaris freebsd netbsd darwin +# EUC-JP Y glibc aix hpux irix osf solaris freebsd netbsd darwin +# EUC-KR Y glibc aix hpux irix osf solaris freebsd netbsd darwin +# EUC-TW glibc aix hpux irix osf solaris netbsd +# BIG5 Y glibc aix hpux osf solaris freebsd netbsd darwin +# BIG5-HKSCS glibc solaris +# GBK glibc aix osf solaris woe32 dos +# GB18030 glibc solaris netbsd +# SHIFT_JIS Y hpux osf solaris freebsd netbsd darwin +# JOHAB glibc solaris woe32 +# TIS-620 glibc aix hpux osf solaris +# VISCII Y glibc +# TCVN5712-1 glibc +# GEORGIAN-PS glibc +# HP-ROMAN8 hpux +# HP-ARABIC8 hpux +# HP-GREEK8 hpux +# HP-HEBREW8 hpux +# HP-TURKISH8 hpux +# HP-KANA8 hpux +# DEC-KANJI osf +# DEC-HANYU osf +# UTF-8 Y glibc aix hpux osf solaris netbsd darwin +# +# Note: Names which are not marked as being a MIME name should not be used in +# Internet protocols for information interchange (mail, news, etc.). +# +# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications +# must understand both names and treat them as equivalent. +# +# The first argument passed to this file is the canonical host specification, +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM + +host="$1" +os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'` +echo "# This file contains a table of character encoding aliases," +echo "# suitable for operating system '${os}'." +echo "# It was automatically generated from config.charset." +# List of references, updated during installation: +echo "# Packages using this file: " +case "$os" in + linux-gnulibc1*) + # Linux libc5 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "C ASCII" + echo "POSIX ASCII" + for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \ + en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \ + en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \ + es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \ + et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \ + fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \ + it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \ + sv_FI sv_SE; do + echo "$l ISO-8859-1" + echo "$l.iso-8859-1 ISO-8859-1" + echo "$l.iso-8859-15 ISO-8859-15" + echo "$l.iso-8859-15@euro ISO-8859-15" + echo "$l@euro ISO-8859-15" + echo "$l.cp-437 CP437" + echo "$l.cp-850 CP850" + echo "$l.cp-1252 CP1252" + echo "$l.cp-1252@euro CP1252" + #echo "$l.atari-st ATARI-ST" # not a commonly used encoding + echo "$l.utf-8 UTF-8" + echo "$l.utf-8@euro UTF-8" + done + for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \ + sl_SI sr sr_CS sr_YU; do + echo "$l ISO-8859-2" + echo "$l.iso-8859-2 ISO-8859-2" + echo "$l.cp-852 CP852" + echo "$l.cp-1250 CP1250" + echo "$l.utf-8 UTF-8" + done + for l in mk mk_MK ru ru_RU; do + echo "$l ISO-8859-5" + echo "$l.iso-8859-5 ISO-8859-5" + echo "$l.koi8-r KOI8-R" + echo "$l.cp-866 CP866" + echo "$l.cp-1251 CP1251" + echo "$l.utf-8 UTF-8" + done + for l in ar ar_SA; do + echo "$l ISO-8859-6" + echo "$l.iso-8859-6 ISO-8859-6" + echo "$l.cp-864 CP864" + #echo "$l.cp-868 CP868" # not a commonly used encoding + echo "$l.cp-1256 CP1256" + echo "$l.utf-8 UTF-8" + done + for l in el el_GR gr gr_GR; do + echo "$l ISO-8859-7" + echo "$l.iso-8859-7 ISO-8859-7" + echo "$l.cp-869 CP869" + echo "$l.cp-1253 CP1253" + echo "$l.cp-1253@euro CP1253" + echo "$l.utf-8 UTF-8" + echo "$l.utf-8@euro UTF-8" + done + for l in he he_IL iw iw_IL; do + echo "$l ISO-8859-8" + echo "$l.iso-8859-8 ISO-8859-8" + echo "$l.cp-862 CP862" + echo "$l.cp-1255 CP1255" + echo "$l.utf-8 UTF-8" + done + for l in tr tr_TR; do + echo "$l ISO-8859-9" + echo "$l.iso-8859-9 ISO-8859-9" + echo "$l.cp-857 CP857" + echo "$l.cp-1254 CP1254" + echo "$l.utf-8 UTF-8" + done + for l in lt lt_LT lv lv_LV; do + #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name + echo "$l ISO-8859-13" + done + for l in ru_UA uk uk_UA; do + echo "$l KOI8-U" + done + for l in zh zh_CN; do + #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name + echo "$l GB2312" + done + for l in ja ja_JP ja_JP.EUC; do + echo "$l EUC-JP" + done + for l in ko ko_KR; do + echo "$l EUC-KR" + done + for l in th th_TH; do + echo "$l TIS-620" + done + for l in fa fa_IR; do + #echo "$l ISIRI-3342" # a broken encoding + echo "$l.utf-8 UTF-8" + done + ;; + linux* | *-gnu*) + # With glibc-2.1 or newer, we don't need any canonicalization, + # because glibc has iconv and both glibc and libiconv support all + # GNU canonical names directly. Therefore, the Makefile does not + # need to install the alias file at all. + # The following applies only to glibc-2.0.x and older libcs. + echo "ISO_646.IRV:1983 ASCII" + ;; + aix*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-6 ISO-8859-6" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "IBM-850 CP850" + echo "IBM-856 CP856" + echo "IBM-921 ISO-8859-13" + echo "IBM-922 CP922" + echo "IBM-932 CP932" + echo "IBM-943 CP943" + echo "IBM-1046 CP1046" + echo "IBM-1124 CP1124" + echo "IBM-1129 CP1129" + echo "IBM-1252 CP1252" + echo "IBM-eucCN GB2312" + echo "IBM-eucJP EUC-JP" + echo "IBM-eucKR EUC-KR" + echo "IBM-eucTW EUC-TW" + echo "big5 BIG5" + echo "GBK GBK" + echo "TIS-620 TIS-620" + echo "UTF-8 UTF-8" + ;; + hpux*) + echo "iso88591 ISO-8859-1" + echo "iso88592 ISO-8859-2" + echo "iso88595 ISO-8859-5" + echo "iso88596 ISO-8859-6" + echo "iso88597 ISO-8859-7" + echo "iso88598 ISO-8859-8" + echo "iso88599 ISO-8859-9" + echo "iso885915 ISO-8859-15" + echo "roman8 HP-ROMAN8" + echo "arabic8 HP-ARABIC8" + echo "greek8 HP-GREEK8" + echo "hebrew8 HP-HEBREW8" + echo "turkish8 HP-TURKISH8" + echo "kana8 HP-KANA8" + echo "tis620 TIS-620" + echo "big5 BIG5" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "hp15CN GB2312" + #echo "ccdc ?" # what is this? + echo "SJIS SHIFT_JIS" + echo "utf8 UTF-8" + ;; + irix*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-9 ISO-8859-9" + echo "eucCN GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + ;; + osf*) + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "cp850 CP850" + echo "big5 BIG5" + echo "dechanyu DEC-HANYU" + echo "dechanzi GB2312" + echo "deckanji DEC-KANJI" + echo "deckorean EUC-KR" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "GBK GBK" + echo "KSC5601 CP949" + echo "sdeckanji EUC-JP" + echo "SJIS SHIFT_JIS" + echo "TACTIS TIS-620" + echo "UTF-8 UTF-8" + ;; + solaris*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-3 ISO-8859-3" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-6 ISO-8859-6" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-8 ISO-8859-8" + echo "ISO8859-9 ISO-8859-9" + echo "ISO8859-15 ISO-8859-15" + echo "koi8-r KOI8-R" + echo "ansi-1251 CP1251" + echo "BIG5 BIG5" + echo "Big5-HKSCS BIG5-HKSCS" + echo "gb2312 GB2312" + echo "GBK GBK" + echo "GB18030 GB18030" + echo "cns11643 EUC-TW" + echo "5601 EUC-KR" + echo "ko_KR.johap92 JOHAB" + echo "eucJP EUC-JP" + echo "PCK SHIFT_JIS" + echo "TIS620.2533 TIS-620" + #echo "sun_eu_greek ?" # what is this? + echo "UTF-8 UTF-8" + ;; + freebsd* | os2*) + # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just + # reuse FreeBSD's locale data for OS/2. + echo "C ASCII" + echo "US-ASCII ASCII" + for l in la_LN lt_LN; do + echo "$l.ASCII ASCII" + done + for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ + fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \ + lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do + echo "$l.ISO_8859-1 ISO-8859-1" + echo "$l.DIS_8859-15 ISO-8859-15" + done + for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do + echo "$l.ISO_8859-2 ISO-8859-2" + done + for l in la_LN lt_LT; do + echo "$l.ISO_8859-4 ISO-8859-4" + done + for l in ru_RU ru_SU; do + echo "$l.KOI8-R KOI8-R" + echo "$l.ISO_8859-5 ISO-8859-5" + echo "$l.CP866 CP866" + done + echo "uk_UA.KOI8-U KOI8-U" + echo "zh_TW.BIG5 BIG5" + echo "zh_TW.Big5 BIG5" + echo "zh_CN.EUC GB2312" + echo "ja_JP.EUC EUC-JP" + echo "ja_JP.SJIS SHIFT_JIS" + echo "ja_JP.Shift_JIS SHIFT_JIS" + echo "ko_KR.EUC EUC-KR" + ;; + netbsd*) + echo "646 ASCII" + echo "ISO8859-1 ISO-8859-1" + echo "ISO8859-2 ISO-8859-2" + echo "ISO8859-4 ISO-8859-4" + echo "ISO8859-5 ISO-8859-5" + echo "ISO8859-7 ISO-8859-7" + echo "ISO8859-13 ISO-8859-13" + echo "ISO8859-15 ISO-8859-15" + echo "eucCN GB2312" + echo "eucJP EUC-JP" + echo "eucKR EUC-KR" + echo "eucTW EUC-TW" + echo "BIG5 BIG5" + echo "SJIS SHIFT_JIS" + ;; + darwin[56]*) + # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "C ASCII" + for l in en_AU en_CA en_GB en_US la_LN; do + echo "$l.US-ASCII ASCII" + done + for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \ + fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \ + nl_NL no_NO pt_PT sv_SE; do + echo "$l ISO-8859-1" + echo "$l.ISO8859-1 ISO-8859-1" + echo "$l.ISO8859-15 ISO-8859-15" + done + for l in la_LN; do + echo "$l.ISO8859-1 ISO-8859-1" + echo "$l.ISO8859-15 ISO-8859-15" + done + for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do + echo "$l.ISO8859-2 ISO-8859-2" + done + for l in la_LN lt_LT; do + echo "$l.ISO8859-4 ISO-8859-4" + done + for l in ru_RU; do + echo "$l.KOI8-R KOI8-R" + echo "$l.ISO8859-5 ISO-8859-5" + echo "$l.CP866 CP866" + done + for l in bg_BG; do + echo "$l.CP1251 CP1251" + done + echo "uk_UA.KOI8-U KOI8-U" + echo "zh_TW.BIG5 BIG5" + echo "zh_TW.Big5 BIG5" + echo "zh_CN.EUC GB2312" + echo "ja_JP.EUC EUC-JP" + echo "ja_JP.SJIS SHIFT_JIS" + echo "ko_KR.EUC EUC-KR" + ;; + darwin*) + # Darwin 7.5 has nl_langinfo(CODESET), but it is useless: + # - It returns the empty string when LANG is set to a locale of the + # form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8 + # LC_CTYPE file. + # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by + # the system; nl_langinfo(CODESET) returns "US-ASCII" in this case. + # - The documentation says: + # "... all code that calls BSD system routines should ensure + # that the const *char parameters of these routines are in UTF-8 + # encoding. All BSD system functions expect their string + # parameters to be in UTF-8 encoding and nothing else." + # It also says + # "An additional caveat is that string parameters for files, + # paths, and other file-system entities must be in canonical + # UTF-8. In a canonical UTF-8 Unicode string, all decomposable + # characters are decomposed ..." + # but this is not true: You can pass non-decomposed UTF-8 strings + # to file system functions, and it is the OS which will convert + # them to decomposed UTF-8 before accessing the file system. + # - The Apple Terminal application displays UTF-8 by default. + # - However, other applications are free to use different encodings: + # - xterm uses ISO-8859-1 by default. + # - TextEdit uses MacRoman by default. + # We prefer UTF-8 over decomposed UTF-8-MAC because one should + # minimize the use of decomposed Unicode. Unfortunately, through the + # Darwin file system, decomposed UTF-8 strings are leaked into user + # space nevertheless. + echo "* UTF-8" + ;; + beos*) + # BeOS has a single locale, and it has UTF-8 encoding. + echo "* UTF-8" + ;; + msdosdjgpp*) + # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore + # localcharset.c falls back to using the full locale name + # from the environment variables. + echo "#" + echo "# The encodings given here may not all be correct." + echo "# If you find that the encoding given for your language and" + echo "# country is not the one your DOS machine actually uses, just" + echo "# correct it in this file, and send a mail to" + echo "# Juan Manuel Guerrero " + echo "# and Bruno Haible ." + echo "#" + echo "C ASCII" + # ISO-8859-1 languages + echo "ca CP850" + echo "ca_ES CP850" + echo "da CP865" # not CP850 ?? + echo "da_DK CP865" # not CP850 ?? + echo "de CP850" + echo "de_AT CP850" + echo "de_CH CP850" + echo "de_DE CP850" + echo "en CP850" + echo "en_AU CP850" # not CP437 ?? + echo "en_CA CP850" + echo "en_GB CP850" + echo "en_NZ CP437" + echo "en_US CP437" + echo "en_ZA CP850" # not CP437 ?? + echo "es CP850" + echo "es_AR CP850" + echo "es_BO CP850" + echo "es_CL CP850" + echo "es_CO CP850" + echo "es_CR CP850" + echo "es_CU CP850" + echo "es_DO CP850" + echo "es_EC CP850" + echo "es_ES CP850" + echo "es_GT CP850" + echo "es_HN CP850" + echo "es_MX CP850" + echo "es_NI CP850" + echo "es_PA CP850" + echo "es_PY CP850" + echo "es_PE CP850" + echo "es_SV CP850" + echo "es_UY CP850" + echo "es_VE CP850" + echo "et CP850" + echo "et_EE CP850" + echo "eu CP850" + echo "eu_ES CP850" + echo "fi CP850" + echo "fi_FI CP850" + echo "fr CP850" + echo "fr_BE CP850" + echo "fr_CA CP850" + echo "fr_CH CP850" + echo "fr_FR CP850" + echo "ga CP850" + echo "ga_IE CP850" + echo "gd CP850" + echo "gd_GB CP850" + echo "gl CP850" + echo "gl_ES CP850" + echo "id CP850" # not CP437 ?? + echo "id_ID CP850" # not CP437 ?? + echo "is CP861" # not CP850 ?? + echo "is_IS CP861" # not CP850 ?? + echo "it CP850" + echo "it_CH CP850" + echo "it_IT CP850" + echo "lt CP775" + echo "lt_LT CP775" + echo "lv CP775" + echo "lv_LV CP775" + echo "nb CP865" # not CP850 ?? + echo "nb_NO CP865" # not CP850 ?? + echo "nl CP850" + echo "nl_BE CP850" + echo "nl_NL CP850" + echo "nn CP865" # not CP850 ?? + echo "nn_NO CP865" # not CP850 ?? + echo "no CP865" # not CP850 ?? + echo "no_NO CP865" # not CP850 ?? + echo "pt CP850" + echo "pt_BR CP850" + echo "pt_PT CP850" + echo "sv CP850" + echo "sv_SE CP850" + # ISO-8859-2 languages + echo "cs CP852" + echo "cs_CZ CP852" + echo "hr CP852" + echo "hr_HR CP852" + echo "hu CP852" + echo "hu_HU CP852" + echo "pl CP852" + echo "pl_PL CP852" + echo "ro CP852" + echo "ro_RO CP852" + echo "sk CP852" + echo "sk_SK CP852" + echo "sl CP852" + echo "sl_SI CP852" + echo "sq CP852" + echo "sq_AL CP852" + echo "sr CP852" # CP852 or CP866 or CP855 ?? + echo "sr_CS CP852" # CP852 or CP866 or CP855 ?? + echo "sr_YU CP852" # CP852 or CP866 or CP855 ?? + # ISO-8859-3 languages + echo "mt CP850" + echo "mt_MT CP850" + # ISO-8859-5 languages + echo "be CP866" + echo "be_BE CP866" + echo "bg CP866" # not CP855 ?? + echo "bg_BG CP866" # not CP855 ?? + echo "mk CP866" # not CP855 ?? + echo "mk_MK CP866" # not CP855 ?? + echo "ru CP866" + echo "ru_RU CP866" + echo "uk CP1125" + echo "uk_UA CP1125" + # ISO-8859-6 languages + echo "ar CP864" + echo "ar_AE CP864" + echo "ar_DZ CP864" + echo "ar_EG CP864" + echo "ar_IQ CP864" + echo "ar_IR CP864" + echo "ar_JO CP864" + echo "ar_KW CP864" + echo "ar_MA CP864" + echo "ar_OM CP864" + echo "ar_QA CP864" + echo "ar_SA CP864" + echo "ar_SY CP864" + # ISO-8859-7 languages + echo "el CP869" + echo "el_GR CP869" + # ISO-8859-8 languages + echo "he CP862" + echo "he_IL CP862" + # ISO-8859-9 languages + echo "tr CP857" + echo "tr_TR CP857" + # Japanese + echo "ja CP932" + echo "ja_JP CP932" + # Chinese + echo "zh_CN GBK" + echo "zh_TW CP950" # not CP938 ?? + # Korean + echo "kr CP949" # not CP934 ?? + echo "kr_KR CP949" # not CP934 ?? + # Thai + echo "th CP874" + echo "th_TH CP874" + # Other + echo "eo CP850" + echo "eo_EO CP850" + ;; +esac diff --git a/glib/glib/libcharset/glibc21.m4 b/glib/glib/libcharset/glibc21.m4 new file mode 100644 index 0000000..d95fd98 --- /dev/null +++ b/glib/glib/libcharset/glibc21.m4 @@ -0,0 +1,30 @@ +# glibc21.m4 serial 3 +dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Test for the GNU C Library, version 2.1 or newer. +# From Bruno Haible. + +AC_DEFUN([gl_GLIBC21], + [ + AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer, + ac_cv_gnu_library_2_1, + [AC_EGREP_CPP([Lucky GNU user], + [ +#include +#ifdef __GNU_LIBRARY__ + #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2) + Lucky GNU user + #endif +#endif + ], + ac_cv_gnu_library_2_1=yes, + ac_cv_gnu_library_2_1=no) + ] + ) + AC_SUBST(GLIBC21) + GLIBC21="$ac_cv_gnu_library_2_1" + ] +) diff --git a/glib/glib/libcharset/libcharset-glib.patch b/glib/glib/libcharset/libcharset-glib.patch new file mode 100644 index 0000000..358d774 --- /dev/null +++ b/glib/glib/libcharset/libcharset-glib.patch @@ -0,0 +1,77 @@ +# Patch against libcharset version 1.4 +--- libiconv-1.12/libcharset//lib/localcharset.c 2006-10-18 07:55:49.000000000 -0400 ++++ localcharset.c 2008-05-20 18:36:24.000000000 -0400 +@@ -103,8 +103,8 @@ + static const char * volatile charset_aliases; + + /* Return a pointer to the contents of the charset.alias file. */ +-static const char * +-get_charset_aliases (void) ++const char * ++_g_locale_get_charset_aliases (void) + { + const char *cp; + +@@ -280,14 +280,10 @@ + If the canonical name cannot be determined, the result is a non-canonical + name. */ + +-#ifdef STATIC +-STATIC +-#endif + const char * +-locale_charset (void) ++_g_locale_charset_raw (void) + { + const char *codeset; +- const char *aliases; + + #if !(defined WIN32_NATIVE || defined OS2) + +@@ -436,12 +432,20 @@ + + #endif + ++ return codeset; ++} ++ ++const char * ++_g_locale_charset_unalias (const char *codeset) ++{ ++ const char *aliases; ++ + if (codeset == NULL) + /* The canonical name cannot be determined. */ + codeset = ""; + + /* Resolve alias. */ +- for (aliases = get_charset_aliases (); ++ for (aliases = _g_locale_get_charset_aliases (); + *aliases != '\0'; + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) + if (strcmp (codeset, aliases) == 0 +--- libiconv-1.12/libcharset//include/libcharset.h.in 2005-05-19 13:14:56.000000000 -0400 ++++ libcharset.h 2008-05-20 18:39:44.000000000 -0400 +@@ -19,7 +19,7 @@ + #ifndef _LIBCHARSET_H + #define _LIBCHARSET_H + +-#include ++#include "localcharset.h" + + + #ifdef __cplusplus +--- libiconv-1.12/libcharset//include/localcharset.h.in 2005-05-19 13:14:57.000000000 -0400 ++++ localcharset.h 2008-05-20 18:36:24.000000000 -0400 +@@ -31,8 +31,9 @@ + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ +-extern const char * locale_charset (void); +- ++extern const char * _g_locale_charset_raw (void); ++extern const char * _g_locale_charset_unalias (const char *codeset); ++extern const char * _g_locale_get_charset_aliases (void); + + #ifdef __cplusplus + } diff --git a/glib/glib/libcharset/libcharset.h b/glib/glib/libcharset/libcharset.h new file mode 100644 index 0000000..686241e --- /dev/null +++ b/glib/glib/libcharset/libcharset.h @@ -0,0 +1,46 @@ +/* Copyright (C) 2003 Free Software Foundation, Inc. + This file is part of the GNU CHARSET Library. + + The GNU CHARSET Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU CHARSET Library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with the GNU CHARSET Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +#ifndef _LIBCHARSET_H +#define _LIBCHARSET_H + +#include "localcharset.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Support for relocatable packages. */ + +/* Sets the original and the current installation prefix of the package. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +extern void libcharset_set_relocation_prefix (const char *orig_prefix, + const char *curr_prefix); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _LIBCHARSET_H */ diff --git a/glib/glib/libcharset/localcharset.c b/glib/glib/libcharset/localcharset.c new file mode 100644 index 0000000..0d001f9 --- /dev/null +++ b/glib/glib/libcharset/localcharset.c @@ -0,0 +1,465 @@ +/* Determine a canonical name for the current locale's character encoding. + + Copyright (C) 2000-2006 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +/* Written by Bruno Haible . */ + +#include "config.h" + +/* Specification. */ +#include "localcharset.h" + +#include +#include +#include +#include + +#if defined _WIN32 || defined __WIN32__ +# define WIN32_NATIVE +#endif + +#if defined __EMX__ +/* Assume EMX program runs on OS/2, even if compiled under DOS. */ +# define OS2 +#endif + +#if !defined WIN32_NATIVE +# if HAVE_LANGINFO_CODESET +# include +# else +# if 0 /* see comment below */ +# include +# endif +# endif +# ifdef __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +# endif +#elif defined WIN32_NATIVE +# define WIN32_LEAN_AND_MEAN +# include +#endif +#if defined OS2 +# define INCL_DOS +# include +#endif + +#if ENABLE_RELOCATABLE +# include "relocatable.h" +#else +# define relocate(pathname) (pathname) +#endif + +/* Get LIBDIR. */ +#ifndef LIBDIR +# include "configmake.h" +#endif + +#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Win32, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +#endif + +#ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +#endif + +#ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +#endif + +#if HAVE_DECL_GETC_UNLOCKED +# undef getc +# define getc getc_unlocked +#endif + +/* The following static variable is declared 'volatile' to avoid a + possible multithread problem in the function get_charset_aliases. If we + are running in a threaded environment, and if two threads initialize + 'charset_aliases' simultaneously, both will produce the same value, + and everything will be ok if the two assignments to 'charset_aliases' + are atomic. But I don't know what will happen if the two assignments mix. */ +#if __STDC__ != 1 +# define volatile /* empty */ +#endif +/* Pointer to the contents of the charset.alias file, if it has already been + read, else NULL. Its format is: + ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ +static const char * volatile charset_aliases; + +/* Return a pointer to the contents of the charset.alias file. */ +const char * +_g_locale_get_charset_aliases (void) +{ + const char *cp; + + cp = charset_aliases; + if (cp == NULL) + { +#if !(defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) + FILE *fp; + const char *dir; + const char *base = "charset.alias"; + char *file_name; + + /* Make it possible to override the charset.alias location. This is + necessary for running the testsuite before "make install". */ + dir = getenv ("CHARSETALIASDIR"); + if (dir == NULL || dir[0] == '\0') + dir = relocate (LIBDIR); + + /* Concatenate dir and base into freshly allocated file_name. */ + { + size_t dir_len = strlen (dir); + size_t base_len = strlen (base); + int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); + file_name = (char *) malloc (dir_len + add_slash + base_len + 1); + if (file_name != NULL) + { + memcpy (file_name, dir, dir_len); + if (add_slash) + file_name[dir_len] = DIRECTORY_SEPARATOR; + memcpy (file_name + dir_len + add_slash, base, base_len + 1); + } + } + + if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL) + /* Out of memory or file not found, treat it as empty. */ + cp = ""; + else + { + /* Parse the file's contents. */ + char *res_ptr = NULL; + size_t res_size = 0; + + for (;;) + { + int c; + char buf1[50+1]; + char buf2[50+1]; + size_t l1, l2; + char *old_res_ptr; + + c = getc (fp); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') + { + /* Skip comment, to end of line. */ + do + c = getc (fp); + while (!(c == EOF || c == '\n')); + if (c == EOF) + break; + continue; + } + ungetc (c, fp); + if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) + break; + l1 = strlen (buf1); + l2 = strlen (buf2); + old_res_ptr = res_ptr; + if (res_size == 0) + { + res_size = l1 + 1 + l2 + 1; + res_ptr = (char *) malloc (res_size + 1); + } + else + { + res_size += l1 + 1 + l2 + 1; + res_ptr = (char *) realloc (res_ptr, res_size + 1); + } + if (res_ptr == NULL) + { + /* Out of memory. */ + res_size = 0; + if (old_res_ptr != NULL) + free (old_res_ptr); + break; + } + strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); + strcpy (res_ptr + res_size - (l2 + 1), buf2); + } + fclose (fp); + if (res_size == 0) + cp = ""; + else + { + *(res_ptr + res_size) = '\0'; + cp = res_ptr; + } + } + + if (file_name != NULL) + free (file_name); + +#else + +# if defined VMS + /* To avoid the troubles of an extra file charset.alias_vms in the + sources of many GNU packages, simply inline the aliases here. */ + /* The list of encodings is taken from the OpenVMS 7.3-1 documentation + "Compaq C Run-Time Library Reference Manual for OpenVMS systems" + section 10.7 "Handling Different Character Sets". */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-8" "\0" "ISO-8859-8" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + /* Japanese */ + "eucJP" "\0" "EUC-JP" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "DECKANJI" "\0" "DEC-KANJI" "\0" + "SDECKANJI" "\0" "EUC-JP" "\0" + /* Chinese */ + "eucTW" "\0" "EUC-TW" "\0" + "DECHANYU" "\0" "DEC-HANYU" "\0" + "DECHANZI" "\0" "GB2312" "\0" + /* Korean */ + "DECKOREAN" "\0" "EUC-KR" "\0"; +# endif + +# if defined WIN32_NATIVE || defined __CYGWIN__ + /* To avoid the troubles of installing a separate file in the same + directory as the DLL and of retrieving the DLL's directory at + runtime, simply inline the aliases here. */ + + cp = "CP936" "\0" "GBK" "\0" + "CP1361" "\0" "JOHAB" "\0" + "CP20127" "\0" "ASCII" "\0" + "CP20866" "\0" "KOI8-R" "\0" + "CP20936" "\0" "GB2312" "\0" + "CP21866" "\0" "KOI8-RU" "\0" + "CP28591" "\0" "ISO-8859-1" "\0" + "CP28592" "\0" "ISO-8859-2" "\0" + "CP28593" "\0" "ISO-8859-3" "\0" + "CP28594" "\0" "ISO-8859-4" "\0" + "CP28595" "\0" "ISO-8859-5" "\0" + "CP28596" "\0" "ISO-8859-6" "\0" + "CP28597" "\0" "ISO-8859-7" "\0" + "CP28598" "\0" "ISO-8859-8" "\0" + "CP28599" "\0" "ISO-8859-9" "\0" + "CP28605" "\0" "ISO-8859-15" "\0" + "CP38598" "\0" "ISO-8859-8" "\0" + "CP51932" "\0" "EUC-JP" "\0" + "CP51936" "\0" "GB2312" "\0" + "CP51949" "\0" "EUC-KR" "\0" + "CP51950" "\0" "EUC-TW" "\0" + "CP54936" "\0" "GB18030" "\0" + "CP65001" "\0" "UTF-8" "\0"; +# endif +#endif + + charset_aliases = cp; + } + + return cp; +} + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ + +const char * +_g_locale_charset_raw (void) +{ + const char *codeset; + +#if !(defined WIN32_NATIVE || defined OS2) + +# if HAVE_LANGINFO_CODESET + + /* Most systems support nl_langinfo (CODESET) nowadays. */ + codeset = nl_langinfo (CODESET); + +# ifdef __CYGWIN__ + /* Cygwin 2006 does not have locales. nl_langinfo (CODESET) always + returns "US-ASCII". As long as this is not fixed, return the suffix + of the locale name from the environment variables (if present) or + the codepage as a number. */ + if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) + { + const char *locale; + static char buf[2 + 10 + 1]; + + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return + it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + } + + /* Woe32 has a function returning the locale's codepage as a number. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + } +# endif + +# else + + /* On old systems which lack it, use setlocale or getenv. */ + const char *locale = NULL; + + /* But most old systems don't have a complete set of locales. Some + (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't + use setlocale here; it would return "C" when it doesn't support the + locale name the user has set. */ +# if 0 + locale = setlocale (LC_CTYPE, NULL); +# endif + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + } + + /* On some old systems, one used to set locale = "iso8859_1". On others, + you set it to "language_COUNTRY.charset". In any case, we resolve it + through the charset.alias file. */ + codeset = locale; + +# endif + +#elif defined WIN32_NATIVE + + static char buf[2 + 10 + 1]; + + /* Woe32 has a function returning the locale's codepage as a number. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + +#elif defined OS2 + + const char *locale; + static char buf[2 + 10 + 1]; + ULONG cp[3]; + ULONG cplen; + + /* Allow user to override the codeset, as set in the operating system, + with standard language environment variables. */ + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + + /* Resolve through the charset.alias file. */ + codeset = locale; + } + else + { + /* OS/2 has a function returning the locale's codepage as a number. */ + if (DosQueryCp (sizeof (cp), cp, &cplen)) + codeset = ""; + else + { + sprintf (buf, "CP%u", cp[0]); + codeset = buf; + } + } + +#endif + + return codeset; +} + +const char * +_g_locale_charset_unalias (const char *codeset) +{ + const char *aliases; + + if (codeset == NULL) + /* The canonical name cannot be determined. */ + codeset = ""; + + /* Resolve alias. */ + for (aliases = _g_locale_get_charset_aliases (); + *aliases != '\0'; + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) + if (strcmp (codeset, aliases) == 0 + || (aliases[0] == '*' && aliases[1] == '\0')) + { + codeset = aliases + strlen (aliases) + 1; + break; + } + + /* Don't return an empty string. GNU libc and GNU libiconv interpret + the empty string as denoting "the locale's character encoding", + thus GNU libiconv would call this function a second time. */ + if (codeset[0] == '\0') + codeset = "ASCII"; + + return codeset; +} diff --git a/glib/glib/libcharset/localcharset.h b/glib/glib/libcharset/localcharset.h new file mode 100644 index 0000000..674aa3a --- /dev/null +++ b/glib/glib/libcharset/localcharset.h @@ -0,0 +1,43 @@ +/* Determine a canonical name for the current locale's character encoding. + Copyright (C) 2000-2003 Free Software Foundation, Inc. + This file is part of the GNU CHARSET Library. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifndef _LOCALCHARSET_H +#define _LOCALCHARSET_H + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ +extern const char * _g_locale_charset_raw (void); +extern const char * _g_locale_charset_unalias (const char *codeset); +extern const char * _g_locale_get_charset_aliases (void); + +#ifdef __cplusplus +} +#endif + + +#endif /* _LOCALCHARSET_H */ diff --git a/glib/glib/libcharset/make-patch.sh b/glib/glib/libcharset/make-patch.sh new file mode 100755 index 0000000..e60014a --- /dev/null +++ b/glib/glib/libcharset/make-patch.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +if test $# = 1 ; then + ORIGINAL=$1 +else + echo "Usage: make-patch.sh /path/to/libcharset" 1>&2 + exit 1 +fi + +if test -f $ORIGINAL/lib/localcharset.c ; then : ; else + echo "Usage: make-patch.sh /path/to/libcharset" 1>&2 + exit 1 +fi + +VERSION=`grep VERSION= $ORIGINAL/configure.ac | sed s/VERSION=//` + +echo "# Patch against libcharset version $VERSION" > libcharset-glib.patch + +for i in localcharset.c ref-add.sin ref-del.sin ; do + diff -u $ORIGINAL/lib/$i $i >> libcharset-glib.patch +done + +for i in glibc21.m4 codeset.m4 ; do + diff -u $ORIGINAL/m4/$i $i >> libcharset-glib.patch +done + +diff -u $ORIGINAL/include/libcharset.h.in libcharset.h >> libcharset-glib.patch +diff -u $ORIGINAL/include/localcharset.h.in localcharset.h >> libcharset-glib.patch diff --git a/glib/glib/libcharset/ref-add.sin b/glib/glib/libcharset/ref-add.sin new file mode 100644 index 0000000..0e2b97b --- /dev/null +++ b/glib/glib/libcharset/ref-add.sin @@ -0,0 +1,31 @@ +# Add this package to a list of references stored in a text file. +# +# Copyright (C) 2000 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published +# by the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. +# +# Written by Bruno Haible . +# +/^# Packages using this file: / { + s/# Packages using this file:// + ta + :a + s/ @PACKAGE@ / @PACKAGE@ / + tb + s/ $/ @PACKAGE@ / + :b + s/^/# Packages using this file:/ +} diff --git a/glib/glib/libcharset/ref-del.sin b/glib/glib/libcharset/ref-del.sin new file mode 100644 index 0000000..1fafbfc --- /dev/null +++ b/glib/glib/libcharset/ref-del.sin @@ -0,0 +1,26 @@ +# Remove this package from a list of references stored in a text file. +# +# Copyright (C) 2000 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU Library General Public License as published +# by the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program 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 +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, +# USA. +# +# Written by Bruno Haible . +# +/^# Packages using this file: / { + s/# Packages using this file:// + s/ @PACKAGE@ / / + s/^/# Packages using this file:/ +} diff --git a/glib/glib/libcharset/update.sh b/glib/glib/libcharset/update.sh new file mode 100755 index 0000000..5873fc7 --- /dev/null +++ b/glib/glib/libcharset/update.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +if test $# = 1 ; then + ORIGINAL=$1 +else + echo "Usage: update.sh /path/to/libcharset" 1>&2 + exit 1 +fi + +if test -f $ORIGINAL/lib/localcharset.c ; then : ; else + echo "Usage: update.sh /path/to/libcharset" 1>&2 + exit 1 +fi + +VERSION=`grep VERSION= $ORIGINAL/configure.ac | sed s/VERSION=//` + +for i in localcharset.c ref-add.sin ref-del.sin config.charset ; do + cp $ORIGINAL/lib/$i . +done + +for i in libcharset.h localcharset.h ; do + cp $ORIGINAL/include/$i.in ./$i +done + +for i in codeset.m4 glibc21.m4 ; do + cp $ORIGINAL/m4/$i . +done + +patch -p0 < libcharset-glib.patch + +echo "dnl From libcharset $VERSION" > ../../aclibcharset.m4 + + diff --git a/glib/glib/libglib-gdb.py.in b/glib/glib/libglib-gdb.py.in new file mode 100644 index 0000000..3e07c42 --- /dev/null +++ b/glib/glib/libglib-gdb.py.in @@ -0,0 +1,10 @@ +import sys +import gdb + +# Update module path. +dir_ = '@datadir@/glib-2.0/gdb' +if not dir_ in sys.path: + sys.path.insert(0, dir_) + +from glib import register +register (gdb.current_objfile ()) diff --git a/glib/glib/win_iconv.c b/glib/glib/win_iconv.c new file mode 100644 index 0000000..4ab1653 --- /dev/null +++ b/glib/glib/win_iconv.c @@ -0,0 +1,1965 @@ +/* + * iconv library implemented with Win32 API. + * + * This file is placed in the public domain. + * + * Maintainer: Yukihiro Nakadaira + * + * If $WINICONV_LIBICONV_DLL environment variable was defined, win_iconv + * loads the specified DLL dynamically and uses it. If loading the DLL + * or iconv_open() failed, falls back to internal conversion. + * $WINICONV_LIBICONV_DLL is a comma separated list. The first loadable + * DLL is used. The specified DLL should have iconv_open(), + * iconv_close() and iconv() functions. Or these functions can be + * libiconv_open(), libiconv_close() and libiconv(). + * + * Win32 API does not support strict encoding conversion for some + * codepage. And MLang function drop or replace invalid bytes and does + * not return useful error status as iconv. This implementation cannot + * be used for encoding validation purpose. + */ + +/* for WC_NO_BEST_FIT_CHARS */ +#ifndef WINVER +# define WINVER 0x0500 +#endif + +#define STRICT +#include +#include +#include +#include + +#if 0 +# define MAKE_EXE +# define MAKE_DLL +# define USE_LIBICONV_DLL +#endif + +#if !defined(DEFAULT_LIBICONV_DLL) +# define DEFAULT_LIBICONV_DLL "" +#endif + +#define MB_CHAR_MAX 16 + +#define UNICODE_MODE_BOM_DONE 1 +#define UNICODE_MODE_SWAPPED 2 + +#define FLAG_USE_BOM_ENDIAN 1 +#define FLAG_TRANSLIT 2 /* //TRANSLIT */ +#define FLAG_IGNORE 4 /* //IGNORE (not implemented) */ + +#define return_error(code) \ + do { \ + errno = code; \ + return -1; \ + } while (0) + +#define xstrlcpy(dst, src, size) \ + do { \ + strncpy(dst, src, size); \ + dst[size - 1] = 0; \ + } while (0) + +#define xstrlcpyn(dst, src, srclen, size) \ + xstrlcpy(dst, src, xmin((srclen) + 1, size)) + +#define xmin(a, b) ((a) < (b) ? (a) : (b)) +#define xmax(a, b) ((a) > (b) ? (a) : (b)) + +#define STATIC_STRLEN(arr) (sizeof(arr) - 1) + +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; + +typedef void* iconv_t; + +iconv_t iconv_open(const char *tocode, const char *fromcode); +int iconv_close(iconv_t cd); +size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); + +/* libiconv interface for vim */ +#if defined(MAKE_DLL) +int +iconvctl (iconv_t cd, int request, void* argument) +{ + /* not supported */ + return 0; +} +#endif + +typedef struct compat_t compat_t; +typedef struct csconv_t csconv_t; +typedef struct rec_iconv_t rec_iconv_t; + +typedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode); +typedef int (*f_iconv_close)(iconv_t cd); +typedef size_t (*f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); +typedef int* (*f_errno)(void); +typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize); +typedef int (*f_flush)(csconv_t *cv, uchar *buf, int bufsize); + +#define COMPAT_IN 1 +#define COMPAT_OUT 2 + +/* unicode mapping for compatibility with other conversion table. */ +struct compat_t { + uint in; + uint out; + uint flag; +}; + +struct csconv_t { + int codepage; + int flags; + f_mbtowc mbtowc; + f_wctomb wctomb; + f_mblen mblen; + f_flush flush; + DWORD mode; + compat_t *compat; +}; + +struct rec_iconv_t { + iconv_t cd; + f_iconv_close iconv_close; + f_iconv iconv; + f_errno _errno; + csconv_t from; + csconv_t to; +#if defined(USE_LIBICONV_DLL) + HMODULE hlibiconv; +#endif +}; + +static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); +static int win_iconv_close(iconv_t cd); +static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); + +static int load_mlang(); +static csconv_t make_csconv(const char *name); +static int name_to_codepage(const char *name); +static uint utf16_to_ucs4(const ushort *wbuf); +static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize); +static int is_unicode(int codepage); +static int mbtowc_flags(int codepage); +static int must_use_null_useddefaultchar(int codepage); +static void check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize); +static char *strrstr(const char *str, const char *token); + +#if defined(USE_LIBICONV_DLL) +static int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode); +static PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size); +static HMODULE find_imported_module_by_funcname(HMODULE hModule, const char *funcname); + +static HMODULE hwiniconv; +static HMODULE hlastdll; /* keep dll loaded for efficiency (unnecessary?) */ +#endif + +static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); +static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); +static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize); +static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize); +static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize); + +static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize); +static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize); +static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize); + +static struct { + int codepage; + const char *name; +} codepage_alias[] = { + {65001, "CP65001"}, + {65001, "UTF8"}, + {65001, "UTF-8"}, + + {1200, "CP1200"}, + {1200, "UTF16LE"}, + {1200, "UTF-16LE"}, + {1200, "UCS2LE"}, + {1200, "UCS-2LE"}, + + {1201, "CP1201"}, + {1201, "UTF16BE"}, + {1201, "UTF-16BE"}, + {1201, "UCS2BE"}, + {1201, "UCS-2BE"}, + {1201, "unicodeFFFE"}, + + {12000, "CP12000"}, + {12000, "UTF32LE"}, + {12000, "UTF-32LE"}, + {12000, "UCS4LE"}, + {12000, "UCS-4LE"}, + + {12001, "CP12001"}, + {12001, "UTF32BE"}, + {12001, "UTF-32BE"}, + {12001, "UCS4BE"}, + {12001, "UCS-4BE"}, + +#ifndef GLIB_COMPILATION + /* + * Default is big endian. + * See rfc2781 4.3 Interpreting text labelled as UTF-16. + */ + {1201, "UTF16"}, + {1201, "UTF-16"}, + {12001, "UTF32"}, + {12001, "UTF-32"}, + {12001, "UCS-4"}, + {12001, "UCS4"}, +#else + /* Default is little endian, because the platform is */ + {1200, "UTF16"}, + {1200, "UTF-16"}, + {1200, "UCS2"}, + {1200, "UCS-2"}, + {12000, "UTF32"}, + {12000, "UTF-32"}, + {12000, "UCS4"}, + {12000, "UCS-4"}, +#endif + + /* copy from libiconv `iconv -l` */ + /* !IsValidCodePage(367) */ + {20127, "ANSI_X3.4-1968"}, + {20127, "ANSI_X3.4-1986"}, + {20127, "ASCII"}, + {20127, "CP367"}, + {20127, "IBM367"}, + {20127, "ISO-IR-6"}, + {20127, "ISO646-US"}, + {20127, "ISO_646.IRV:1991"}, + {20127, "US"}, + {20127, "US-ASCII"}, + {20127, "CSASCII"}, + + /* !IsValidCodePage(819) */ + {1252, "CP819"}, + {1252, "IBM819"}, + {28591, "ISO-8859-1"}, + {28591, "ISO-IR-100"}, + {28591, "ISO8859-1"}, + {28591, "ISO_8859-1"}, + {28591, "ISO_8859-1:1987"}, + {28591, "L1"}, + {28591, "LATIN1"}, + {28591, "CSISOLATIN1"}, + + {1250, "CP1250"}, + {1250, "MS-EE"}, + {1250, "WINDOWS-1250"}, + + {1251, "CP1251"}, + {1251, "MS-CYRL"}, + {1251, "WINDOWS-1251"}, + + {1252, "CP1252"}, + {1252, "MS-ANSI"}, + {1252, "WINDOWS-1252"}, + + {1253, "CP1253"}, + {1253, "MS-GREEK"}, + {1253, "WINDOWS-1253"}, + + {1254, "CP1254"}, + {1254, "MS-TURK"}, + {1254, "WINDOWS-1254"}, + + {1255, "CP1255"}, + {1255, "MS-HEBR"}, + {1255, "WINDOWS-1255"}, + + {1256, "CP1256"}, + {1256, "MS-ARAB"}, + {1256, "WINDOWS-1256"}, + + {1257, "CP1257"}, + {1257, "WINBALTRIM"}, + {1257, "WINDOWS-1257"}, + + {1258, "CP1258"}, + {1258, "WINDOWS-1258"}, + + {850, "850"}, + {850, "CP850"}, + {850, "IBM850"}, + {850, "CSPC850MULTILINGUAL"}, + + /* !IsValidCodePage(862) */ + {862, "862"}, + {862, "CP862"}, + {862, "IBM862"}, + {862, "CSPC862LATINHEBREW"}, + + {866, "866"}, + {866, "CP866"}, + {866, "IBM866"}, + {866, "CSIBM866"}, + + /* !IsValidCodePage(154) */ + {154, "CP154"}, + {154, "CYRILLIC-ASIAN"}, + {154, "PT154"}, + {154, "PTCP154"}, + {154, "CSPTCP154"}, + + /* !IsValidCodePage(1133) */ + {1133, "CP1133"}, + {1133, "IBM-CP1133"}, + + {874, "CP874"}, + {874, "WINDOWS-874"}, + + /* !IsValidCodePage(51932) */ + {51932, "CP51932"}, + {51932, "MS51932"}, + {51932, "WINDOWS-51932"}, + {51932, "EUC-JP"}, + + {932, "CP932"}, + {932, "MS932"}, + {932, "SHIFFT_JIS"}, + {932, "SHIFFT_JIS-MS"}, + {932, "SJIS"}, + {932, "SJIS-MS"}, + {932, "SJIS-OPEN"}, + {932, "SJIS-WIN"}, + {932, "WINDOWS-31J"}, + {932, "WINDOWS-932"}, + {932, "CSWINDOWS31J"}, + + {50221, "CP50221"}, + {50221, "ISO-2022-JP"}, + {50221, "ISO-2022-JP-MS"}, + {50221, "ISO2022-JP"}, + {50221, "ISO2022-JP-MS"}, + {50221, "MS50221"}, + {50221, "WINDOWS-50221"}, + + {936, "CP936"}, + {936, "GBK"}, + {936, "MS936"}, + {936, "WINDOWS-936"}, + + {950, "CP950"}, + {950, "BIG5"}, + + {949, "CP949"}, + {949, "UHC"}, + {949, "EUC-KR"}, + + {1361, "CP1361"}, + {1361, "JOHAB"}, + + {437, "437"}, + {437, "CP437"}, + {437, "IBM437"}, + {437, "CSPC8CODEPAGE437"}, + + {737, "CP737"}, + + {775, "CP775"}, + {775, "IBM775"}, + {775, "CSPC775BALTIC"}, + + {852, "852"}, + {852, "CP852"}, + {852, "IBM852"}, + {852, "CSPCP852"}, + + /* !IsValidCodePage(853) */ + {853, "CP853"}, + + {855, "855"}, + {855, "CP855"}, + {855, "IBM855"}, + {855, "CSIBM855"}, + + {857, "857"}, + {857, "CP857"}, + {857, "IBM857"}, + {857, "CSIBM857"}, + + /* !IsValidCodePage(858) */ + {858, "CP858"}, + + {860, "860"}, + {860, "CP860"}, + {860, "IBM860"}, + {860, "CSIBM860"}, + + {861, "861"}, + {861, "CP-IS"}, + {861, "CP861"}, + {861, "IBM861"}, + {861, "CSIBM861"}, + + {863, "863"}, + {863, "CP863"}, + {863, "IBM863"}, + {863, "CSIBM863"}, + + {864, "CP864"}, + {864, "IBM864"}, + {864, "CSIBM864"}, + + {865, "865"}, + {865, "CP865"}, + {865, "IBM865"}, + {865, "CSIBM865"}, + + {869, "869"}, + {869, "CP-GR"}, + {869, "CP869"}, + {869, "IBM869"}, + {869, "CSIBM869"}, + + /* !IsValidCodePage(1152) */ + {1125, "CP1125"}, + + /* + * Code Page Identifiers + * http://msdn2.microsoft.com/en-us/library/ms776446.aspx + */ + {37, "IBM037"}, /* IBM EBCDIC US-Canada */ + {437, "IBM437"}, /* OEM United States */ + {500, "IBM500"}, /* IBM EBCDIC International */ + {708, "ASMO-708"}, /* Arabic (ASMO 708) */ + /* 709 Arabic (ASMO-449+, BCON V4) */ + /* 710 Arabic - Transparent Arabic */ + {720, "DOS-720"}, /* Arabic (Transparent ASMO); Arabic (DOS) */ + {737, "ibm737"}, /* OEM Greek (formerly 437G); Greek (DOS) */ + {775, "ibm775"}, /* OEM Baltic; Baltic (DOS) */ + {850, "ibm850"}, /* OEM Multilingual Latin 1; Western European (DOS) */ + {852, "ibm852"}, /* OEM Latin 2; Central European (DOS) */ + {855, "IBM855"}, /* OEM Cyrillic (primarily Russian) */ + {857, "ibm857"}, /* OEM Turkish; Turkish (DOS) */ + {858, "IBM00858"}, /* OEM Multilingual Latin 1 + Euro symbol */ + {860, "IBM860"}, /* OEM Portuguese; Portuguese (DOS) */ + {861, "ibm861"}, /* OEM Icelandic; Icelandic (DOS) */ + {862, "DOS-862"}, /* OEM Hebrew; Hebrew (DOS) */ + {863, "IBM863"}, /* OEM French Canadian; French Canadian (DOS) */ + {864, "IBM864"}, /* OEM Arabic; Arabic (864) */ + {865, "IBM865"}, /* OEM Nordic; Nordic (DOS) */ + {866, "cp866"}, /* OEM Russian; Cyrillic (DOS) */ + {869, "ibm869"}, /* OEM Modern Greek; Greek, Modern (DOS) */ + {870, "IBM870"}, /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */ + {874, "windows-874"}, /* ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows) */ + {875, "cp875"}, /* IBM EBCDIC Greek Modern */ + {932, "shift_jis"}, /* ANSI/OEM Japanese; Japanese (Shift-JIS) */ + {932, "shift-jis"}, /* alternative name for it */ + {936, "gb2312"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */ + {949, "ks_c_5601-1987"}, /* ANSI/OEM Korean (Unified Hangul Code) */ + {950, "big5"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */ + {1026, "IBM1026"}, /* IBM EBCDIC Turkish (Latin 5) */ + {1047, "IBM01047"}, /* IBM EBCDIC Latin 1/Open System */ + {1140, "IBM01140"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */ + {1141, "IBM01141"}, /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */ + {1142, "IBM01142"}, /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */ + {1143, "IBM01143"}, /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */ + {1144, "IBM01144"}, /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */ + {1145, "IBM01145"}, /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */ + {1146, "IBM01146"}, /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */ + {1147, "IBM01147"}, /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */ + {1148, "IBM01148"}, /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */ + {1149, "IBM01149"}, /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */ + {1250, "windows-1250"}, /* ANSI Central European; Central European (Windows) */ + {1251, "windows-1251"}, /* ANSI Cyrillic; Cyrillic (Windows) */ + {1252, "windows-1252"}, /* ANSI Latin 1; Western European (Windows) */ + {1253, "windows-1253"}, /* ANSI Greek; Greek (Windows) */ + {1254, "windows-1254"}, /* ANSI Turkish; Turkish (Windows) */ + {1255, "windows-1255"}, /* ANSI Hebrew; Hebrew (Windows) */ + {1256, "windows-1256"}, /* ANSI Arabic; Arabic (Windows) */ + {1257, "windows-1257"}, /* ANSI Baltic; Baltic (Windows) */ + {1258, "windows-1258"}, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */ + {1361, "Johab"}, /* Korean (Johab) */ + {10000, "macintosh"}, /* MAC Roman; Western European (Mac) */ + {10001, "x-mac-japanese"}, /* Japanese (Mac) */ + {10002, "x-mac-chinesetrad"}, /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */ + {10003, "x-mac-korean"}, /* Korean (Mac) */ + {10004, "x-mac-arabic"}, /* Arabic (Mac) */ + {10005, "x-mac-hebrew"}, /* Hebrew (Mac) */ + {10006, "x-mac-greek"}, /* Greek (Mac) */ + {10007, "x-mac-cyrillic"}, /* Cyrillic (Mac) */ + {10008, "x-mac-chinesesimp"}, /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */ + {10010, "x-mac-romanian"}, /* Romanian (Mac) */ + {10017, "x-mac-ukrainian"}, /* Ukrainian (Mac) */ + {10021, "x-mac-thai"}, /* Thai (Mac) */ + {10029, "x-mac-ce"}, /* MAC Latin 2; Central European (Mac) */ + {10079, "x-mac-icelandic"}, /* Icelandic (Mac) */ + {10081, "x-mac-turkish"}, /* Turkish (Mac) */ + {10082, "x-mac-croatian"}, /* Croatian (Mac) */ + {20000, "x-Chinese_CNS"}, /* CNS Taiwan; Chinese Traditional (CNS) */ + {20001, "x-cp20001"}, /* TCA Taiwan */ + {20002, "x_Chinese-Eten"}, /* Eten Taiwan; Chinese Traditional (Eten) */ + {20003, "x-cp20003"}, /* IBM5550 Taiwan */ + {20004, "x-cp20004"}, /* TeleText Taiwan */ + {20005, "x-cp20005"}, /* Wang Taiwan */ + {20105, "x-IA5"}, /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */ + {20106, "x-IA5-German"}, /* IA5 German (7-bit) */ + {20107, "x-IA5-Swedish"}, /* IA5 Swedish (7-bit) */ + {20108, "x-IA5-Norwegian"}, /* IA5 Norwegian (7-bit) */ + {20127, "us-ascii"}, /* US-ASCII (7-bit) */ + {20261, "x-cp20261"}, /* T.61 */ + {20269, "x-cp20269"}, /* ISO 6937 Non-Spacing Accent */ + {20273, "IBM273"}, /* IBM EBCDIC Germany */ + {20277, "IBM277"}, /* IBM EBCDIC Denmark-Norway */ + {20278, "IBM278"}, /* IBM EBCDIC Finland-Sweden */ + {20280, "IBM280"}, /* IBM EBCDIC Italy */ + {20284, "IBM284"}, /* IBM EBCDIC Latin America-Spain */ + {20285, "IBM285"}, /* IBM EBCDIC United Kingdom */ + {20290, "IBM290"}, /* IBM EBCDIC Japanese Katakana Extended */ + {20297, "IBM297"}, /* IBM EBCDIC France */ + {20420, "IBM420"}, /* IBM EBCDIC Arabic */ + {20423, "IBM423"}, /* IBM EBCDIC Greek */ + {20424, "IBM424"}, /* IBM EBCDIC Hebrew */ + {20833, "x-EBCDIC-KoreanExtended"}, /* IBM EBCDIC Korean Extended */ + {20838, "IBM-Thai"}, /* IBM EBCDIC Thai */ + {20866, "koi8-r"}, /* Russian (KOI8-R); Cyrillic (KOI8-R) */ + {20871, "IBM871"}, /* IBM EBCDIC Icelandic */ + {20880, "IBM880"}, /* IBM EBCDIC Cyrillic Russian */ + {20905, "IBM905"}, /* IBM EBCDIC Turkish */ + {20924, "IBM00924"}, /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */ + {20932, "EUC-JP"}, /* Japanese (JIS 0208-1990 and 0121-1990) */ + {20936, "x-cp20936"}, /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */ + {20949, "x-cp20949"}, /* Korean Wansung */ + {21025, "cp1025"}, /* IBM EBCDIC Cyrillic Serbian-Bulgarian */ + /* 21027 (deprecated) */ + {21866, "koi8-u"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */ + {28591, "iso-8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */ + {28591, "iso8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */ + {28592, "iso-8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */ + {28592, "iso8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */ + {28593, "iso-8859-3"}, /* ISO 8859-3 Latin 3 */ + {28593, "iso8859-3"}, /* ISO 8859-3 Latin 3 */ + {28594, "iso-8859-4"}, /* ISO 8859-4 Baltic */ + {28594, "iso8859-4"}, /* ISO 8859-4 Baltic */ + {28595, "iso-8859-5"}, /* ISO 8859-5 Cyrillic */ + {28595, "iso8859-5"}, /* ISO 8859-5 Cyrillic */ + {28596, "iso-8859-6"}, /* ISO 8859-6 Arabic */ + {28596, "iso8859-6"}, /* ISO 8859-6 Arabic */ + {28597, "iso-8859-7"}, /* ISO 8859-7 Greek */ + {28597, "iso8859-7"}, /* ISO 8859-7 Greek */ + {28598, "iso-8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */ + {28598, "iso8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */ + {28599, "iso-8859-9"}, /* ISO 8859-9 Turkish */ + {28599, "iso8859-9"}, /* ISO 8859-9 Turkish */ + {28603, "iso-8859-13"}, /* ISO 8859-13 Estonian */ + {28603, "iso8859-13"}, /* ISO 8859-13 Estonian */ + {28605, "iso-8859-15"}, /* ISO 8859-15 Latin 9 */ + {28605, "iso8859-15"}, /* ISO 8859-15 Latin 9 */ + {29001, "x-Europa"}, /* Europa 3 */ + {38598, "iso-8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */ + {38598, "iso8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */ + {50220, "iso-2022-jp"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */ + {50221, "csISO2022JP"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */ + {50222, "iso-2022-jp"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */ + {50225, "iso-2022-kr"}, /* ISO 2022 Korean */ + {50225, "iso2022-kr"}, /* ISO 2022 Korean */ + {50227, "x-cp50227"}, /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */ + /* 50229 ISO 2022 Traditional Chinese */ + /* 50930 EBCDIC Japanese (Katakana) Extended */ + /* 50931 EBCDIC US-Canada and Japanese */ + /* 50933 EBCDIC Korean Extended and Korean */ + /* 50935 EBCDIC Simplified Chinese Extended and Simplified Chinese */ + /* 50936 EBCDIC Simplified Chinese */ + /* 50937 EBCDIC US-Canada and Traditional Chinese */ + /* 50939 EBCDIC Japanese (Latin) Extended and Japanese */ + {51932, "euc-jp"}, /* EUC Japanese */ + {51936, "EUC-CN"}, /* EUC Simplified Chinese; Chinese Simplified (EUC) */ + {51949, "euc-kr"}, /* EUC Korean */ + /* 51950 EUC Traditional Chinese */ + {52936, "hz-gb-2312"}, /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */ + {54936, "GB18030"}, /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */ + {57002, "x-iscii-de"}, /* ISCII Devanagari */ + {57003, "x-iscii-be"}, /* ISCII Bengali */ + {57004, "x-iscii-ta"}, /* ISCII Tamil */ + {57005, "x-iscii-te"}, /* ISCII Telugu */ + {57006, "x-iscii-as"}, /* ISCII Assamese */ + {57007, "x-iscii-or"}, /* ISCII Oriya */ + {57008, "x-iscii-ka"}, /* ISCII Kannada */ + {57009, "x-iscii-ma"}, /* ISCII Malayalam */ + {57010, "x-iscii-gu"}, /* ISCII Gujarati */ + {57011, "x-iscii-pa"}, /* ISCII Punjabi */ + + {0, NULL} +}; + +/* + * SJIS SHIFTJIS table CP932 table + * ---- --------------------------- -------------------------------- + * 5C U+00A5 YEN SIGN U+005C REVERSE SOLIDUS + * 7E U+203E OVERLINE U+007E TILDE + * 815C U+2014 EM DASH U+2015 HORIZONTAL BAR + * 815F U+005C REVERSE SOLIDUS U+FF3C FULLWIDTH REVERSE SOLIDUS + * 8160 U+301C WAVE DASH U+FF5E FULLWIDTH TILDE + * 8161 U+2016 DOUBLE VERTICAL LINE U+2225 PARALLEL TO + * 817C U+2212 MINUS SIGN U+FF0D FULLWIDTH HYPHEN-MINUS + * 8191 U+00A2 CENT SIGN U+FFE0 FULLWIDTH CENT SIGN + * 8192 U+00A3 POUND SIGN U+FFE1 FULLWIDTH POUND SIGN + * 81CA U+00AC NOT SIGN U+FFE2 FULLWIDTH NOT SIGN + * + * EUC-JP and ISO-2022-JP should be compatible with CP932. + * + * Kernel and MLang have different Unicode mapping table. Make sure + * which API is used. + */ +static compat_t cp932_compat[] = { + {0x00A5, 0x005C, COMPAT_OUT}, + {0x203E, 0x007E, COMPAT_OUT}, + {0x2014, 0x2015, COMPAT_OUT}, + {0x301C, 0xFF5E, COMPAT_OUT}, + {0x2016, 0x2225, COMPAT_OUT}, + {0x2212, 0xFF0D, COMPAT_OUT}, + {0x00A2, 0xFFE0, COMPAT_OUT}, + {0x00A3, 0xFFE1, COMPAT_OUT}, + {0x00AC, 0xFFE2, COMPAT_OUT}, + {0, 0, 0} +}; + +static compat_t cp20932_compat[] = { + {0x00A5, 0x005C, COMPAT_OUT}, + {0x203E, 0x007E, COMPAT_OUT}, + {0x2014, 0x2015, COMPAT_OUT}, + {0xFF5E, 0x301C, COMPAT_OUT|COMPAT_IN}, + {0x2225, 0x2016, COMPAT_OUT|COMPAT_IN}, + {0xFF0D, 0x2212, COMPAT_OUT|COMPAT_IN}, + {0xFFE0, 0x00A2, COMPAT_OUT|COMPAT_IN}, + {0xFFE1, 0x00A3, COMPAT_OUT|COMPAT_IN}, + {0xFFE2, 0x00AC, COMPAT_OUT|COMPAT_IN}, + {0, 0, 0} +}; + +static compat_t *cp51932_compat = cp932_compat; + +/* cp20932_compat for kernel. cp932_compat for mlang. */ +static compat_t *cp5022x_compat = cp932_compat; + +typedef HRESULT (WINAPI *CONVERTINETSTRING)( + LPDWORD lpdwMode, + DWORD dwSrcEncoding, + DWORD dwDstEncoding, + LPCSTR lpSrcStr, + LPINT lpnSrcSize, + LPBYTE lpDstStr, + LPINT lpnDstSize +); +typedef HRESULT (WINAPI *CONVERTINETMULTIBYTETOUNICODE)( + LPDWORD lpdwMode, + DWORD dwSrcEncoding, + LPCSTR lpSrcStr, + LPINT lpnMultiCharCount, + LPWSTR lpDstStr, + LPINT lpnWideCharCount +); +typedef HRESULT (WINAPI *CONVERTINETUNICODETOMULTIBYTE)( + LPDWORD lpdwMode, + DWORD dwEncoding, + LPCWSTR lpSrcStr, + LPINT lpnWideCharCount, + LPSTR lpDstStr, + LPINT lpnMultiCharCount +); +typedef HRESULT (WINAPI *ISCONVERTINETSTRINGAVAILABLE)( + DWORD dwSrcEncoding, + DWORD dwDstEncoding +); +typedef HRESULT (WINAPI *LCIDTORFC1766A)( + LCID Locale, + LPSTR pszRfc1766, + int nChar +); +typedef HRESULT (WINAPI *LCIDTORFC1766W)( + LCID Locale, + LPWSTR pszRfc1766, + int nChar +); +typedef HRESULT (WINAPI *RFC1766TOLCIDA)( + LCID *pLocale, + LPSTR pszRfc1766 +); +typedef HRESULT (WINAPI *RFC1766TOLCIDW)( + LCID *pLocale, + LPWSTR pszRfc1766 +); +static CONVERTINETSTRING ConvertINetString; +static CONVERTINETMULTIBYTETOUNICODE ConvertINetMultiByteToUnicode; +static CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte; +static ISCONVERTINETSTRINGAVAILABLE IsConvertINetStringAvailable; +static LCIDTORFC1766A LcidToRfc1766A; +static RFC1766TOLCIDA Rfc1766ToLcidA; + +static int +load_mlang() +{ + HMODULE h = NULL; + char mlang_dll[MAX_PATH + 100]; + int n; + if (ConvertINetString != NULL) + return TRUE; + n = GetSystemDirectory(mlang_dll, MAX_PATH); + if (n > 0 && n < MAX_PATH) + { + if (mlang_dll[n-1] != '\\' && + mlang_dll[n-1] != '/') + strcat(mlang_dll, "\\"); + strcat(mlang_dll, "mlang.dll"); + h = LoadLibrary(mlang_dll); + } + if (!h) + return FALSE; + ConvertINetString = (CONVERTINETSTRING)GetProcAddress(h, "ConvertINetString"); + ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode"); + ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte"); + IsConvertINetStringAvailable = (ISCONVERTINETSTRINGAVAILABLE)GetProcAddress(h, "IsConvertINetStringAvailable"); + LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddress(h, "LcidToRfc1766A"); + Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddress(h, "Rfc1766ToLcidA"); + return TRUE; +} + +iconv_t +iconv_open(const char *tocode, const char *fromcode) +{ + rec_iconv_t *cd; + + cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t)); + if (cd == NULL) + { + errno = ENOMEM; + return (iconv_t)(-1); + } + +#if defined(USE_LIBICONV_DLL) + if (libiconv_iconv_open(cd, tocode, fromcode)) + return (iconv_t)cd; +#endif + + if (win_iconv_open(cd, tocode, fromcode)) + return (iconv_t)cd; + + free(cd); + errno = EINVAL; + return (iconv_t)(-1); +} + +int +iconv_close(iconv_t _cd) +{ + rec_iconv_t *cd = (rec_iconv_t *)_cd; + int r = cd->iconv_close(cd->cd); + int e = *(cd->_errno()); +#if defined(USE_LIBICONV_DLL) + if (cd->hlibiconv != NULL) + FreeLibrary(cd->hlibiconv); +#endif + free(cd); + errno = e; + return r; +} + +size_t +iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) +{ + rec_iconv_t *cd = (rec_iconv_t *)_cd; + size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft); + errno = *(cd->_errno()); + return r; +} + +static int +win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode) +{ + cd->from = make_csconv(fromcode); + cd->to = make_csconv(tocode); + if (cd->from.codepage == -1 || cd->to.codepage == -1) + return FALSE; + cd->iconv_close = win_iconv_close; + cd->iconv = win_iconv; + cd->_errno = _errno; + cd->cd = (iconv_t)cd; + return TRUE; +} + +static int +win_iconv_close(iconv_t cd) +{ + return 0; +} + +static size_t +win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft) +{ + rec_iconv_t *cd = (rec_iconv_t *)_cd; + ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */ + int insize; + int outsize; + int wsize; + DWORD mode; + uint wc; + compat_t *cp; + int i; + + if (inbuf == NULL || *inbuf == NULL) + { + if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL) + { + outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft); + if (outsize == -1) + return (size_t)(-1); + *outbuf += outsize; + *outbytesleft -= outsize; + } + if (is_unicode(cd->from.codepage) && (cd->from.mode & UNICODE_MODE_SWAPPED)) + cd->from.codepage ^= 1; + cd->from.mode = 0; + cd->to.mode = 0; + return 0; + } + + while (*inbytesleft != 0) + { + mode = cd->from.mode; + wsize = MB_CHAR_MAX; + + insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize); + if (insize == -1) + return (size_t)(-1); + + if (is_unicode(cd->from.codepage) && !(cd->from.mode & UNICODE_MODE_BOM_DONE)) + { + check_utf_bom(cd, wbuf, &wsize); + cd->from.mode |= UNICODE_MODE_BOM_DONE; + } + + if (wsize == 0) + { + *inbuf += insize; + *inbytesleft -= insize; + continue; + } + + if (cd->from.compat != NULL) + { + wc = utf16_to_ucs4(wbuf); + cp = cd->from.compat; + for (i = 0; cp[i].in != 0; ++i) + { + if ((cp[i].flag & COMPAT_IN) && cp[i].out == wc) + { + ucs4_to_utf16(cp[i].in, wbuf, &wsize); + break; + } + } + } + + if (cd->to.compat != NULL) + { + wc = utf16_to_ucs4(wbuf); + cp = cd->to.compat; + for (i = 0; cp[i].in != 0; ++i) + { + if ((cp[i].flag & COMPAT_OUT) && cp[i].in == wc) + { + ucs4_to_utf16(cp[i].out, wbuf, &wsize); + break; + } + } + } + + outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft); + if (outsize == -1) + { + cd->from.mode = mode; + return (size_t)(-1); + } + + *inbuf += insize; + *outbuf += outsize; + *inbytesleft -= insize; + *outbytesleft -= outsize; + } + + return 0; +} + +static csconv_t +make_csconv(const char *_name) +{ + CPINFOEX cpinfoex; + csconv_t cv; + int use_compat = TRUE; + int flag = 0; + char name[128]; + char *p; + + xstrlcpy(name, _name, sizeof(name)); + + /* check for option "enc_name//opt1//opt2" */ + while ((p = strrstr(name, "//")) != NULL) + { + if (_stricmp(p + 2, "nocompat") == 0) + use_compat = FALSE; + else if (_stricmp(p + 2, "translit") == 0) + flag |= FLAG_TRANSLIT; + else if (_stricmp(p + 2, "ignore") == 0) + flag |= FLAG_IGNORE; + *p = 0; + } + + cv.mode = 0; + cv.flags = flag; + cv.mblen = NULL; + cv.flush = NULL; + cv.compat = NULL; + cv.codepage = name_to_codepage(name); + if (cv.codepage == 1200 || cv.codepage == 1201) + { + cv.mbtowc = utf16_mbtowc; + cv.wctomb = utf16_wctomb; + if (_stricmp(name, "UTF-16") == 0 || + _stricmp(name, "UTF16") == 0 || + _stricmp(name, "UCS-2") == 0 || + _stricmp(name, "UCS2") == 0) + cv.flags |= FLAG_USE_BOM_ENDIAN; + } + else if (cv.codepage == 12000 || cv.codepage == 12001) + { + cv.mbtowc = utf32_mbtowc; + cv.wctomb = utf32_wctomb; + if (_stricmp(name, "UTF-32") == 0 || + _stricmp(name, "UTF32") == 0 || + _stricmp(name, "UCS-4") == 0 || + _stricmp(name, "UCS4") == 0) + cv.flags |= FLAG_USE_BOM_ENDIAN; + } + else if (cv.codepage == 65001) + { + cv.mbtowc = kernel_mbtowc; + cv.wctomb = kernel_wctomb; + cv.mblen = utf8_mblen; + } + else if ((cv.codepage == 50220 || cv.codepage == 50221 || cv.codepage == 50222) && load_mlang()) + { + cv.mbtowc = iso2022jp_mbtowc; + cv.wctomb = iso2022jp_wctomb; + cv.flush = iso2022jp_flush; + } + else if (cv.codepage == 51932 && load_mlang()) + { + cv.mbtowc = mlang_mbtowc; + cv.wctomb = mlang_wctomb; + cv.mblen = eucjp_mblen; + } + else if (IsValidCodePage(cv.codepage) + && GetCPInfoEx(cv.codepage, 0, &cpinfoex) != 0) + { + cv.mbtowc = kernel_mbtowc; + cv.wctomb = kernel_wctomb; + if (cpinfoex.MaxCharSize == 1) + cv.mblen = sbcs_mblen; + else if (cpinfoex.MaxCharSize == 2) + cv.mblen = dbcs_mblen; + else + cv.mblen = mbcs_mblen; + } + else + { + /* not supported */ + cv.codepage = -1; + } + if (use_compat) + { + switch (cv.codepage) + { + case 932: cv.compat = cp932_compat; break; + case 20932: cv.compat = cp20932_compat; break; + case 51932: cv.compat = cp51932_compat; break; + case 50220: case 50221: case 50222: cv.compat = cp5022x_compat; break; + } + } + return cv; +} + +static int +name_to_codepage(const char *name) +{ + int i; + + if (*name == '\0' || + strcmp(name, "char") == 0) + return GetACP(); + else if (strcmp(name, "wchar_t") == 0) + return 1200; + else if (_strnicmp(name, "cp", 2) == 0) + return atoi(name + 2); /* CP123 */ + else if ('0' <= name[0] && name[0] <= '9') + return atoi(name); /* 123 */ + else if (_strnicmp(name, "xx", 2) == 0) + return atoi(name + 2); /* XX123 for debug */ + + for (i = 0; codepage_alias[i].name != NULL; ++i) + if (_stricmp(name, codepage_alias[i].name) == 0) + return codepage_alias[i].codepage; + return -1; +} + +/* + * http://www.faqs.org/rfcs/rfc2781.html + */ +static uint +utf16_to_ucs4(const ushort *wbuf) +{ + uint wc = wbuf[0]; + if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) + wc = ((wbuf[0] & 0x3FF) << 10) + (wbuf[1] & 0x3FF) + 0x10000; + return wc; +} + +static void +ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize) +{ + if (wc < 0x10000) + { + wbuf[0] = wc; + *wbufsize = 1; + } + else + { + wc -= 0x10000; + wbuf[0] = 0xD800 | ((wc >> 10) & 0x3FF); + wbuf[1] = 0xDC00 | (wc & 0x3FF); + *wbufsize = 2; + } +} + +static int +is_unicode(int codepage) +{ + return (codepage == 1200 || codepage == 1201 || + codepage == 12000 || codepage == 12001 || + codepage == 65000 || codepage == 65001); +} + +/* + * Check if codepage is one of those for which the dwFlags parameter + * to MultiByteToWideChar() must be zero. Return zero or + * MB_ERR_INVALID_CHARS. The docs in Platform SDK for for Windows + * Server 2003 R2 claims that also codepage 65001 is one of these, but + * that doesn't seem to be the case. The MSDN docs for MSVS2008 leave + * out 65001 (UTF-8), and that indeed seems to be the case on XP, it + * works fine to pass MB_ERR_INVALID_CHARS in dwFlags when converting + * from UTF-8. + */ +static int +mbtowc_flags(int codepage) +{ + return (codepage == 50220 || codepage == 50221 || + codepage == 50222 || codepage == 50225 || + codepage == 50227 || codepage == 50229 || + codepage == 52936 || codepage == 54936 || + (codepage >= 57002 && codepage <= 57011) || + codepage == 65000 || codepage == 42) ? 0 : MB_ERR_INVALID_CHARS; +} + +/* + * Check if codepage is one those for which the lpUsedDefaultChar + * parameter to WideCharToMultiByte() must be NULL. The docs in + * Platform SDK for for Windows Server 2003 R2 claims that this is the + * list below, while the MSDN docs for MSVS2008 claim that it is only + * for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform + * SDK seems to be correct, at least for XP. + */ +static int +must_use_null_useddefaultchar(int codepage) +{ + return (codepage == 65000 || codepage == 65001 || + codepage == 50220 || codepage == 50221 || + codepage == 50222 || codepage == 50225 || + codepage == 50227 || codepage == 50229 || + codepage == 52936 || codepage == 54936 || + (codepage >= 57002 && codepage <= 57011) || + codepage == 42); +} + +static void +check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize) +{ + /* If we have a BOM, trust it, despite what the caller said */ + if (wbuf[0] == 0xFFFE && (cd->from.flags & FLAG_USE_BOM_ENDIAN)) + { + /* swap endian: 1200 <-> 1201 or 12000 <-> 12001 */ + cd->from.codepage ^= 1; + cd->from.mode |= UNICODE_MODE_SWAPPED; + wbuf[0] = 0xFEFF; + } + + /* + * Remove BOM. + * Don't do this if "to" is Unicode, + * except if "to" is UTF-8. + */ + if (wbuf[0] == 0xFEFF && (!is_unicode(cd->to.codepage) || cd->to.codepage == 65001)) + *wbufsize = 0; +} + +static char * +strrstr(const char *str, const char *token) +{ + int len = strlen(token); + const char *p = str + strlen(str); + + while (str <= --p) + if (p[0] == token[0] && strncmp(p, token, len) == 0) + return (char *)p; + return NULL; +} + +#if defined(USE_LIBICONV_DLL) +static int +libiconv_iconv_open(rec_iconv_t *cd, const char *fromcode, const char *tocode) +{ + HMODULE hlibiconv = NULL; + HMODULE hmsvcrt = NULL; + char dllname[_MAX_PATH]; + const char *p; + const char *e; + f_iconv_open _iconv_open; + + /* + * always try to load dll, so that we can switch dll in runtime. + */ + + /* XXX: getenv() can't get variable set by SetEnvironmentVariable() */ + p = getenv("WINICONV_LIBICONV_DLL"); + if (p == NULL) + p = DEFAULT_LIBICONV_DLL; + /* parse comma separated value */ + for ( ; *p != 0; p = (*e == ',') ? e + 1 : e) + { + e = strchr(p, ','); + if (p == e) + continue; + else if (e == NULL) + e = p + strlen(p); + xstrlcpyn(dllname, p, e - p, sizeof(dllname)); + hlibiconv = LoadLibrary(dllname); + if (hlibiconv != NULL) + { + if (hlibiconv == hwiniconv) + { + FreeLibrary(hlibiconv); + hlibiconv = NULL; + continue; + } + break; + } + } + + if (hlastdll != NULL) + { + /* decrement reference count */ + FreeLibrary(hlastdll); + hlastdll = NULL; + } + + if (hlibiconv == NULL) + goto failed; + + hmsvcrt = find_imported_module_by_funcname(hlibiconv, "_errno"); + if (hmsvcrt == NULL) + goto failed; + + _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "libiconv_open"); + if (_iconv_open == NULL) + _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "iconv_open"); + cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "libiconv_close"); + if (cd->iconv_close == NULL) + cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "iconv_close"); + cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "libiconv"); + if (cd->iconv == NULL) + cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "iconv"); + cd->_errno = (f_errno)GetProcAddress(hmsvcrt, "_errno"); + if (_iconv_open == NULL || cd->iconv_close == NULL + || cd->iconv == NULL || cd->_errno == NULL) + goto failed; + + /* increment reference count */ + hlastdll = LoadLibrary(dllname); + + cd->cd = _iconv_open(tocode, fromcode); + if (cd->cd == (iconv_t)(-1)) + goto failed; + + cd->hlibiconv = hlibiconv; + return TRUE; + +failed: + if (hlibiconv != NULL) + FreeLibrary(hlibiconv); + /* do not free hmsvcrt which is obtained by GetModuleHandle() */ + return FALSE; +} + +/* + * Reference: + * http://forums.belution.com/ja/vc/000/234/78s.shtml + * http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html + * + * The formal way is + * imagehlp.h or dbghelp.h + * imagehlp.lib or dbghelp.lib + * ImageDirectoryEntryToData() + */ +#define TO_DOS_HEADER(base) ((PIMAGE_DOS_HEADER)(base)) +#define TO_NT_HEADERS(base) ((PIMAGE_NT_HEADERS)((LPBYTE)(base) + TO_DOS_HEADER(base)->e_lfanew)) +static PVOID +MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size) +{ + /* TODO: MappedAsImage? */ + PIMAGE_DATA_DIRECTORY p; + p = TO_NT_HEADERS(Base)->OptionalHeader.DataDirectory + DirectoryEntry; + if (p->VirtualAddress == 0) { + *Size = 0; + return NULL; + } + *Size = p->Size; + return (PVOID)((LPBYTE)Base + p->VirtualAddress); +} + +static HMODULE +find_imported_module_by_funcname(HMODULE hModule, const char *funcname) +{ + DWORD Base; + ULONG Size; + PIMAGE_IMPORT_DESCRIPTOR Imp; + PIMAGE_THUNK_DATA Name; /* Import Name Table */ + PIMAGE_IMPORT_BY_NAME ImpName; + + Base = (DWORD)hModule; + Imp = MyImageDirectoryEntryToData( + (LPVOID)Base, + TRUE, + IMAGE_DIRECTORY_ENTRY_IMPORT, + &Size); + if (Imp == NULL) + return NULL; + for ( ; Imp->OriginalFirstThunk != 0; ++Imp) + { + Name = (PIMAGE_THUNK_DATA)(Base + Imp->OriginalFirstThunk); + for ( ; Name->u1.Ordinal != 0; ++Name) + { + if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal)) + { + ImpName = (PIMAGE_IMPORT_BY_NAME) + (Base + (DWORD)Name->u1.AddressOfData); + if (strcmp((char *)ImpName->Name, funcname) == 0) + return GetModuleHandle((char *)(Base + Imp->Name)); + } + } + } + return NULL; +} +#endif + +static int +sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) +{ + return 1; +} + +static int +dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) +{ + int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1; + if (bufsize < len) + return_error(EINVAL); + return len; +} + +static int +mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize) +{ + int len = 0; + + if (cv->codepage == 54936) { + if (buf[0] <= 0x7F) len = 1; + else if (buf[0] >= 0x81 && buf[0] <= 0xFE && + bufsize >= 2 && + ((buf[1] >= 0x40 && buf[1] <= 0x7E) || + (buf[1] >= 0x80 && buf[1] <= 0xFE))) len = 2; + else if (buf[0] >= 0x81 && buf[0] <= 0xFE && + bufsize >= 4 && + buf[1] >= 0x30 && buf[1] <= 0x39) len = 4; + else + return_error(EINVAL); + return len; + } + else + return_error(EINVAL); +} + +static int +utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize) +{ + int len = 0; + + if (buf[0] < 0x80) len = 1; + else if ((buf[0] & 0xE0) == 0xC0) len = 2; + else if ((buf[0] & 0xF0) == 0xE0) len = 3; + else if ((buf[0] & 0xF8) == 0xF0) len = 4; + else if ((buf[0] & 0xFC) == 0xF8) len = 5; + else if ((buf[0] & 0xFE) == 0xFC) len = 6; + + if (len == 0) + return_error(EILSEQ); + else if (bufsize < len) + return_error(EINVAL); + return len; +} + +static int +eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize) +{ + if (buf[0] < 0x80) /* ASCII */ + return 1; + else if (buf[0] == 0x8E) /* JIS X 0201 */ + { + if (bufsize < 2) + return_error(EINVAL); + else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF)) + return_error(EILSEQ); + return 2; + } + else if (buf[0] == 0x8F) /* JIS X 0212 */ + { + if (bufsize < 3) + return_error(EINVAL); + else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE) + || !(0xA1 <= buf[2] && buf[2] <= 0xFE)) + return_error(EILSEQ); + return 3; + } + else /* JIS X 0208 */ + { + if (bufsize < 2) + return_error(EINVAL); + else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE) + || !(0xA1 <= buf[1] && buf[1] <= 0xFE)) + return_error(EILSEQ); + return 2; + } +} + +static int +kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + int len; + + len = cv->mblen(cv, buf, bufsize); + if (len == -1) + return -1; + /* If converting from ASCII, reject 8bit + * chars. MultiByteToWideChar() doesn't. Note that for ASCII we + * know that the mblen function is sbcs_mblen() so len is 1. + */ + if (cv->codepage == 20127 && buf[0] >= 0x80) + return_error(EILSEQ); + *wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage), + (const char *)buf, len, (wchar_t *)wbuf, *wbufsize); + if (*wbufsize == 0) + return_error(EILSEQ); + return len; +} + +static int +kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + BOOL usedDefaultChar = 0; + BOOL *p = NULL; + int flags = 0; + int len; + + if (bufsize == 0) + return_error(E2BIG); + if (!must_use_null_useddefaultchar(cv->codepage)) + { + p = &usedDefaultChar; +#ifdef WC_NO_BEST_FIT_CHARS + if (!(cv->flags & FLAG_TRANSLIT)) + flags |= WC_NO_BEST_FIT_CHARS; +#endif + } + len = WideCharToMultiByte(cv->codepage, flags, + (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p); + if (len == 0) + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + return_error(E2BIG); + return_error(EILSEQ); + } + else if (usedDefaultChar) + return_error(EILSEQ); + else if (cv->mblen(cv, buf, len) != len) /* validate result */ + return_error(EILSEQ); + return len; +} + +/* + * It seems that the mode (cv->mode) is fixnum. + * For example, when converting iso-2022-jp(cp50221) to unicode: + * in ascii sequence: mode=0xC42C0000 + * in jisx0208 sequence: mode=0xC42C0001 + * "C42C" is same for each convert session. + * It should be: ((codepage-1)<<16)|state + */ +static int +mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + int len; + int insize; + HRESULT hr; + + len = cv->mblen(cv, buf, bufsize); + if (len == -1) + return -1; + insize = len; + hr = ConvertINetMultiByteToUnicode(&cv->mode, cv->codepage, + (const char *)buf, &insize, (wchar_t *)wbuf, wbufsize); + if (hr != S_OK || insize != len) + return_error(EILSEQ); + return len; +} + +static int +mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + char tmpbuf[MB_CHAR_MAX]; /* enough room for one character */ + int tmpsize = MB_CHAR_MAX; + int insize = wbufsize; + HRESULT hr; + + hr = ConvertINetUnicodeToMultiByte(&cv->mode, cv->codepage, + (const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize); + if (hr != S_OK || insize != wbufsize) + return_error(EILSEQ); + else if (bufsize < tmpsize) + return_error(E2BIG); + else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize) + return_error(EILSEQ); + memcpy(buf, tmpbuf, tmpsize); + return tmpsize; +} + +static int +utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + if (bufsize < 2) + return_error(EINVAL); + if (cv->codepage == 1200) /* little endian */ + wbuf[0] = (buf[1] << 8) | buf[0]; + else if (cv->codepage == 1201) /* big endian */ + wbuf[0] = (buf[0] << 8) | buf[1]; + if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF) + return_error(EILSEQ); + if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) + { + if (bufsize < 4) + return_error(EINVAL); + if (cv->codepage == 1200) /* little endian */ + wbuf[1] = (buf[3] << 8) | buf[2]; + else if (cv->codepage == 1201) /* big endian */ + wbuf[1] = (buf[2] << 8) | buf[3]; + if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF)) + return_error(EILSEQ); + *wbufsize = 2; + return 4; + } + *wbufsize = 1; + return 2; +} + +static int +utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + if (bufsize < 2) + return_error(E2BIG); + if (cv->codepage == 1200) /* little endian */ + { + buf[0] = (wbuf[0] & 0x00FF); + buf[1] = (wbuf[0] & 0xFF00) >> 8; + } + else if (cv->codepage == 1201) /* big endian */ + { + buf[0] = (wbuf[0] & 0xFF00) >> 8; + buf[1] = (wbuf[0] & 0x00FF); + } + if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF) + { + if (bufsize < 4) + return_error(E2BIG); + if (cv->codepage == 1200) /* little endian */ + { + buf[2] = (wbuf[1] & 0x00FF); + buf[3] = (wbuf[1] & 0xFF00) >> 8; + } + else if (cv->codepage == 1201) /* big endian */ + { + buf[2] = (wbuf[1] & 0xFF00) >> 8; + buf[3] = (wbuf[1] & 0x00FF); + } + return 4; + } + return 2; +} + +static int +utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + uint wc; + + if (bufsize < 4) + return_error(EINVAL); + if (cv->codepage == 12000) /* little endian */ + wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0]; + else if (cv->codepage == 12001) /* big endian */ + wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc) + return_error(EILSEQ); + ucs4_to_utf16(wc, wbuf, wbufsize); + return 4; +} + +static int +utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + uint wc; + + if (bufsize < 4) + return_error(E2BIG); + wc = utf16_to_ucs4(wbuf); + if (cv->codepage == 12000) /* little endian */ + { + buf[0] = wc & 0x000000FF; + buf[1] = (wc & 0x0000FF00) >> 8; + buf[2] = (wc & 0x00FF0000) >> 16; + buf[3] = (wc & 0xFF000000) >> 24; + } + else if (cv->codepage == 12001) /* big endian */ + { + buf[0] = (wc & 0xFF000000) >> 24; + buf[1] = (wc & 0x00FF0000) >> 16; + buf[2] = (wc & 0x0000FF00) >> 8; + buf[3] = wc & 0x000000FF; + } + return 4; +} + +/* + * 50220: ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) + * 50221: ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow + * 1 byte Kana) + * 50222: ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte + * Kana - SO/SI) + * + * MultiByteToWideChar() and WideCharToMultiByte() behave differently + * depending on Windows version. On XP, WideCharToMultiByte() doesn't + * terminate result sequence with ascii escape. But Vista does. + * Use MLang instead. + */ + +#define ISO2022_MODE(cs, shift) (((cs) << 8) | (shift)) +#define ISO2022_MODE_CS(mode) (((mode) >> 8) & 0xFF) +#define ISO2022_MODE_SHIFT(mode) ((mode) & 0xFF) + +#define ISO2022_SI 0 +#define ISO2022_SO 1 + +/* shift in */ +static const char iso2022_SI_seq[] = "\x0F"; +/* shift out */ +static const char iso2022_SO_seq[] = "\x0E"; + +typedef struct iso2022_esc_t iso2022_esc_t; +struct iso2022_esc_t { + const char *esc; + int esc_len; + int len; + int cs; +}; + +#define ISO2022JP_CS_ASCII 0 +#define ISO2022JP_CS_JISX0201_ROMAN 1 +#define ISO2022JP_CS_JISX0201_KANA 2 +#define ISO2022JP_CS_JISX0208_1978 3 +#define ISO2022JP_CS_JISX0208_1983 4 +#define ISO2022JP_CS_JISX0212 5 + +static iso2022_esc_t iso2022jp_esc[] = { + {"\x1B\x28\x42", 3, 1, ISO2022JP_CS_ASCII}, + {"\x1B\x28\x4A", 3, 1, ISO2022JP_CS_JISX0201_ROMAN}, + {"\x1B\x28\x49", 3, 1, ISO2022JP_CS_JISX0201_KANA}, + {"\x1B\x24\x40", 3, 2, ISO2022JP_CS_JISX0208_1983}, /* unify 1978 with 1983 */ + {"\x1B\x24\x42", 3, 2, ISO2022JP_CS_JISX0208_1983}, + {"\x1B\x24\x28\x44", 4, 2, ISO2022JP_CS_JISX0212}, + {NULL, 0, 0, 0} +}; + +static int +iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize) +{ + iso2022_esc_t *iesc = iso2022jp_esc; + char tmp[MB_CHAR_MAX]; + int insize; + HRESULT hr; + DWORD dummy = 0; + int len; + int esc_len; + int cs; + int shift; + int i; + + if (buf[0] == 0x1B) + { + for (i = 0; iesc[i].esc != NULL; ++i) + { + esc_len = iesc[i].esc_len; + if (bufsize < esc_len) + { + if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0) + return_error(EINVAL); + } + else + { + if (strncmp((char *)buf, iesc[i].esc, esc_len) == 0) + { + cv->mode = ISO2022_MODE(iesc[i].cs, ISO2022_SI); + *wbufsize = 0; + return esc_len; + } + } + } + /* not supported escape sequence */ + return_error(EILSEQ); + } + else if (buf[0] == iso2022_SO_seq[0]) + { + cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SO); + *wbufsize = 0; + return 1; + } + else if (buf[0] == iso2022_SI_seq[0]) + { + cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SI); + *wbufsize = 0; + return 1; + } + + cs = ISO2022_MODE_CS(cv->mode); + shift = ISO2022_MODE_SHIFT(cv->mode); + + /* reset the mode for informal sequence */ + if (buf[0] < 0x20) + { + cs = ISO2022JP_CS_ASCII; + shift = ISO2022_SI; + } + + len = iesc[cs].len; + if (bufsize < len) + return_error(EINVAL); + for (i = 0; i < len; ++i) + if (!(buf[i] < 0x80)) + return_error(EILSEQ); + esc_len = iesc[cs].esc_len; + memcpy(tmp, iesc[cs].esc, esc_len); + if (shift == ISO2022_SO) + { + memcpy(tmp + esc_len, iso2022_SO_seq, 1); + esc_len += 1; + } + memcpy(tmp + esc_len, buf, len); + + if ((cv->codepage == 50220 || cv->codepage == 50221 + || cv->codepage == 50222) && shift == ISO2022_SO) + { + /* XXX: shift-out cannot be used for mbtowc (both kernel and + * mlang) */ + esc_len = iesc[ISO2022JP_CS_JISX0201_KANA].esc_len; + memcpy(tmp, iesc[ISO2022JP_CS_JISX0201_KANA].esc, esc_len); + memcpy(tmp + esc_len, buf, len); + } + + insize = len + esc_len; + hr = ConvertINetMultiByteToUnicode(&dummy, cv->codepage, + (const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize); + if (hr != S_OK || insize != len + esc_len) + return_error(EILSEQ); + + /* Check for conversion error. Assuming defaultChar is 0x3F. */ + /* ascii should be converted from ascii */ + if (wbuf[0] == buf[0] + && cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI)) + return_error(EILSEQ); + + /* reset the mode for informal sequence */ + if (cv->mode != ISO2022_MODE(cs, shift)) + cv->mode = ISO2022_MODE(cs, shift); + + return len; +} + +static int +iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize) +{ + iso2022_esc_t *iesc = iso2022jp_esc; + char tmp[MB_CHAR_MAX]; + int tmpsize = MB_CHAR_MAX; + int insize = wbufsize; + HRESULT hr; + DWORD dummy = 0; + int len; + int esc_len; + int cs; + int shift; + int i; + + /* + * MultiByte = [escape sequence] + character + [escape sequence] + * + * Whether trailing escape sequence is added depends on which API is + * used (kernel or MLang, and its version). + */ + hr = ConvertINetUnicodeToMultiByte(&dummy, cv->codepage, + (const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize); + if (hr != S_OK || insize != wbufsize) + return_error(EILSEQ); + else if (bufsize < tmpsize) + return_error(E2BIG); + + if (tmpsize == 1) + { + cs = ISO2022JP_CS_ASCII; + esc_len = 0; + } + else + { + for (i = 1; iesc[i].esc != NULL; ++i) + { + esc_len = iesc[i].esc_len; + if (strncmp(tmp, iesc[i].esc, esc_len) == 0) + { + cs = iesc[i].cs; + break; + } + } + if (iesc[i].esc == NULL) + /* not supported escape sequence */ + return_error(EILSEQ); + } + + shift = ISO2022_SI; + if (tmp[esc_len] == iso2022_SO_seq[0]) + { + shift = ISO2022_SO; + esc_len += 1; + } + + len = iesc[cs].len; + + /* Check for converting error. Assuming defaultChar is 0x3F. */ + /* ascii should be converted from ascii */ + if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80)) + return_error(EILSEQ); + else if (tmpsize < esc_len + len) + return_error(EILSEQ); + + if (cv->mode == ISO2022_MODE(cs, shift)) + { + /* remove escape sequence */ + if (esc_len != 0) + memmove(tmp, tmp + esc_len, len); + esc_len = 0; + } + else + { + if (cs == ISO2022JP_CS_ASCII) + { + esc_len = iesc[ISO2022JP_CS_ASCII].esc_len; + memmove(tmp + esc_len, tmp, len); + memcpy(tmp, iesc[ISO2022JP_CS_ASCII].esc, esc_len); + } + if (ISO2022_MODE_SHIFT(cv->mode) == ISO2022_SO) + { + /* shift-in before changing to other mode */ + memmove(tmp + 1, tmp, len + esc_len); + memcpy(tmp, iso2022_SI_seq, 1); + esc_len += 1; + } + } + + if (bufsize < len + esc_len) + return_error(E2BIG); + memcpy(buf, tmp, len + esc_len); + cv->mode = ISO2022_MODE(cs, shift); + return len + esc_len; +} + +static int +iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize) +{ + iso2022_esc_t *iesc = iso2022jp_esc; + int esc_len; + + if (cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI)) + { + esc_len = 0; + if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI) + esc_len += 1; + if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII) + esc_len += iesc[ISO2022JP_CS_ASCII].esc_len; + if (bufsize < esc_len) + return_error(E2BIG); + + esc_len = 0; + if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI) + { + memcpy(buf, iso2022_SI_seq, 1); + esc_len += 1; + } + if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII) + { + memcpy(buf + esc_len, iesc[ISO2022JP_CS_ASCII].esc, + iesc[ISO2022JP_CS_ASCII].esc_len); + esc_len += iesc[ISO2022JP_CS_ASCII].esc_len; + } + return esc_len; + } + return 0; +} + +#if defined(MAKE_DLL) && defined(USE_LIBICONV_DLL) +BOOL WINAPI +DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) +{ + switch( fdwReason ) + { + case DLL_PROCESS_ATTACH: + hwiniconv = (HMODULE)hinstDLL; + break; + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +#if defined(MAKE_EXE) +#include +#include +#include +int +main(int argc, char **argv) +{ + char *fromcode = NULL; + char *tocode = NULL; + int i; + char inbuf[BUFSIZ]; + char outbuf[BUFSIZ]; + const char *pin; + char *pout; + size_t inbytesleft; + size_t outbytesleft; + size_t rest = 0; + iconv_t cd; + size_t r; + FILE *in = stdin; + + _setmode(_fileno(stdin), _O_BINARY); + _setmode(_fileno(stdout), _O_BINARY); + + for (i = 1; i < argc; ++i) + { + if (strcmp(argv[i], "-l") == 0) + { + for (i = 0; codepage_alias[i].name != NULL; ++i) + printf("%s\n", codepage_alias[i].name); + return 0; + } + + if (strcmp(argv[i], "-f") == 0) + fromcode = argv[++i]; + else if (strcmp(argv[i], "-t") == 0) + tocode = argv[++i]; + else + { + in = fopen(argv[i], "rb"); + if (in == NULL) + { + fprintf(stderr, "cannot open %s\n", argv[i]); + return 1; + } + break; + } + } + + if (fromcode == NULL || tocode == NULL) + { + printf("usage: %s -f from-enc -t to-enc [file]\n", argv[0]); + return 0; + } + + cd = iconv_open(tocode, fromcode); + if (cd == (iconv_t)(-1)) + { + perror("iconv_open error"); + return 1; + } + + while ((inbytesleft = fread(inbuf + rest, 1, sizeof(inbuf) - rest, in)) != 0 + || rest != 0) + { + inbytesleft += rest; + pin = inbuf; + pout = outbuf; + outbytesleft = sizeof(outbuf); + r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft); + fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout); + if (r == (size_t)(-1) && errno != EINVAL && errno != E2BIG) + { + perror("conversion error"); + return 1; + } + memmove(inbuf, pin, inbytesleft); + rest = inbytesleft; + } + pout = outbuf; + outbytesleft = sizeof(outbuf); + r = iconv(cd, NULL, NULL, &pout, &outbytesleft); + fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout); + if (r == (size_t)(-1)) + { + perror("conversion error"); + return 1; + } + + iconv_close(cd); + + return 0; +} +#endif diff --git a/glib/m4macros/.gitignore b/glib/m4macros/.gitignore new file mode 100644 index 0000000..d59889a --- /dev/null +++ b/glib/m4macros/.gitignore @@ -0,0 +1,6 @@ +libtool.m4 +ltoptions.m4 +ltsugar.m4 +ltversion.m4 +lt~obsolete.m4 +gtk-doc.m4 diff --git a/glib/m4macros/Makefile.am b/glib/m4macros/Makefile.am new file mode 100644 index 0000000..75a9ca0 --- /dev/null +++ b/glib/m4macros/Makefile.am @@ -0,0 +1,8 @@ +include $(top_srcdir)/Makefile.decl + +installed_m4= glib-2.0.m4 glib-gettext.m4 gsettings.m4 + +EXTRA_DIST+=$(installed_m4) + +m4datadir = $(datadir)/aclocal +m4data_DATA = $(installed_m4) diff --git a/glib/m4macros/glib-2.0.m4 b/glib/m4macros/glib-2.0.m4 new file mode 100644 index 0000000..0507b76 --- /dev/null +++ b/glib/m4macros/glib-2.0.m4 @@ -0,0 +1,214 @@ +# Configure paths for GLIB +# Owen Taylor 1997-2001 + +dnl AM_PATH_GLIB_2_0([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND [, MODULES]]]]) +dnl Test for GLIB, and define GLIB_CFLAGS and GLIB_LIBS, if gmodule, gobject, +dnl gthread, or gio is specified in MODULES, pass to pkg-config +dnl +AC_DEFUN([AM_PATH_GLIB_2_0], +[dnl +dnl Get the cflags and libraries from pkg-config +dnl +AC_ARG_ENABLE(glibtest, [ --disable-glibtest do not try to compile and run a test GLIB program], + , enable_glibtest=yes) + + pkg_config_args=glib-2.0 + for module in . $4 + do + case "$module" in + gmodule) + pkg_config_args="$pkg_config_args gmodule-2.0" + ;; + gmodule-no-export) + pkg_config_args="$pkg_config_args gmodule-no-export-2.0" + ;; + gobject) + pkg_config_args="$pkg_config_args gobject-2.0" + ;; + gthread) + pkg_config_args="$pkg_config_args gthread-2.0" + ;; + gio*) + pkg_config_args="$pkg_config_args $module-2.0" + ;; + esac + done + + PKG_PROG_PKG_CONFIG([0.16]) + + no_glib="" + + if test "x$PKG_CONFIG" = x ; then + no_glib=yes + PKG_CONFIG=no + fi + + min_glib_version=ifelse([$1], ,2.0.0,$1) + AC_MSG_CHECKING(for GLIB - version >= $min_glib_version) + + if test x$PKG_CONFIG != xno ; then + ## don't try to run the test against uninstalled libtool libs + if $PKG_CONFIG --uninstalled $pkg_config_args; then + echo "Will use uninstalled version of GLib found in PKG_CONFIG_PATH" + enable_glibtest=no + fi + + if $PKG_CONFIG --atleast-version $min_glib_version $pkg_config_args; then + : + else + no_glib=yes + fi + fi + + if test x"$no_glib" = x ; then + GLIB_GENMARSHAL=`$PKG_CONFIG --variable=glib_genmarshal glib-2.0` + GOBJECT_QUERY=`$PKG_CONFIG --variable=gobject_query glib-2.0` + GLIB_MKENUMS=`$PKG_CONFIG --variable=glib_mkenums glib-2.0` + GLIB_COMPILE_RESOURCES=`$PKG_CONFIG --variable=glib_compile_resources gio-2.0` + + GLIB_CFLAGS=`$PKG_CONFIG --cflags $pkg_config_args` + GLIB_LIBS=`$PKG_CONFIG --libs $pkg_config_args` + glib_config_major_version=`$PKG_CONFIG --modversion glib-2.0 | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + glib_config_minor_version=`$PKG_CONFIG --modversion glib-2.0 | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + glib_config_micro_version=`$PKG_CONFIG --modversion glib-2.0 | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_glibtest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GLIB_CFLAGS" + LIBS="$GLIB_LIBS $LIBS" +dnl +dnl Now check if the installed GLIB is sufficiently new. (Also sanity +dnl checks the results of pkg-config to some extent) +dnl + rm -f conf.glibtest + AC_TRY_RUN([ +#include +#include +#include + +int +main () +{ + unsigned int major, minor, micro; + char *tmp_version; + + fclose (fopen ("conf.glibtest", "w")); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = g_strdup("$min_glib_version"); + if (sscanf(tmp_version, "%u.%u.%u", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_glib_version"); + exit(1); + } + + if ((glib_major_version != $glib_config_major_version) || + (glib_minor_version != $glib_config_minor_version) || + (glib_micro_version != $glib_config_micro_version)) + { + printf("\n*** 'pkg-config --modversion glib-2.0' returned %d.%d.%d, but GLIB (%d.%d.%d)\n", + $glib_config_major_version, $glib_config_minor_version, $glib_config_micro_version, + glib_major_version, glib_minor_version, glib_micro_version); + printf ("*** was found! If pkg-config was correct, then it is best\n"); + printf ("*** to remove the old version of GLib. You may also be able to fix the error\n"); + printf("*** by modifying your LD_LIBRARY_PATH enviroment variable, or by editing\n"); + printf("*** /etc/ld.so.conf. Make sure you have run ldconfig if that is\n"); + printf("*** required on your system.\n"); + printf("*** If pkg-config was wrong, set the environment variable PKG_CONFIG_PATH\n"); + printf("*** to point to the correct configuration files\n"); + } + else if ((glib_major_version != GLIB_MAJOR_VERSION) || + (glib_minor_version != GLIB_MINOR_VERSION) || + (glib_micro_version != GLIB_MICRO_VERSION)) + { + printf("*** GLIB header files (version %d.%d.%d) do not match\n", + GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION); + printf("*** library (version %d.%d.%d)\n", + glib_major_version, glib_minor_version, glib_micro_version); + } + else + { + if ((glib_major_version > major) || + ((glib_major_version == major) && (glib_minor_version > minor)) || + ((glib_major_version == major) && (glib_minor_version == minor) && (glib_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** An old version of GLIB (%u.%u.%u) was found.\n", + glib_major_version, glib_minor_version, glib_micro_version); + printf("*** You need a version of GLIB newer than %u.%u.%u. The latest version of\n", + major, minor, micro); + printf("*** GLIB is always available from ftp://ftp.gtk.org.\n"); + printf("***\n"); + printf("*** If you have already installed a sufficiently new version, this error\n"); + printf("*** probably means that the wrong copy of the pkg-config shell script is\n"); + printf("*** being found. The easiest way to fix this is to remove the old version\n"); + printf("*** of GLIB, but you can also set the PKG_CONFIG environment to point to the\n"); + printf("*** correct copy of pkg-config. (In this case, you will have to\n"); + printf("*** modify your LD_LIBRARY_PATH enviroment variable, or edit /etc/ld.so.conf\n"); + printf("*** so that the correct libraries are found at run-time))\n"); + } + } + return 1; +} +],, no_glib=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_glib" = x ; then + AC_MSG_RESULT(yes (version $glib_config_major_version.$glib_config_minor_version.$glib_config_micro_version)) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$PKG_CONFIG" = "no" ; then + echo "*** A new enough version of pkg-config was not found." + echo "*** See http://www.freedesktop.org/software/pkgconfig/" + else + if test -f conf.glibtest ; then + : + else + echo "*** Could not run GLIB test program, checking why..." + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GLIB_CFLAGS" + LIBS="$LIBS $GLIB_LIBS" + AC_TRY_LINK([ +#include +#include +], [ return ((glib_major_version) || (glib_minor_version) || (glib_micro_version)); ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding GLIB or finding the wrong" + echo "*** version of GLIB. If it is not finding GLIB, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means GLIB is incorrectly installed."]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + GLIB_CFLAGS="" + GLIB_LIBS="" + GLIB_GENMARSHAL="" + GOBJECT_QUERY="" + GLIB_MKENUMS="" + GLIB_COMPILE_RESOURCES="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(GLIB_CFLAGS) + AC_SUBST(GLIB_LIBS) + AC_SUBST(GLIB_GENMARSHAL) + AC_SUBST(GOBJECT_QUERY) + AC_SUBST(GLIB_MKENUMS) + AC_SUBST(GLIB_COMPILE_RESOURCES) + rm -f conf.glibtest +]) diff --git a/glib/m4macros/glib-gettext.m4 b/glib/m4macros/glib-gettext.m4 new file mode 100644 index 0000000..c64e64f --- /dev/null +++ b/glib/m4macros/glib-gettext.m4 @@ -0,0 +1,436 @@ +# Copyright (C) 1995-2002 Free Software Foundation, Inc. +# Copyright (C) 2001-2003,2004 Red Hat, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# This file can be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# +# Macro to add for using GNU gettext. +# Ulrich Drepper , 1995, 1996 +# +# Modified to never use included libintl. +# Owen Taylor , 12/15/1998 +# +# Major rework to remove unused code +# Owen Taylor , 12/11/2002 +# +# Added better handling of ALL_LINGUAS from GNU gettext version +# written by Bruno Haible, Owen Taylor 5/30/3002 +# +# Modified to require ngettext +# Matthias Clasen 08/06/2004 +# +# We need this here as well, since someone might use autoconf-2.5x +# to configure GLib then an older version to configure a package +# using AM_GLIB_GNU_GETTEXT +AC_PREREQ(2.53) + +dnl +dnl We go to great lengths to make sure that aclocal won't +dnl try to pull in the installed version of these macros +dnl when running aclocal in the glib directory. +dnl +m4_copy([AC_DEFUN],[glib_DEFUN]) +m4_copy([AC_REQUIRE],[glib_REQUIRE]) +dnl +dnl At the end, if we're not within glib, we'll define the public +dnl definitions in terms of our private definitions. +dnl + +# GLIB_LC_MESSAGES +#-------------------- +glib_DEFUN([GLIB_LC_MESSAGES], + [AC_CHECK_HEADERS([locale.h]) + if test $ac_cv_header_locale_h = yes; then + AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES, + [AC_TRY_LINK([#include ], [return LC_MESSAGES], + am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)]) + if test $am_cv_val_LC_MESSAGES = yes; then + AC_DEFINE(HAVE_LC_MESSAGES, 1, + [Define if your file defines LC_MESSAGES.]) + fi + fi]) + +# GLIB_PATH_PROG_WITH_TEST +#---------------------------- +dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR, +dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]]) +glib_DEFUN([GLIB_PATH_PROG_WITH_TEST], +[# Extract the first word of "$2", so it can be a program name with args. +set dummy $2; ac_word=[$]2 +AC_MSG_CHECKING([for $ac_word]) +AC_CACHE_VAL(ac_cv_path_$1, +[case "[$]$1" in + /*) + ac_cv_path_$1="[$]$1" # Let the user override the test with a path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in ifelse([$5], , $PATH, [$5]); do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if [$3]; then + ac_cv_path_$1="$ac_dir/$ac_word" + break + fi + fi + done + IFS="$ac_save_ifs" +dnl If no 4th arg is given, leave the cache variable unset, +dnl so AC_PATH_PROGS will keep looking. +ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4" +])dnl + ;; +esac])dnl +$1="$ac_cv_path_$1" +if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then + AC_MSG_RESULT([$]$1) +else + AC_MSG_RESULT(no) +fi +AC_SUBST($1)dnl +]) + +# GLIB_WITH_NLS +#----------------- +glib_DEFUN([GLIB_WITH_NLS], + dnl NLS is obligatory + [USE_NLS=yes + AC_SUBST(USE_NLS) + + gt_cv_have_gettext=no + + CATOBJEXT=NONE + XGETTEXT=: + INTLLIBS= + + AC_CHECK_HEADER(libintl.h, + [gt_cv_func_dgettext_libintl="no" + libintl_extra_libs="" + + # + # First check in libc + # + AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc, + [AC_TRY_LINK([ +#include +], + [return !ngettext ("","", 1)], + gt_cv_func_ngettext_libc=yes, + gt_cv_func_ngettext_libc=no) + ]) + + if test "$gt_cv_func_ngettext_libc" = "yes" ; then + AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc, + [AC_TRY_LINK([ +#include +], + [return !dgettext ("","")], + gt_cv_func_dgettext_libc=yes, + gt_cv_func_dgettext_libc=no) + ]) + fi + + if test "$gt_cv_func_ngettext_libc" = "yes" ; then + AC_CHECK_FUNCS(bind_textdomain_codeset) + fi + + # + # If we don't have everything we want, check in libintl + # + if test "$gt_cv_func_dgettext_libc" != "yes" \ + || test "$gt_cv_func_ngettext_libc" != "yes" \ + || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then + + AC_CHECK_LIB(intl, bindtextdomain, + [AC_CHECK_LIB(intl, ngettext, + [AC_CHECK_LIB(intl, dgettext, + gt_cv_func_dgettext_libintl=yes)])]) + + if test "$gt_cv_func_dgettext_libintl" != "yes" ; then + AC_MSG_CHECKING([if -liconv is needed to use gettext]) + AC_MSG_RESULT([]) + AC_CHECK_LIB(intl, ngettext, + [AC_CHECK_LIB(intl, dcgettext, + [gt_cv_func_dgettext_libintl=yes + libintl_extra_libs=-liconv], + :,-liconv)], + :,-liconv) + fi + + # + # If we found libintl, then check in it for bind_textdomain_codeset(); + # we'll prefer libc if neither have bind_textdomain_codeset(), + # and both have dgettext and ngettext + # + if test "$gt_cv_func_dgettext_libintl" = "yes" ; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS -lintl $libintl_extra_libs" + unset ac_cv_func_bind_textdomain_codeset + AC_CHECK_FUNCS(bind_textdomain_codeset) + LIBS="$glib_save_LIBS" + + if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then + gt_cv_func_dgettext_libc=no + else + if test "$gt_cv_func_dgettext_libc" = "yes" \ + && test "$gt_cv_func_ngettext_libc" = "yes"; then + gt_cv_func_dgettext_libintl=no + fi + fi + fi + fi + + if test "$gt_cv_func_dgettext_libc" = "yes" \ + || test "$gt_cv_func_dgettext_libintl" = "yes"; then + gt_cv_have_gettext=yes + fi + + if test "$gt_cv_func_dgettext_libintl" = "yes"; then + INTLLIBS="-lintl $libintl_extra_libs" + fi + + if test "$gt_cv_have_gettext" = "yes"; then + AC_DEFINE(HAVE_GETTEXT,1, + [Define if the GNU gettext() function is already present or preinstalled.]) + GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl + if test "$MSGFMT" != "no"; then + glib_save_LIBS="$LIBS" + LIBS="$LIBS $INTLLIBS" + AC_CHECK_FUNCS(dcgettext) + MSGFMT_OPTS= + AC_MSG_CHECKING([if msgfmt accepts -c]) + GLIB_RUN_PROG([$MSGFMT -c -o /dev/null],[ +msgid "" +msgstr "" +"Content-Type: text/plain; charset=UTF-8\n" +"Project-Id-Version: test 1.0\n" +"PO-Revision-Date: 2007-02-15 12:01+0100\n" +"Last-Translator: test \n" +"Language-Team: C \n" +"MIME-Version: 1.0\n" +"Content-Transfer-Encoding: 8bit\n" +], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])]) + AC_SUBST(MSGFMT_OPTS) + AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT) + GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext, + [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :) + AC_TRY_LINK(, [extern int _nl_msg_cat_cntr; + return _nl_msg_cat_cntr], + [CATOBJEXT=.gmo + DATADIRNAME=share], + [case $host in + *-*-solaris*) + dnl On Solaris, if bind_textdomain_codeset is in libc, + dnl GNU format message catalog is always supported, + dnl since both are added to the libc all together. + dnl Hence, we'd like to go with DATADIRNAME=share and + dnl and CATOBJEXT=.gmo in this case. + AC_CHECK_FUNC(bind_textdomain_codeset, + [CATOBJEXT=.gmo + DATADIRNAME=share], + [CATOBJEXT=.mo + DATADIRNAME=lib]) + ;; + *-*-openbsd*) + CATOBJEXT=.mo + DATADIRNAME=share + ;; + *) + CATOBJEXT=.mo + DATADIRNAME=lib + ;; + esac]) + LIBS="$glib_save_LIBS" + INSTOBJEXT=.mo + else + gt_cv_have_gettext=no + fi + fi + ]) + + if test "$gt_cv_have_gettext" = "yes" ; then + AC_DEFINE(ENABLE_NLS, 1, + [always defined to indicate that i18n is enabled]) + fi + + dnl Test whether we really found GNU xgettext. + if test "$XGETTEXT" != ":"; then + dnl If it is not GNU xgettext we define it as : so that the + dnl Makefiles still can work. + if $XGETTEXT --omit-header /dev/null 2> /dev/null; then + : ; + else + AC_MSG_RESULT( + [found xgettext program is not GNU xgettext; ignore it]) + XGETTEXT=":" + fi + fi + + # We need to process the po/ directory. + POSUB=po + + AC_OUTPUT_COMMANDS( + [case "$CONFIG_FILES" in *po/Makefile.in*) + sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile + esac]) + + dnl These rules are solely for the distribution goal. While doing this + dnl we only have to keep exactly one list of the available catalogs + dnl in configure.ac. + for lang in $ALL_LINGUAS; do + GMOFILES="$GMOFILES $lang.gmo" + POFILES="$POFILES $lang.po" + done + + dnl Make all variables we use known to autoconf. + AC_SUBST(CATALOGS) + AC_SUBST(CATOBJEXT) + AC_SUBST(DATADIRNAME) + AC_SUBST(GMOFILES) + AC_SUBST(INSTOBJEXT) + AC_SUBST(INTLLIBS) + AC_SUBST(PO_IN_DATADIR_TRUE) + AC_SUBST(PO_IN_DATADIR_FALSE) + AC_SUBST(POFILES) + AC_SUBST(POSUB) + ]) + +# AM_GLIB_GNU_GETTEXT +# ------------------- +# Do checks necessary for use of gettext. If a suitable implementation +# of gettext is found in either in libintl or in the C library, +# it will set INTLLIBS to the libraries needed for use of gettext +# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable +# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST() +# on various variables needed by the Makefile.in.in installed by +# glib-gettextize. +dnl +glib_DEFUN([GLIB_GNU_GETTEXT], + [AC_REQUIRE([AC_PROG_CC])dnl + AC_REQUIRE([AC_HEADER_STDC])dnl + + GLIB_LC_MESSAGES + GLIB_WITH_NLS + + if test "$gt_cv_have_gettext" = "yes"; then + if test "x$ALL_LINGUAS" = "x"; then + LINGUAS= + else + AC_MSG_CHECKING(for catalogs to be installed) + NEW_LINGUAS= + for presentlang in $ALL_LINGUAS; do + useit=no + if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then + desiredlanguages="$LINGUAS" + else + desiredlanguages="$ALL_LINGUAS" + fi + for desiredlang in $desiredlanguages; do + # Use the presentlang catalog if desiredlang is + # a. equal to presentlang, or + # b. a variant of presentlang (because in this case, + # presentlang can be used as a fallback for messages + # which are not translated in the desiredlang catalog). + case "$desiredlang" in + "$presentlang"*) useit=yes;; + esac + done + if test $useit = yes; then + NEW_LINGUAS="$NEW_LINGUAS $presentlang" + fi + done + LINGUAS=$NEW_LINGUAS + AC_MSG_RESULT($LINGUAS) + fi + + dnl Construct list of names of catalog files to be constructed. + if test -n "$LINGUAS"; then + for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done + fi + fi + + dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly + dnl find the mkinstalldirs script in another subdir but ($top_srcdir). + dnl Try to locate is. + MKINSTALLDIRS= + if test -n "$ac_aux_dir"; then + MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs" + fi + if test -z "$MKINSTALLDIRS"; then + MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs" + fi + AC_SUBST(MKINSTALLDIRS) + + dnl Generate list of files to be processed by xgettext which will + dnl be included in po/Makefile. + test -d po || mkdir po + if test "x$srcdir" != "x."; then + if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then + posrcprefix="$srcdir/" + else + posrcprefix="../$srcdir/" + fi + else + posrcprefix="../" + fi + rm -f po/POTFILES + sed -e "/^#/d" -e "/^\$/d" -e "s,.*, $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \ + < $srcdir/po/POTFILES.in > po/POTFILES + ]) + +# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE) +# ------------------------------- +# Define VARIABLE to the location where catalog files will +# be installed by po/Makefile. +glib_DEFUN([GLIB_DEFINE_LOCALEDIR], +[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl +glib_save_prefix="$prefix" +glib_save_exec_prefix="$exec_prefix" +glib_save_datarootdir="$datarootdir" +test "x$prefix" = xNONE && prefix=$ac_default_prefix +test "x$exec_prefix" = xNONE && exec_prefix=$prefix +datarootdir=`eval echo "${datarootdir}"` +if test "x$CATOBJEXT" = "x.mo" ; then + localedir=`eval echo "${libdir}/locale"` +else + localedir=`eval echo "${datadir}/locale"` +fi +prefix="$glib_save_prefix" +exec_prefix="$glib_save_exec_prefix" +datarootdir="$glib_save_datarootdir" +AC_DEFINE_UNQUOTED($1, "$localedir", + [Define the location where the catalogs will be installed]) +]) + +dnl +dnl Now the definitions that aclocal will find +dnl +ifdef(glib_configure_ac,[],[ +AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)]) +AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)]) +])dnl + +# GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL]) +# +# Create a temporary file with TEST-FILE as its contents and pass the +# file name to PROGRAM. Perform ACTION-IF-PASS if PROGRAM exits with +# 0 and perform ACTION-IF-FAIL for any other exit status. +AC_DEFUN([GLIB_RUN_PROG], +[cat >conftest.foo <<_ACEOF +$2 +_ACEOF +if AC_RUN_LOG([$1 conftest.foo]); then + m4_ifval([$3], [$3], [:]) +m4_ifvaln([$4], [else $4])dnl +echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD +sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD +fi]) + diff --git a/glib/m4macros/gsettings.m4 b/glib/m4macros/gsettings.m4 new file mode 100644 index 0000000..7b2f9a2 --- /dev/null +++ b/glib/m4macros/gsettings.m4 @@ -0,0 +1,83 @@ +dnl GLIB_GSETTINGS +dnl Defines GSETTINGS_SCHEMAS_INSTALL which controls whether +dnl the schema should be compiled +dnl + +AC_DEFUN([GLIB_GSETTINGS], +[ + m4_pattern_allow([AM_V_GEN]) + AC_ARG_ENABLE(schemas-compile, + AS_HELP_STRING([--disable-schemas-compile], + [Disable regeneration of gschemas.compiled on install]), + [case ${enableval} in + yes) GSETTINGS_DISABLE_SCHEMAS_COMPILE="" ;; + no) GSETTINGS_DISABLE_SCHEMAS_COMPILE="1" ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-schemas-compile]) ;; + esac]) + AC_SUBST([GSETTINGS_DISABLE_SCHEMAS_COMPILE]) + PKG_PROG_PKG_CONFIG([0.16]) + AC_SUBST(gsettingsschemadir, [${datadir}/glib-2.0/schemas]) + if test x$cross_compiling != xyes; then + GLIB_COMPILE_SCHEMAS=`$PKG_CONFIG --variable glib_compile_schemas gio-2.0` + else + AC_PATH_PROG(GLIB_COMPILE_SCHEMAS, glib-compile-schemas) + fi + AC_SUBST(GLIB_COMPILE_SCHEMAS) + if test "x$GLIB_COMPILE_SCHEMAS" = "x"; then + ifelse([$2],,[AC_MSG_ERROR([glib-compile-schemas not found.])],[$2]) + else + ifelse([$1],,[:],[$1]) + fi + + GSETTINGS_RULES=' +.PHONY : uninstall-gsettings-schemas install-gsettings-schemas clean-gsettings-schemas + +mostlyclean-am: clean-gsettings-schemas + +gsettings__enum_file = $(addsuffix .enums.xml,$(gsettings_ENUM_NAMESPACE)) + +%.gschema.valid: %.gschema.xml $(gsettings__enum_file) + $(AM_V_GEN) if test -f "$<"; then d=; else d="$(srcdir)/"; fi; $(GLIB_COMPILE_SCHEMAS) --strict --dry-run $(addprefix --schema-file=,$(gsettings__enum_file)) --schema-file=$${d}$< && touch [$]@ + +all-am: $(gsettings_SCHEMAS:.xml=.valid) +uninstall-am: uninstall-gsettings-schemas +install-data-am: install-gsettings-schemas + +.SECONDARY: $(gsettings_SCHEMAS) + +install-gsettings-schemas: $(gsettings_SCHEMAS) $(gsettings__enum_file) + @$(NORMAL_INSTALL) + if test -n "$^"; then \ + test -z "$(gsettingsschemadir)" || $(MKDIR_P) "$(DESTDIR)$(gsettingsschemadir)"; \ + $(INSTALL_DATA) $^ "$(DESTDIR)$(gsettingsschemadir)"; \ + test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir); \ + fi + +uninstall-gsettings-schemas: + @$(NORMAL_UNINSTALL) + @list='\''$(gsettings_SCHEMAS) $(gsettings__enum_file)'\''; test -n "$(gsettingsschemadir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e '\''s|^.*/||'\''`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '\''$(DESTDIR)$(gsettingsschemadir)'\'' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(gsettingsschemadir)" && rm -f $$files + test -n "$(GSETTINGS_DISABLE_SCHEMAS_COMPILE)$(DESTDIR)" || $(GLIB_COMPILE_SCHEMAS) $(gsettingsschemadir) + +clean-gsettings-schemas: + rm -f $(gsettings_SCHEMAS:.xml=.valid) $(gsettings__enum_file) + +ifdef gsettings_ENUM_NAMESPACE +$(gsettings__enum_file): $(gsettings_ENUM_FILES) + $(AM_V_GEN) glib-mkenums --comments '\'''\'' --fhead "" --vhead " <@type@ id='\''$(gsettings_ENUM_NAMESPACE).@EnumName@'\''>" --vprod " " --vtail " " --ftail "" [$]^ > [$]@.tmp && mv [$]@.tmp [$]@ +endif +' + _GSETTINGS_SUBST(GSETTINGS_RULES) +]) + +dnl _GSETTINGS_SUBST(VARIABLE) +dnl Abstract macro to do either _AM_SUBST_NOTMAKE or AC_SUBST +AC_DEFUN([_GSETTINGS_SUBST], +[ +AC_SUBST([$1]) +m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([$1])]) +] +) diff --git a/glib/mkinstalldirs b/glib/mkinstalldirs new file mode 100755 index 0000000..4191a45 --- /dev/null +++ b/glib/mkinstalldirs @@ -0,0 +1,162 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy + +scriptversion=2009-04-28.21; # UTC + +# Original author: Noah Friedman +# Created: 1993-05-16 +# Public domain. +# +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' +IFS=" "" $nl" +errstatus=0 +dirmode= + +usage="\ +Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... + +Create each directory DIR (with mode MODE, if specified), including all +leading file name components. + +Report bugs to ." + +# process command line arguments +while test $# -gt 0 ; do + case $1 in + -h | --help | --h*) # -h for help + echo "$usage" + exit $? + ;; + -m) # -m PERM arg + shift + test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } + dirmode=$1 + shift + ;; + --version) + echo "$0 $scriptversion" + exit $? + ;; + --) # stop option processing + shift + break + ;; + -*) # unknown option + echo "$usage" 1>&2 + exit 1 + ;; + *) # first non-opt arg + break + ;; + esac +done + +for file +do + if test -d "$file"; then + shift + else + break + fi +done + +case $# in + 0) exit 0 ;; +esac + +# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and +# mkdir -p a/c at the same time, both will detect that a is missing, +# one will create a, then the other will try to create a and die with +# a "File exists" error. This is a problem when calling mkinstalldirs +# from a parallel make. We use --version in the probe to restrict +# ourselves to GNU mkdir, which is thread-safe. +case $dirmode in + '') + if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + echo "mkdir -p -- $*" + exec mkdir -p -- "$@" + else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + test -d ./-p && rmdir ./-p + test -d ./--version && rmdir ./--version + fi + ;; + *) + if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && + test ! -d ./--version; then + echo "mkdir -m $dirmode -p -- $*" + exec mkdir -m "$dirmode" -p -- "$@" + else + # Clean up after NextStep and OpenStep mkdir. + for d in ./-m ./-p ./--version "./$dirmode"; + do + test -d $d && rmdir $d + done + fi + ;; +esac + +for file +do + case $file in + /*) pathcomp=/ ;; + *) pathcomp= ;; + esac + oIFS=$IFS + IFS=/ + set fnord $file + shift + IFS=$oIFS + + for d + do + test "x$d" = x && continue + + pathcomp=$pathcomp$d + case $pathcomp in + -*) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + else + if test ! -z "$dirmode"; then + echo "chmod $dirmode $pathcomp" + lasterr= + chmod "$dirmode" "$pathcomp" || lasterr=$? + + if test ! -z "$lasterr"; then + errstatus=$lasterr + fi + fi + fi + fi + + pathcomp=$pathcomp/ + done +done + +exit $errstatus + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC" +# time-stamp-end: "; # UTC" +# End: -- cgit v1.2.3